Czy możesz podać git-shell w .ssh / Author_keys, aby ograniczyć dostęp tylko do poleceń git przez ssh?

37

Chciałbym móc użyć klucza ssh do uwierzytelnienia, ale nadal ograniczać polecenia, które można wykonać w tunelu ssh.

Dzięki Subversion osiągnąłem to, używając pliku .ssh / author_keys, takiego jak:

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

Próbowałem tego z poleceniem „/ usr / bin / git-shell”, ale po prostu dostaję stary, stary fatal: What do you think I am? A shell?komunikat o błędzie.

Matt Connolly
źródło

Odpowiedzi:

30

Poniższe działa dla mnie.

W ~/.ssh/authorized_keys:

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

W ~/gitserveskrypcie:

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

Pamiętaj, że jeśli umieścisz coś gitserveinnego niż katalog domowy, będziesz musiał dostosować command="./gitserve"parametr w authorized_keys.

Neil Mayhew
źródło
Bingo! To działa tak, jak chciałem to osiągnąć! Dzięki.
Matt Connolly,
W tym powiązanym poście na SO stackoverflow.com/questions/5871652/... wskazują na inne rozwiązanie tutaj: joey.kitenet.net/blog/entry/locking_down_ssh_authorized_keys
Tim
1
@Tim Jest to zasadniczo to samo rozwiązanie, ale wyciska zawartość mojego skryptu ~ / gitserve w autoryzowane klucze za pomocą perla. Osobiście wolę trzymać go w osobnym skrypcie.
Neil Mayhew
1
Rozumiem, po prostu dodałem to jako odniesienie.
Tim
Jaką powłokę masz ustawiony w tej konfiguracji przez użytkownika? /bin/bash?
M-Pixel
33

Mogłem z powodzeniem używać git-shell bezpośrednio w pliku authorKeys bez użycia dodatkowego skryptu.

Kluczem jest dodanie \"wokół zmiennej env.

Testowany w 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
źródło
+1 to poprawna odpowiedź, patrz svnweb.freebsd.org/base/head/crypto/openssh/…
Tino
2
Osobiście podałbym pełną ścieżkę do git-shell, ale to może być po prostu paranoja.
Ulrich Schwarz
Czy ktoś znalazł sposób na ograniczenie katalogu, do którego ma dostęp? Odkryłem, że mogę wykonać cd do katalogu przed uruchomieniem git-shell, ale git-shell pozwala na „..” i ścieżki bezwzględne.
yokto
5

Rozwiązanie Grawity można łatwo zmodyfikować do pracy, zastępując linię

        exec $SSH_ORIGINAL_COMMAND

z linią

        git-shell -c "$SSH_ORIGINAL_COMMAND"

Cytaty zajmują się powyższymi problemami, a zastąpienie exec przez git-shell wydaje się nieco bezpieczniejsze.

dschwen
źródło
4

git-shelljest przeznaczony do użycia jako powłoka logowania, aby otrzymywał -c "originalcommand"jako argumenty. Nie dzieje się tak w przypadku „poleceń wymuszonych” w OpenSSH; zamiast tego polecenie wymuszone jest przekazywane do skonfigurowanej powłoki.

Możesz napisać skrypt, który to sprawdzi $SSH_ORIGINAL_COMMANDi wykona. Przykład w 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
grawitacja
źródło
@Matt: git-shell (1) mówi, że polecenia są git <cmd>, nie git-<cmd>?
grawity
Hmm ... Dokonałem tej zmiany zgodnie z tym, co zobaczyłem, kiedy ją uruchomiłem. Zarówno skryptem bash, jak i skryptem ruby ​​widziałem polecenie „git-receive-pack” jako polecenie. Cytat z mojego man git-shell(git 1.7.3.4): Obecnie dozwolone są tylko cztery polecenia, git-receive-pack git-upload-pack i git-upload-archive z jednym wymaganym argumentem lub serwer cvs (aby wywołać git -cvsserver).
Matt Connolly,
formatowanie nie działa w komentarzach :(
Matt Connolly,
1
Nie działa to dla mnie, ponieważ mój klient git (1.7.5.4) wysyła nazwę repozytorium pojedynczymi cudzysłowami, prawdopodobnie dlatego, że oczekuje interpretacji całej linii poleceń przez powłokę. Następnie exec $ SSH_ORIGINAL_COMMAND przekazuje pojedyncze cudzysłowy do git-receive-pack itp., Który dlatego nie znajduje repozytorium.
Neil Mayhew
Dzięki za rozwiązanie, grawity, ale to nie działa dla mnie, z tego samego powodu, że został zgłoszony przez Neila Mayhew ... moja wersja 1.7.x od git wysyła również nazwę repo w apostrofach, ostatecznie powodując $SSH_ORIGINAL_COMMANDbyć nieważne i powodujące git-shellbum :-(
pvandenberk 13.10.11
1

Dla kompletności, a ponieważ oryginalne pytanie nie określił, że to samo konto musiał być użyteczny dla non-git rzeczy, oczywistym rozwiązaniem jest używać git-shelljak to zostało zaprojektowane do wykorzystania: ustawić ją jako powłokę zgłoszeniową (tj usermod, in /etc/passwd) dla tego użytkownika ssh.

Jeśli masz jedno konto użytkownika, którego chcesz używać na dwa sposoby:

  • podczas łączenia z uwierzytelnianiem klucza, używaj tylko dla git
  • podczas łączenia z uwierzytelnianiem za pomocą hasła lub przy użyciu innego klucza prywatnego zapewnij pełną powłokę

... wówczas obowiązują inne odpowiedzi w tym wątku. Ale jeśli możesz sobie pozwolić na przydzielenie osobnego użytkownika do git, to ustawienie jego powłoki git-shellto najprostszy sposób na ograniczenie tego i jest nieco bezpieczniejsze, ponieważ nie wymaga żadnych dodatkowych skryptów powłoki.

Felix
źródło