Włącz dostęp do powłoki SSH, ale wyłącz dostęp SFTP

21

Szukałem realnej odpowiedzi na to pytanie, a większość odpowiedzi zawiera porady, jak tego nie robić. Oto jednak scenariusz i jego konieczność:

Mam aplikację konsolową, aw każdym pliku .profile każdego użytkownika znajduje się polecenie uruchamiania aplikacji, a bezpośrednio po poleceniu, które ją uruchamia, jest polecenie „exit”, które wylogowuje ich z systemu. Chcę tylko, aby mogły uzyskać dostęp do tej aplikacji konsoli za pośrednictwem dostarczonego przez nią interfejsu. Po uruchomieniu aplikacja wyświetla użytkownikowi listę klientów, do których można uzyskać dostęp za pośrednictwem aplikacji, przy czym każdy klient ma własny katalog danych. Użytkownicy mają dostęp tylko do klientów, do których będą potrzebować dostępu.

Teraz jest problem: jeśli dam użytkownikom dostęp SSH, będą oni mogli również zalogować się przy użyciu klienta SFTP, co da im bezpośredni dostęp do katalogów danych aplikacji, co jest BARDZO niepożądane, ponieważ to również da mają dostęp do katalogów danych, do których nie powinni mieć dostępu.

To była tak prosta rzecz do zrobienia przy użyciu kombinacji telnet / FTP, ale teraz, gdy chcę dać użytkownikom dostęp z dowolnego miejsca w Internecie, nie byłem w stanie znaleźć sposobu na wyłączenie ich z SFTP, podczas gdy nadal pozwalając im na dostęp do powłoki, w której mogą uruchomić aplikację.

sosaisapunk
źródło
8
Zapominam o szczegółach, ale myślę, że SSH pozwala ograniczyć użytkownikom uruchamianie jednego polecenia podczas logowania. Nie dostają pełnego dostępu do powłoki, jeśli to skonfigurujesz. Może to być przydatne w twoim przypadku użycia. (W końcu można emulować dostęp SFTP za pomocą SSHFS. Wyłączenie SFTP nie powstrzyma umiarkowanie zdeterminowanego użytkownika przed dostępem do dowolnego pliku, do którego ma dostęp jego konto użytkownika.)
David Z
3
Dodatkowo możesz rozważyć „chrootowanie” użytkowników. a dla dostępu do zapasowych danych wygląda to na problem projektowy
Dennis Nolte,
2
Używanie .profiledo tego brzmi jak złe rozwiązanie. Wierzę, że skonfigurowanie użytkownika z alternatywną powłoką miałoby o wiele więcej sensu.
kasperd,
3
Nie próbuj używać tej .profilesztuczki, aby ograniczyć dostęp, ponieważ omijanie jest trywialne. (szczegóły znajdują się w mojej odpowiedzi)
Aleksi Torhamo,

Odpowiedzi:

22

Edytować:

W przypadku, gdy nie jest to oczywiste, poniższa odpowiedź nie jest przeznaczona jako bezpieczna metoda zapobiegania używaniu SFTP przez osoby mające dostęp do powłoki z serwera. To tylko odpowiedź, która wyjaśnia, jak wyłączyć to z widoczności zewnętrznej. Dyskusję na temat bezpieczeństwa na poziomie użytkownika można znaleźć w odpowiedziach @cpast i @Aleksi Torhamo. Jeśli Twoim celem jest bezpieczeństwo, ta odpowiedź nie jest właściwa. Jeśli koncentrujesz się na widoczności prostych usług, to jest to twoja odpowiedź.

Przechodzimy teraz do oryginalnej odpowiedzi:


Skomentuj obsługę sftp w sshd_config (i oczywiście zrestartuj sshd):

#Subsystem sftp /usr/lib/openssh/sftp-server

Wesley
źródło
1
Czasami linia może byćSubsystem sftp internal-sftp
Kondybas
1
Mam Subsystem sftp /usr/libexec/sftp-server Ale to załatwiło sprawę. Dziękuję bardzo
sosaisapunk,
16
To nie brzmi realistycznie. Jeśli możesz wykonać dowolne polecenia na serwerze, możesz uruchomić program po stronie serwera sftp. Nawet jeśli nie jest zainstalowany, możesz go ponownie wdrożyć jako polecenie długiej powłoki i zlecić klientowi sftp wysłanie tego polecenia zamiast sftp. Ta metoda może sprawić, że korzystanie z sftp będzie mniej wygodne, ale nie ma sposobu, aby użytkownik, który może uruchomić dowolne polecenia, nie używał tych poleceń do przesyłania plików.
R ..
1
@sosaisapunk To nieprawda. Użytkownicy mogą uruchamiać dowolne polecenia za pomocą ssh user@host command, ponieważ .profilenie zostaną uruchomione, jeśli to zrobisz, a zatem Twoja aplikacja w ogóle się nie uruchomi. Mogą uzyskać pełny dostęp do powłoki, po prostu mówiąc ssh -t user@host bash. Po prostu spróbuj, a zobaczysz. Podsystem jest tylko aliasem poleceń; jeśli mogliby wcześniej używać sftp, nadal mogliby go używać - i każdego innego polecenia, jakie chcieli. Przeczytaj moją odpowiedź poniżej.
Aleksi Torhamo
1
@sosaisapunk: Nie, chodzi o to, że możesz to zrobić za pomocą ssh, ale nie za pomocą, .profileponieważ nie jest on przeznaczony dla bezpieczeństwa i można go łatwo ominąć. W mojej odpowiedzi wymieniłem trzy różne metody robienia tego za pomocą ssh. W skrócie, po prostu przenieś wywołanie aplikacji z .profileskryptu powłoki i albo 1) ustaw skrypt powłoki jako powłokę użytkownika 2) ustaw skrypt powłoki jako (odpowiednio dopasowany) ForceCommandw sshd_config3) przełącz na uwierzytelnianie za pomocą klucza publicznego i ustaw skrypt powłoki jak commandw .ssh/authorized_keys. (Ponadto powinieneś używać @name, aby ludzie byli powiadamiani o komentarzach)
Aleksi Torhamo
28

Jak wspomnieli inni, wyłączenie sftpnie jest prawie wystarczające - użytkownik z nieograniczonym sshdostępem może przeglądać każdy plik, do którego konto ma uprawnienia do przeglądania, może modyfikować wszystko, do czego ma uprawnienia, i może łatwo pobrać wszystko, co może przeczytać samodzielnie maszyna. Jedynym sposobem na powstrzymanie ich przed tym jest ograniczenie ich dostępu. Nie jest też idealnym poleganiem na .profileograniczaniu użytkowników, ponieważ nie po to jest (Edycja: jak wspomina Aleksi w swojej odpowiedzi, omijanie jest w rzeczywistości banalne .profile; chodzi o .profileto, że jest to dla wygody, a nie bezpieczeństwa, więc nie jest przeznaczone do ograniczenia użytkownika. Używaj rzeczy zaprojektowanych dla bezpieczeństwa, takich jak rzeczy poniżej, aby zapewnić bezpieczeństwo).

Można to zrobić na dwa podstawowe sposoby: możesz ograniczyć je za pomocą uprawnień do plików lub zmusić je do uruchamiania tylko aplikacji konsoli. Drugi sposób jest lepszy: Przypisz użytkowników, którzy powinni być ograniczeni do aplikacji konsoli do grupy (np. customers); następnie sshd_configdodaj następujące wiersze:

Match Group customers
ForceCommand /path/to/app

Dzięki temu wszystkie połączenia od użytkowników w tej grupie otwierają aplikację konsoli; nie mogą uruchomić niczego innego, w tym sftpnarzędzia serwera. To również powstrzymuje ich przed robieniem czegokolwiek innego w systemie, i w przeciwieństwie do tego .profile, używa samego serwera SSH ( .profileogranicza je w powłoce, ForceCommandzapobiega także robieniu innych rzeczy, które nie wymagają uruchomienia powłoki). Również w przeciwieństwie do .profiletego, jest to zaprojektowane jako kwestia bezpieczeństwa; jest specjalnie zaprojektowany, aby opierać się unikaniu go przez złośliwego użytkownika.

(Prawdopodobnie gorsza) alternatywa polegałaby na utworzeniu nowego użytkownika do uruchomienia aplikacji konsoli. Następnie ograniczysz katalogi danych do tego użytkownika, ustawisz aplikację konsolową należącą do tego użytkownika i uruchomisz u+sprogram. To jest setuidtrochę; oznacza to, że ktoś, kto uruchamia program konsoli, robi to z uprawnieniami właściciela programu. W ten sposób użytkownik sam nie ma dostępu do katalogów, uzyskuje je tylko przez program. Jednakże, należy prawdopodobnie wystarczy użyć ForceCommand, jako że ogranicza cały dostęp do „po prostu uruchomić ten program”.

cpast
źródło
4
Chciałbym dodać, że ForceCommandnie uniemożliwia przekierowania portów SSH.
nyuszika7h,
1
W rzeczywistości poleganie na .profileczymś więcej niż „nie jest idealne”; łatwo go ominąć (szczegóły w mojej odpowiedzi), a zatem nie zapewnia żadnej ochrony, tylko fałszywe poczucie bezpieczeństwa.
Aleksi Torhamo
@AleksiTorhamo Ah. Podejrzewałem, że możesz to ominąć, ale nie byłem pewien, w jaki sposób (generalnie podejrzewam, że rzeczy nieprzeznaczone dla bezpieczeństwa można obejść). Dzięki za szczegóły jak!
cpast
15

Nie próbuj tego robić, .profileponieważ nie zapewnia żadnych zabezpieczeń i nie ogranicza dokładnie niczego!

To nie ma znaczenia, co można umieścić w .profile, gdyż można go po prostu bypass daje komendę, aby uruchomić w wierszu polecenia ssh, tak: ssh user@host command. W ten sposób nadal możesz uzyskać normalny dostęp do powłoki ssh -t user@host bash.

Wyłączenie podsystemu sftp, jak wspomniano w innej odpowiedzi, wcale nie pomaga. Podsystemy są w zasadzie tylko aliasami do poleceń i nadal możesz normalnie używać sftp, wykonując to sftp -s /path/to/sftp-executable user@host.

Jak powiedzieli cpast i niektórzy komentatorzy, powinieneś użyć odpowiednich mechanizmów ograniczających dostęp. To jest,

  • Użyj ForceCommandwsshd_config
  • Użyj logowania bez hasła i command="..."do.ssh/authorized_keys
  • Zmień powłokę użytkownika na coś, co ogranicza jego możliwości

Uwagi:

  • command="..." dotyczy tylko jednego klucza, więc nie ogranicza logowania ssh dla użytkownika używającego hasła lub innego klucza
  • Możesz także chcieć ograniczyć przekierowanie portów itp. (Przekierowanie portów, przekierowanie x11, przekierowanie agenta i alokacja pty to te, o których słyszałem)
    • AllowTcpForwarding itp. w sshd_config
    • no-port-forwarding itp. w .ssh/authorized_keys
  • Jeśli masz uruchomione inne demony (np. FTP), powinieneś sprawdzić, czy nie wpuszczają użytkownika (niektóre demony podejmują tę decyzję na podstawie powłoki użytkownika, więc jeśli to zmienisz, możesz to sprawdzić ponownie)
  • Możesz zmienić powłokę użytkownika na skrypt, który robi to, co chcesz; działa albo bez argumentów, albo jakscript -c 'command-the-user-wanted-to-run'
  • Zarówno ForceCommandi command="..."uruchom polecenie przez powłokę użytkownika, aby nie działały, jeśli powłoka użytkownika jest ustawiona na np. /bin/falselub/sbin/nologin

Oświadczenie: W żadnym wypadku nie jestem ekspertem w tej sprawie, więc chociaż mogę powiedzieć, że .profilerzecz nie jest bezpieczna, nie mogę obiecać, że nie ma „gotcha” innymi metodami, których nie znam o. O ile mi wiadomo, są bezpieczne, ale nie byłbym pierwszą osobą, która się myli w Internecie.

Aleksi Torhamo
źródło
1
Wydaje się, że przynajmniej na ForceCommandi zmuszony pozbawione hasła logowania z command=W authorized_keys, a to zostało pominięte wcześniej, że to z powodu błędu na serwerze: jest przeznaczony do zabezpieczania zawartości przed złośliwego użytkownika, a użytkownik z pominięciem liczy się jako poważna luka na serwerze SSH (i dlatego jest poprawką priorytetową). Jak zauważyłeś, można go .profileobejść z założenia: ponieważ nie jest uważany za funkcję bezpieczeństwa, obejście go przez użytkownika jest całkowicie OK z punktu widzenia dewelopera powłoki.
cpast
1
@cpast: Tak, myślałem o istnieniu większej liczby funkcji, takich jak przekierowywanie portów. Mam na myśli, że jeśli nie wiedziałeś, że ssh pozwala na przekierowanie portów i po prostu użyłeś go ForceCommanddo ograniczenia dostępu, a miałeś demona, który tylko nasłuchuje połączeń lokalnie i nie wykonuje uwierzytelnienia, użytkownik ssh może nadal uzyskać dostęp do demona. Wymienione przeze mnie funkcje to np. Rozwiązania hostingowe git zwykle wyłączają się i nie widziałem żadnych innych „złych” wyglądających na stronach podręcznika, ale nie znalazłem też żadnych oficjalnych „w ten sposób ForceCommandbezpiecznie używasz ” dokumentu.
Aleksi Torhamo,
Wprawdzie ~/.profilejest edytowalny przez użytkownika i nie jest pomocny ze względów bezpieczeństwa, ale czy możesz uczynić technikę cpast znaczącą, wprowadzając ją /etc/profile? Możesz sprawdzić identyfikator UID, aby ograniczyć go do odpowiednich użytkowników.
pisklęta
1
@ chicks: Nie, ma dokładnie ten sam problem. Problemem nie jest to, że plik można edytować przez użytkownika; Problem polega na tym, że oba pliki można całkowicie ominąć. Pliki są używane tylko do powłok logowania, które otrzymujesz, jeśli tylko powiesz ssh user@host, ale jeśli powiesz ssh, aby uruchomił polecenie - tj. ssh user@host command- nie masz już powłoki logowania, a pliki w ogóle nie są dotykane. Możesz więc w prosty sposób ominąć wszelkie ograniczenia, które ktoś próbował stworzyć z plikami, po prostu podając dodatkowy argument ssh.
Aleksi Torhamo
2
@ chicks: Właśnie zdałem sobie sprawę, że wspomniałeś o cpast; metoda w odpowiedzi cpast nie używa .profile, używa sshd_configi powinna być bezpieczna. Wymienia tylko .profilejako metodę, której nie powinieneś używać do tego.
Aleksi Torhamo
1

Możliwe jest włączenie SSH i wyłączenie SFTP zarówno globalnie, jak i dla użytkownika / grupy.

Potrzebuję tego osobiście, ponieważ chcę dać dostęp do niektórych repozytoriów git przez SSH i lubię wyłączać systemy, które nie są potrzebne. W takim przypadku SFTP nie jest potrzebne.

Globalnie

Możesz wyłączyć SFTP dla wszystkich użytkowników na kilka sposobów.

Brakujący podsystem

Demon SFTP używany przez SSH można skonfigurować za pomocą Subsystemsłowa kluczowego. Z sshd_config(5)instrukcji:

Subsystem
        Configures an external subsystem (e.g. file transfer daemon).
        Arguments should be a subsystem name and a command (with optional
        arguments) to execute upon subsystem request.

        The command sftp-server(8) implements the “sftp” file transfer
        subsystem.

        Alternately the name “internal-sftp” implements an in-process
        “sftp” server.  This may simplify configurations using
        ChrootDirectory to force a different filesystem root on clients.

        By default no subsystems are defined.

Ostatni wiersz sugeruje, że powinno wystarczyć, aby nie definiować żadnego podsystemu dla „sftp”.

Fałszywe kłamstwo

Możesz także wyłączyć SFTP, ustawiając demona SFTP używanego przez SSH na coś nieużytecznego. Na przykład skonfiguruj podsystem „sftp”, aby /bin/false:

Subsystem sftp /bin/false

Gdy coś próbuje się zalogować przez SFTP, demon SSH próbuje odrodzić się „demon sftp” /bin/false. /bin/falseProgram robi tylko jedno, a to zwraca kod błędu. Próba połączenia SFTP została skutecznie odrzucona.

Na użytkownika / grupę

Możliwe jest również wyłączenie SFTP dla użytkownika, grupy lub kilku innych kryteriów.

To nie działa, jeśli chcesz, aby użytkownik otrzymywał regularne polecenia powłoki. Nie ma to również sensu, ponieważ można obejść większość rzeczy, jeśli masz dostęp do powłoki. Działa to tylko wtedy, gdy chcesz dać dostęp do określonego programu.

Pasujący

Aby dopasować zestaw użytkowników, możesz skonfigurować SSH za pomocą Matchsłowa kluczowego. Z sshd_config(5)instrukcji:

Match
        ...

        The arguments to Match are one or more criteria-pattern pairs or the
        single token All which matches all criteria.  The available criteria
        are User, Group, Host, LocalAddress, LocalPort, and Address.  The
        match patterns may consist of single entries or comma-separated
        lists and may use the wildcard and negation operators described in
        the PATTERNS section of ssh_config(5).

        ...

Kilka przykładów:

  • Match User eva pasuje do użytkownika „eva”
  • Match User stephen,maria pasuje do użytkowników „stephen” i „maria”
  • Match Group wheel,adams,simpsons dopasowuje grupy „koło”, „adams”, „simpsonowie”

Jeśli chcesz uzyskać więcej informacji, w sshd_config(5)instrukcji jest mnóstwo .

Wymuszone polecenie

Zwykle dostajesz powłokę logowania użytkownika, gdy łączysz się przez SSH, ale SSH można skonfigurować tak, aby wymuszał określone polecenie. Polecenie jest wymuszone dla dowolnego połączenia SSH, w tym SFTP, dlatego możesz mieć możliwość wymuszenia żądanego polecenia.

Polecenie wymuszenia można skonfigurować za pomocą ForceCommandsłowa kluczowego. Z sshd_config(5)instrukcji:

ForceCommand
        Forces the execution of the command specified by ForceCommand,
        ignoring any command supplied by the client and ~/.ssh/rc if
        present.  The command is invoked by using the user's login shell
        with the -c option.  This applies to shell, command, or subsystem
        execution.  It is most useful inside a Match block.  The command
        originally supplied by the client is available in the
        SSH_ORIGINAL_COMMAND environment variable.  Specifying a command of
        “internal-sftp” will force the use of an in-process sftp server that
        requires no support files when used with ChrootDirectory.  The
        default is “none”.

Możesz więc wymusić ograniczoną komendę, której chcesz użyć ForceCommand <your command>. Na przykład:

Match User kim
        ForceCommand echo 'successful login man, congrats'

Przykład

W moim przypadku, w którym chcę dać dostęp do git, potrzebuję tylko użytkownika git-shell. To jest sekcja, która wyłącza SFTP dla moich użytkowników git, wraz z kilkoma opcjami bezpieczeństwa:

Match Group git

        # have to do this instead of setting the login shell to `git-shell`,
        # to disable SFTP
        ForceCommand /usr/bin/git-shell -c "$SSH_ORIGINAL_COMMAND"

        # disable stuff we don't need
        AllowAgentForwarding no
        AllowTcpForwarding no
        AllowStreamLocalForwarding no
        PermitOpen none
        PermitTunnel no
        PermitTTY no
        X11Forwarding no
aude
źródło
W moim przypadku chciałem zezwolić na dostęp MySQL (nie zezwalając zarówno na dostęp SFTP, jak i okna terminali SSH) dla określonego autoryzowanego klucza (tj. Bez zmian w pliku sshd_config). Udało mi się to zrobić za pomocą następujących opcji ~ / .ssh / Author_keys dla określonego klucza: polecenie = "/ usr / bin / echo 'Dozwolony jest tylko dostęp do MySQL." ", No-pty, no-X11-forwarding, permopen = „127.0.0.1:3306”
Martin_ATS