Können Sie git-shell in .ssh / authorized_keys angeben, um den Zugriff nur auf git-Befehle über ssh zu beschränken?

37

Ich möchte in der Lage sein, einen SSH-Schlüssel zur Authentifizierung zu verwenden, aber trotzdem die Befehle einschränken, die über den SSH-Tunnel ausgeführt werden können.

Mit Subversion habe ich dies erreicht, indem ich eine .ssh / authorized_keys-Datei wie die folgende verwendet habe:

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...

Ich habe dies mit "/ usr / bin / git-shell" im Befehl versucht, aber ich bekomme nur die funky alte fatal: What do you think I am? A shell?Fehlermeldung.

Matt Connolly
quelle

Antworten:

30

Folgendes funktioniert für mich.

In ~/.ssh/authorized_keys:

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

Im ~/gitserveDrehbuch:

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

Beachten Sie, dass Sie gitserveden command="./gitserve"Parameter in anpassen müssen , wenn Sie ein anderes Verzeichnis als das Basisverzeichnis angeben authorized_keys.

Neil Mayhew
quelle
Bingo! Das funktioniert genau so, wie ich es mir erhofft hatte! Vielen Dank.
Matt Connolly
In diesem verwandten Beitrag auf SO stackoverflow.com/questions/5871652/… wird hier auf eine andere Lösung verwiesen
Tim
1
@Tim Dies ist im Wesentlichen die gleiche Lösung, jedoch wird der Inhalt meines ~ / gitserve-Skripts mithilfe von Perl in autorisierte Schlüssel zerlegt. Persönlich bevorzuge ich es in einem separaten Skript.
Neil Mayhew
1
Ich verstehe, ich habe es nur als Referenz hinzugefügt.
Tim
Auf welche Shell haben Sie den Benutzer in dieser Konfiguration eingestellt? /bin/bash?
M-Pixel
33

Ich konnte git-shell erfolgreich direkt in der authorizedKeys-Datei verwenden, ohne ein zusätzliches Skript zu verwenden.

Der Schlüssel ist, um die \"Umgebungsvariable hinzuzufügen .

Getestet in 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
quelle
+1 das ist die richtige Antwort, siehe svnweb.freebsd.org/base/head/crypto/openssh/…
Tino
2
Persönlich würde ich den vollständigen Weg angeben git-shell, aber das könnte nur Paranoia sein.
Ulrich Schwarz
Hat jemand eine Möglichkeit gefunden, das Verzeichnis einzuschränken, auf das er Zugriff hat? Ich fand, dass ich in ein Verzeichnis vor dem Ausführen von Git-Shell CD, aber Git-Shell erlaubt ".." und absolute Pfade.
Yokto
5

Die Lösung von Grawity kann durch Ersetzen der Leitung problemlos geändert werden

        exec $SSH_ORIGINAL_COMMAND

mit der Linie

        git-shell -c "$SSH_ORIGINAL_COMMAND"

Die Anführungszeichen kümmern sich um die oben genannten Probleme, und das Ersetzen von exec durch git-shell scheint etwas sicherer zu sein.

dschwen
quelle
4

git-shellsoll als Login-Shell verwendet werden, so dass es -c "originalcommand"als Argumente erhalten würde . Dies ist bei "erzwungenen Befehlen" in OpenSSH nicht der Fall. Stattdessen wird der erzwungene Befehl an die konfigurierte Shell übergeben.

Sie können ein Skript schreiben, das es überprüft $SSH_ORIGINAL_COMMANDund ausführt. Beispiel in 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
quelle
@Matt: Git-Shell (1) sagt, die Befehle sind git <cmd>, nicht wahr git-<cmd>?
Grawity
Hmm ... Ich habe diese Änderung entsprechend dem, was ich gesehen habe, als ich sie ausgeführt habe, vorgenommen. Sowohl mit einem Bash-Skript als auch mit einem Ruby-Skript sah ich "git-receive-pack" als Befehl. Zitat aus meinem man git-shell(git 1.7.3.4): Derzeit dürfen nur vier Befehle aufgerufen werden, git-receive-pack, git-upload-pack und git-upload-archive mit einem einzigen erforderlichen Argument, oder cvs server (um git aufzurufen) -cvsserver).
Matt Connolly
Formatierung funktioniert nicht in Kommentaren :(
Matt Connolly
1
Dies funktioniert bei mir nicht, da mein Git-Client (1.7.5.4) den Repo-Namen in einfachen Anführungszeichen sendet, vermutlich weil er erwartet, dass die gesamte Befehlszeile von einer Shell interpretiert wird. Der exec $ SSH_ORIGINAL_COMMAND übergibt dann die einzelnen Anführungszeichen an git-receive-pack usw., der das Repository daher nicht findet.
Neil Mayhew
Vielen Dank für die Lösung, grawity, aber es ist nicht für mich arbeiten, aus dem gleichen Grunde, der von Neil Mayhew ... meine 1.7.x - Version von git berichtet wurde , sendet auch die Repo - Namen in einfachen Anführungszeichen, letztlich die verursacht $SSH_ORIGINAL_COMMANDwerden ungültig und verursacht, git-shellum heraus zu brennen :-(
pvandenberk
1

Der Vollständigkeit halber und da in der ursprünglichen Frage nicht angegeben war, dass dasselbe Konto für Nicht-Git-Dinge verwendet werden muss, ist die offensichtliche Antwort, dass git-shelles so verwendet wird, wie es entworfen wurde: Legen Sie es als Anmeldeshell fest (dh mit usermod, in /etc/passwd) für diesen SSH-Benutzer.

Wenn Sie ein einzelnes Benutzerkonto haben, das Sie auf zwei Arten verwenden möchten:

  • Verwenden Sie diese Option nur für Git, wenn Sie eine Verbindung mit der Schlüsselauthentifizierung herstellen
  • Wenn Sie eine Verbindung mit der Kennwortauthentifizierung herstellen oder einen anderen privaten Schlüssel verwenden, geben Sie eine vollständige Shell an

... dann gelten die anderen Antworten in diesem Thread. Wenn Sie es sich jedoch leisten können, git einen separaten Benutzer zuzuweisen, git-shellist das Festlegen der Shell die einfachste Möglichkeit, diese einzuschränken, und sie ist etwas sicherer, da keine zusätzlichen Shell-Skripte erforderlich sind.

Felix
quelle