sshpostępuje zgodnie z rshtradycją, używając programu powłoki użytkownika z pliku haseł do wykonywania poleceń.
Oznacza to, że możemy rozwiązać ten problem bez angażowania sshw jakikolwiek sposób konfiguracji.
Jeśli nie chcesz, aby użytkownik miał dostęp do powłoki, po prostu zastąp powłokę tego użytkownika skryptem. Jeśli /etc/passwdzajrzysz do środka, zobaczysz, że istnieje pole, które przypisuje każdemu użytkownikowi interpreter poleceń powłoki. Skrypt jest używany jako powłoka zarówno do ich interaktywnego logowania, ssh user@host jak i do poleceń ssh user@host command arg ....
Oto przykład. Stworzyłem użytkownika, fooktórego powłoką jest skrypt. Skrypt wypisuje komunikat, my arguments are:po którym następują jego argumenty (każdy w osobnym wierszu i w nawiasach ostrych) i kończy. W przypadku dziennika nie ma argumentów. Oto, co się dzieje:
webserver:~
foo@localhost's password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.
Jeśli użytkownik spróbuje uruchomić polecenie, wygląda to tak:
webserver:~
foo@localhost's password:
my arguments are:
<-c>
<cat /etc/passwd>
Nasza „powłoka” otrzymuje -cwywołanie stylu, z całym poleceniem jako jednym argumentem, dokładnie w taki sam sposób, w /bin/shjaki je otrzyma.
Jak widać, możemy teraz dalej rozwijać skrypt, tak aby rozpoznawał przypadek, gdy został wywołany z -cargumentem, a następnie analizuje ciąg (powiedzmy przez dopasowanie do wzorca). Te ciągi, które są dozwolone, mogą być przekazane do prawdziwej powłoki przez rekurencyjne wywołanie /bin/bash -c <string>. Przypadek odrzucenia może wydrukować komunikat o błędzie i zakończyć (w tym przypadek, gdy go -cbrakuje).
Musisz uważać, jak to piszesz. Polecam pisać tylko pozytywne dopasowania, które pozwalają tylko na bardzo konkretne rzeczy i nie pozwalają na wszystko inne.
Uwaga: jeśli tak root, nadal możesz zalogować się na to konto, zastępując powłokę w supoleceniu, w ten sposób su -s /bin/bash foo. (Wybrana powłoka zastępcza). Nie-root nie może tego zrobić.
Oto przykładowy skrypt: ogranicz użytkownika do korzystania tylko sshz gitdostępu do repozytoriów w ramach /git.
#!/bin/sh
if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
printf "interactive login not permitted\n"
exit 1
fi
set -- $2
if [ $# != 2 ] ; then
printf "wrong number of arguments\n"
exit 1
fi
case "$1" in
( git-upload-pack | git-receive-pack )
;;
( * )
printf "command not allowed\n"
exit 1
;;
esac
gitpath=$(readlink -f "$2")
case "$gitpath" in
( /git/* )
;;
( * )
printf "access denied outside of /git\n"
exit 1
;;
esac
if ! [ -e "$gitpath" ] ; then
printf "that git repo doesn't exist\n"
exit 1
fi
"$1" "$gitpath"
Oczywiście ufamy, że te programy Git git-upload-packi git-receive-packnie mają dziur ani włazów, które umożliwią użytkownikom dostęp do systemu.
Jest to nieodłączne w tego rodzaju schemacie ograniczeń. Użytkownik jest uwierzytelniany w celu wykonania kodu w określonej domenie bezpieczeństwa, a my wzywamy do ograniczenia tej domeny do subdomeny. Na przykład, jeśli pozwolisz użytkownikowi uruchomić vimpolecenie na określonym pliku w celu jego edycji, użytkownik może po prostu uzyskać powłokę za pomocą :!sh[Enter].