Pouvez-vous spécifier git-shell dans .ssh / registered_keys pour limiter l'accès aux commandes git uniquement via ssh?

37

J'aimerais pouvoir utiliser une clé ssh pour l'authentification, tout en limitant les commandes pouvant être exécutées via le tunnel ssh.

Avec Subversion, j’ai atteint cet objectif en utilisant un fichier .ssh / registered_keys tel que:

command="/usr/local/bin/svnserve -t --tunnel-user matt -r /path/to/repository",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAABIetc...

J'ai essayé ceci avec "/ usr / bin / git-shell" dans la commande, mais je viens de recevoir le vieux fatal: What do you think I am? A shell?message d'erreur génial .

Matt Connolly
la source

Réponses:

30

Ce qui suit fonctionne pour moi.

Dans ~/.ssh/authorized_keys:

command="./gitserve",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-dss AAAAB…

Dans le ~/gitservescript:

#!/bin/sh
exec git-shell -c "$SSH_ORIGINAL_COMMAND"

Notez que si vous placez un gitserveemplacement autre que le répertoire de base, vous devrez ajuster le command="./gitserve"paramètre dans authorized_keys.

Neil Mayhew
la source
Bingo! Cela fonctionne exactement comme ce que j'espérais réaliser! Merci.
Matt Connolly
Dans ce post connexe sur SO stackoverflow.com/questions/5871652/…, ils indiquent une autre solution ici: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys
Tim
1
@ Tim C'est essentiellement la même solution, mais compresse le contenu de mon script ~ / gitserve dans des clés autorisées à l'aide de perl. Personnellement, je préfère le garder dans un script séparé.
Neil Mayhew
1
Je comprends, je l'ai simplement ajouté comme référence.
Tim
Dans quel shell l'utilisateur a-t-il été configuré dans cette configuration? /bin/bash?
M-Pixel
33

Je pouvais utiliser avec succès git-shell directement dans le fichier allowedKeys sans utiliser de script supplémentaire.

La clé est d'ajouter \"autour de la variable env.

Testé dans rhel6 openssh-server-5.3p1-70.el6.x86_64:

no-port-forwarding,no-agent-forwarding,command="git-shell -c \"$SSH_ORIGINAL_COMMAND\"" ssh-dss AAAA...
sophana
la source
+1 c'est la bonne réponse, voir svnweb.freebsd.org/base/head/crypto/openssh/…
Tino
2
Personnellement, je donnerais le chemin complet à git-shell, mais cela pourrait bien être une paranoïa.
Ulrich Schwarz
Quelqu'un at-il trouvé un moyen de restreindre le répertoire auquel il a accès? J'ai trouvé que je pouvais aller dans un répertoire avant d'exécuter git-shell, mais git-shell autorise ".." et les chemins absolus.
Yokto
5

La solution de Grawity peut être facilement modifiée afin de fonctionner en remplaçant la ligne.

        exec $SSH_ORIGINAL_COMMAND

avec la ligne

        git-shell -c "$SSH_ORIGINAL_COMMAND"

Les guillemets traitent des problèmes signalés ci-dessus, et le remplacement de exec par git-shell semble un peu plus sécurisé.

dschwen
la source
4

git-shellest conçu pour être utilisé comme un shell de connexion, afin qu'il reçoive -c "originalcommand"comme arguments. Cela ne se produit pas avec les "commandes forcées" dans OpenSSH; au lieu de cela, le commande forcée est transmise au shell configuré.

Ce que vous pouvez faire, c'est écrire un script qui le vérifie $SSH_ORIGINAL_COMMANDet l'exécute. Exemple en bash :

#!/bin/bash

SSH_ORIGINAL_COMMAND=${SSH_ORIGINAL_COMMAND/#git /git-}

case $SSH_ORIGINAL_COMMAND in
    "git-receive-pack"*|"git-upload-pack"*|"git-upload-archive"*)
        eval exec $SSH_ORIGINAL_COMMAND
        ;;
    *)
        echo "Go away." >&2
        exit 1
        ;;
esac
Grawity
la source
@Matt: git-shell (1) dit que les commandes sont git <cmd>, non git-<cmd>?
Grawity
Hmm ... J'ai fait ce changement en fonction de ce que j'ai vu quand je l'ai exécuté. Avec un script bash et un script ruby, j'ai vu "git-receive-pack" comme commande. Citation de my man git-shell(git 1.7.3.4): Actuellement, seules quatre commandes peuvent être appelées, git-receive-pack, git-upload-pack et git-upload-archive avec un seul argument requis, ou le serveur cvs (pour appeler git -cvsserver).
Matt Connolly
La mise en forme ne fonctionne pas dans les commentaires :(
Matt Connolly
1
Cela ne fonctionne pas pour moi, car mon client git (1.7.5.4) envoie le nom du référentiel entre guillemets simples, probablement parce qu'il s'attend à ce que toute la ligne de commande soit interprétée par un shell. Exec $ SSH_ORIGINAL_COMMAND transmet ensuite les guillemets simples à git-receive-pack, etc., qui ne trouve donc pas le référentiel.
Neil Mayhew
Merci pour la solution, grawity, mais il ne fonctionne pas pour moi, pour la même raison qui a été rapporté par Neil Mayhew ... ma version 1.7.x de git envoie également le nom de repo entre guillemets simples, ce qui en fin de compte la $SSH_ORIGINAL_COMMANDpour être invalide, et causant git-shellde brûler :-(
pvandenberk
1

Pour être complet, et comme la question initiale ne spécifiait pas que le même compte devait être utilisable pour des choses non git, la réponse évidente est d'utiliser git-shelltel qu'il a été conçu pour être utilisé: définissez-le comme shell de connexion (c'est-à-dire usermod, dans /etc/passwd) pour cet utilisateur ssh.

Si vous ne possédez qu'un seul compte utilisateur, vous souhaitez utiliser deux méthodes:

  • lors de la connexion avec l'authentification par clé, utilisez uniquement pour git
  • lors de la connexion avec une authentification par mot de passe ou en utilisant une clé privée différente, fournissez un shell complet

... alors les autres réponses de ce fil s'appliquent. Mais si vous pouvez vous permettre d’attribuer un utilisateur distinct à git, alors définir son shell en git-shellest le moyen le plus simple de le restreindre. Il est légèrement plus sécurisé car il ne nécessite aucun script supplémentaire.

Félix
la source