To pomysł na zabezpieczenie. Nasi pracownicy będą mieli dostęp do niektórych poleceń na serwerze Linux, ale nie do wszystkich. Powinni mieć np. Możliwość dostępu do pliku dziennika ( less logfile
) lub uruchamiania różnych poleceń ( shutdown.sh
/ run.sh
).
Informacje podstawowe:
Wszyscy pracownicy uzyskują dostęp do serwera z tą samą nazwą użytkownika: nasz produkt działa na „normalnych” uprawnieniach użytkownika, nie jest wymagana żadna „instalacja”. Po prostu rozpakuj go w katalogu użytkownika i uruchom. Zarządzamy kilkoma serwerami, na których „zainstalowana” jest nasza aplikacja. Na każdej maszynie jest użytkownik johndoe
. Nasi pracownicy czasami potrzebują dostępu do aplikacji z wiersza poleceń, aby uzyskać dostęp i sprawdzić pliki dziennika lub ręcznie ponownie uruchomić aplikację. Tylko niektóre osoby będą miały pełny dostęp do wiersza poleceń.
Używamy uwierzytelniania ppk na serwerze.
Byłoby wspaniale, gdyby pracownik1 miał dostęp tylko do pliku dziennika, a pracownik2 mógł również wykonywać X itd.
Rozwiązanie:
Jako rozwiązanie użyję command
opcji podanej w zaakceptowanej odpowiedzi. Zrobię swój własny mały skrypt powłoki, który będzie jedynym plikiem, który będzie można uruchomić dla niektórych pracowników. Skrypt będzie oferował kilka poleceń, które można wykonać, ale żadnych innych. Użyję następujących parametrów w authorized_keys
od, jak podano tutaj :
command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= user@host
To nam wystarczy. Dzięki społeczności!
Odpowiedzi:
Możesz także ograniczyć klucze do dozwolonych poleceń (w pliku authorised_keys).
To znaczy, że użytkownik nie logowałby się przez ssh, a następnie miałby ograniczony zestaw poleceń, ale raczej mógłby wykonywać te polecenia tylko przez ssh (np. „Ssh somehost bin / showlogfile”)
źródło
ssh
postępuje zgodnie zrsh
tradycją, 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
ssh
w 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/passwd
zajrzysz 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,
foo
któ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:~# ssh foo@localhost 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:~# ssh foo@localhost cat /etc/passwd foo@localhost's password: my arguments are: <-c> <cat /etc/passwd>
Nasza „powłoka” otrzymuje
-c
wywołanie stylu, z całym poleceniem jako jednym argumentem, dokładnie w taki sam sposób, w/bin/sh
jaki je otrzyma.Jak widać, możemy teraz dalej rozwijać skrypt, tak aby rozpoznawał przypadek, gdy został wywołany z
-c
argumentem, 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-c
brakuje).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ę wsu
poleceniu, w ten sposóbsu -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
ssh
zgit
dostę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 ) ;; # continue execution ( * ) printf "command not allowed\n" exit 1 ;; esac # Canonicalize the path name: we don't want escape out of # git via ../ path components. gitpath=$(readlink -f "$2") # GNU Coreutils specific case "$gitpath" in ( /git/* ) ;; # continue execution ( * ) 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-pack
igit-receive-pack
nie 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ć
vim
polecenie na określonym pliku w celu jego edycji, użytkownik może po prostu uzyskać powłokę za pomocą:!sh[Enter]
.źródło
git-receive-pack '/git/';dd if=/dev/urandom of=/dev/sda
?case
, nie wygląda na poprawne./bin/bash -c "$2"
jest niebezpieczny (podobnie jak działa wstrzyknięcie SQL). Możesz filtrować ciąg za pomocą „magicznych cudzysłowów”, takich jak PHP. Jednak najłatwiejszym sposobem zapewnienia całkowitego bezpieczeństwa jest ręczne wywołanie polecenia, a następnie przekazanie parametrów w cudzysłowie. Ponieważ bezpieczeństwo całości zależy wtedy od tego, czy polecenie jest najsłabszym ogniwem (trudniejszym do zweryfikowania). Najciekawsze, jak twoja odpowiedź ma 22 głosy za, ale nikt tego nie zauważył;) Czy zaktualizujesz własną odpowiedź?set
i pobiera z niego tylko pierwsze dwa słowa. Pierwsza musi być dozwolonymgit-
poleceniem, a druga musi być ścieżką, która jest kanonizowana, sprawdzana pod kątem dozwolonego przedrostka i sprawdzana pod kątem istnienia. Czy możesz wymyślić jakiś sposób, aby to przerwać?To, czego szukasz, nazywa się Restricted Shell . Bash zapewnia taki tryb, w którym użytkownicy mogą wykonywać tylko polecenia obecne w ich katalogach domowych (i nie mogą przenosić się do innych katalogów), co może być dla Ciebie wystarczająco dobre.
Uważam, że ten wątek jest bardzo ilustracyjny, choć trochę przestarzały.
źródło
Powinieneś kupić `rssh ', powłokę z ograniczeniami
Możesz postępować zgodnie ze wskazówkami dotyczącymi ograniczeń, o których mowa powyżej, wszystkie są raczej oczywiste i łatwe do naśladowania. Zapoznaj się z terminami `` jail chroot '' i jak skutecznie wdrażać konfiguracje sshd / terminala i tak dalej.
Ponieważ większość użytkowników uzyskuje dostęp do terminali przez sshd, prawdopodobnie powinieneś również zajrzeć do sshd_conifg, pliku konfiguracyjnego demona SSH, aby zastosować pewne ograniczenia przez SSH. Uważaj jednak. Zrozum dobrze, co próbujesz zaimplementować, ponieważ konsekwencje nieprawidłowych konfiguracji są prawdopodobnie dość tragiczne.
źródło
rssh
został usunięty z Debian Buster. Myślę, że nowa gorączka to pośpiech GNU .Dlaczego nie napiszesz własnej powłoki logowania? Byłoby całkiem proste użycie do tego Bash, ale możesz użyć dowolnego języka.
Przykład w Bash
Użyj swojego ulubionego edytora, aby utworzyć plik
/root/rbash.sh
(może to być dowolna nazwa lub ścieżka, ale powinno byćchown root:root
ichmod 700
):#!/bin/bash commands=("man" "pwd" "ls" "whoami") timestamp(){ date +'%Y-%m-%s %H:%M:%S'; } log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; } trycmd() { # Provide an option to exit the shell if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]] then exit # You can do exact string matching for some alias: elif [[ "$ln" == "help" ]] then echo "Type exit or q to quit." echo "Commands you can use:" echo " help" echo " echo" echo "${commands[@]}" | tr ' ' '\n' | awk '{print " " $0}' # You can use custom regular expression matching: elif [[ "$ln" =~ ^echo\ .*$ ]] then ln="${ln:5}" echo "$ln" # Beware, these double quotes are important to prevent malicious injection # For example, optionally you can log this command log COMMAND "echo $ln" # Or you could even check an array of commands: else ok=false for cmd in "${commands[@]}" do if [[ "$cmd" == "$ln" ]] then ok=true fi done if $ok then $ln else log DENIED "$cmd" fi fi } # Optionally show a friendly welcome-message with instructions since it is a custom shell echo "$(timestamp) Welcome, $(whoami). Type 'help' for information." # Optionally log the login log LOGIN "$@" # Optionally log the logout trap "trap=\"\";log LOGOUT;exit" EXIT # Optionally check for '-c custom_command' arguments passed directly to shell # Then you can also use ssh user@host custom_command, which will execute /root/rbash.sh if [[ "$1" == "-c" ]] then shift trycmd "$@" else while echo -n "> " && read ln do trycmd "$ln" done fi
Wszystko, co musisz zrobić, to ustawić ten plik wykonywalny jako swoją powłokę logowania. Na przykład, edytować swój
/etc/passwd
plik i zastąpić bieżącą powłokę logowania tego użytkownika/bin/bash
z/root/rbash.sh
.To tylko prosty przykład, ale możesz zrobić to tak zaawansowanym, jak chcesz, pomysł istnieje. Uważaj, aby nie zablokować się, zmieniając powłokę logowania swojego i jedynego użytkownika. I zawsze testuj dziwne symbole i polecenia, aby sprawdzić, czy jest to rzeczywiście bezpieczne.
Można przetestować go z:
su -s /root/rbash.sh
.Uważaj , pamiętaj, aby dopasować całe polecenie i uważaj na symbole wieloznaczne! Lepiej wykluczyć bash symboli, takich jak
;
,&
,&&
,||
,$
, i backticks aby się upewnić.W zależności od swobody, jaką dajesz użytkownikowi, nie będzie to dużo bezpieczniejsze niż to. Zauważyłem, że często potrzebowałem tylko użytkownika, który ma dostęp tylko do kilku odpowiednich poleceń i w takim przypadku jest to naprawdę lepsze rozwiązanie. Czy jednak chcesz dać więcej wolności, więzienie i pozwolenia mogą być bardziej odpowiednie. Błędy są łatwe do zrobienia i zauważone dopiero, gdy jest już za późno.
źródło
ln="service httpd restart"
, z:${ln[@]}
. Pamiętaj jednak, aby pomyśleć o kwestiach bezpieczeństwa, w takim przypadku przydatna byłaby biała lista zawierająca tylko znaki alfanumeryczne i białe spacje. Ale możesz też po prostu zrobić:if [[ "$ln" == "restart-httpd"];then service httpd restart;fi
i pracować z takimi prostymi poleceniami./root/rbash.sh: Permission denied
Próbowałem też chmod 777/root/rbash.sh
do/etc/shells
? To zależy od dystrybucji. Możesz także spróbować tymczasowo wyłączyćselinux
i sprawdzić komunikaty dziennika pod kątem wskazówek (spójrz na sygnaturę czasową) w plikach w formacie/var/log
.Możesz spojrzeć na ustawienie więzienia .
źródło
GNU Rush może być najbardziej elastycznym i bezpiecznym sposobem na osiągnięcie tego:
źródło
Innym sposobem spojrzenia na to jest użycie list ACL POSIX, musi być obsługiwane przez twój system plików, jednakże możesz precyzyjnie dostroić wszystkie polecenia w Linuksie tak samo, jak masz taką samą kontrolę w Windows (tylko bez ładniejszego interfejsu użytkownika ). połączyć
Inną rzeczą, na którą należy zwrócić uwagę, jest PolicyKit .
Będziesz musiał trochę googlować, aby wszystko działało, ponieważ zdecydowanie nie jest to w tej chwili mocna strona Linuksa.
źródło
[Ujawnienie: napisałem sshdo, które opisano poniżej]
Jeśli chcesz, aby logowanie było interaktywne, ustawienie powłoki z ograniczeniami jest prawdopodobnie właściwą odpowiedzią. Ale jeśli istnieje rzeczywisty zestaw poleceń, na które chcesz zezwolić (i nic więcej) i jest w porządku, aby te polecenia były wykonywane indywidualnie przez ssh (np. Ssh user @ host cmd arg blah blah), to ogólne polecenie umieszczania białej listy na ssh może być tym, czego potrzebujesz. Jest to przydatne, gdy polecenia są w jakiś sposób skryptowane po stronie klienta i nie wymagają od użytkownika rzeczywistego wpisywania polecenia ssh.
Do tego służy program o nazwie sshdo. Kontroluje, które polecenia mogą być wykonywane przez przychodzące połączenia ssh. Można go pobrać pod adresem:
http://raf.org/sshdo/ (przeczytaj strony podręcznika tutaj) https://github.com/raforg/sshdo/
Posiada tryb uczenia, który pozwala na wykonywanie wszystkich poleceń, a także opcję --learn do tworzenia konfiguracji potrzebnej do trwałego zezwalania na wyuczone polecenia. Wtedy tryb treningu można wyłączyć, a inne polecenia nie będą wykonywane.
Posiada również opcję --unlearn, która zatrzymuje zezwalanie na polecenia, które nie są już używane, aby zachować jak najmniejsze uprawnienia, gdy wymagania zmieniają się w czasie.
Jest bardzo wybredny, jeśli chodzi o to, na co pozwala. Nie pozwoli na polecenie z żadnymi argumentami. Dozwolone są tylko pełne polecenia powłoki.
Ale obsługuje proste wzorce do reprezentowania podobnych poleceń, które różnią się tylko cyframi pojawiającymi się w linii poleceń (np. Numery sekwencji lub znaczniki daty / czasu).
To jest jak zapora ogniowa lub kontrola białej listy dla poleceń ssh.
I obsługuje różne polecenia, które są dozwolone dla różnych użytkowników.
źródło