Stanisław Fedczuk
Software Engineer
· · 1242 sł.

Zabezpieczanie SSH przed intruzami

5 prostych metod, dzięki którym ograniczysz ryzyko włamania na serwer.

W sieci roi się od skanerów, których celem jest znalezienie serwerów lub usług podatnych na różnego rodzaju ataki. Może to prowadzić do uzyskania nieautoryzowanego dostępu do maszyny lub wycieku poufnych informacji, np. danych osobowych klientów. Każda taka sytuacja może mieć katastrofalne skutki.

Jedną z takich usług jest SSH, która znajduje się na każdym serwerze i zazwyczaj nie jest domyślnie skonfigurowana z myślą o większym bezpieczeństwie. To sprawia, że często znajduje się na celowniku włamywaczy.

Jak sprawdzić czy ktoś skanuje SSH na Twoim serwerze? Wystarczy zajrzeć do pliku /var/log/auth.log. Jeśli zauważyłeś dziwne próby logowania to oznacza, że masz nieproszonych gości, którzy czają się przed drzwiami.

W tym artykule zebrałem kroki jakie podjąłem, aby zabezpieczyć swoje serwery oparte na dystrybucji Ubuntu lub Debian. Nie są to jakieś odkrywcze rady, ale uznałem, że może będą dla Ciebie równie pomocne.

Wyłącz bezpośrednie logowanie na konto root’a

Uzyskanie dostępu do konta root’a jest najbardziej pożądane przez potencjalnego włamywacza, ponieważ pozwala mu zrobić wszystko czego zapragnie. Z tego powodu powinniśmy wyłączyć możliwość bezpośredniego logowania na konto root’a po SSH oraz zadbać o odpowiednie zasady dostępu do serwera.

Każdy użytkownik, który może zalogować się na serwer, powinien mieć odrębne konto, z silnym hasłem. Uzyskanie uprawnień root’a powinno być możliwe dopiero po pomyślnym zalogowaniu na swoje konto. Liczba osób, które mogą uzyskać dostęp do root’a powinna być jak najmniejsza.

  1. Utwórz konto dla siebie i pozostałych użytkowników.
# adduser [USER]
  1. Wymuś zmianę hasła przy pierwszym logowaniu.
# chage -d 0 [USER]
  1. Dodaj wybrane osoby do grupy sudo.
# usermod -aG sudo [USER]

Spróbuj zalogować się na swoje konto ssh [USER]@[SERVER], a następnie za pomocą polecenia sudo su przejdź na konto root’a. Jeśli Ci się udało, to możemy zablokować logowanie na root’a po SSH.

  1. Otwórz plik konfiguracyjny.
# nano /etc/ssh/sshd_config
  1. Ustaw parametr.
PermitRootLogin no
  1. Przeładuj konfigurację.
# service ssh reload

Przy próbie zalogowania na konto root’a ssh root@[SERVER], powinieneś zobaczyć informację o odmowie dostępu.

Wymuś stosowanie bezpiecznych haseł

Każdy z użytkowników serwera może ustawić dowolne hasło do swojego konta. Im trudniejsze, tym lepsze. Niestety, nie zawsze możemy mieć pewność, że każdy takie ustawi. Z tego powodu najlepiej wymusić stosowanie bezpiecznych haseł.

  1. Zainstaluj dodatkowe pakiety.
# apt install libpam-pwquality cracklib-runtime
  1. Otwórz plik z konfiguracją.
# nano /etc/pam.d/common-password
  1. Wprowadź poniższe ustawienia.
password    requisite    pam_pwquality.so retry=3 minlen=12 maxrepeat=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 difok=3 gecoscheck=1 reject_username enforce_for_root
  1. Zresetuj serwer.
# reboot

Wyjaśnijmy pokrótce co oznaczają poszczególne parametry:

Zaloguj się na serwer i spróbuj zmienić swoje hasło za pomocą komendy passwd. Hasło powinno zostać zaakceptowane dopiero wtedy, gdy zostaną spełnione wszystkie wymagane kryteria. Hasła możesz generować oraz przechowywać korzystając np. z KeePass, 1Password, LastPass lub innego menedżera.

Aktywuj logowanie wyłącznie po kluczach

Lepszym rozwiązaniem od logowania za pomocą hasła jest logowanie po kluczach. To zabezpieczenie znacznie utrudnia potencjalnym włamywaczą dostanie się do serwera. A w praktyce jest znacznie wygodniejsze, gdyż pozwala użytkownikom na autoryzację bez podawania hasła, przy każdej próbie dostępu do serwera.

  1. Wygeneruj parę kluczy: jeden prywatny i jeden publiczny.
$ ssh-keygen -t rsa -b 4096
  1. Podczas generowania klucza prywatnego, możesz dodatkowo zabezpieczyć go hasłem, na wypadek, gdyby klucz dostał się w niepowołane ręce.
  2. Skopiuj klucz publiczny na serwer.
$ ssh-copy-id [USER]@[SERVER]

Spróbuj zalogować się na serwer ssh [USER]@[SERVER]. Powinieneś uzyskać dostęp bez podawania hasła. I to byłoby wszystko, gdyby nie pewien problem.

Jeśli nie posiadasz klucza na swoim komputerze, serwer zapyta Cię o hasło. To nie jest pożądane przez nas zachowanie. Aby wymusić logowanie wyłącznie po kluczach, musimy wprowadzić drobne zmiany w konfiguracji serwera SSH.

  1. Otwórz plik konfiguracyjny.
# nano /etc/ssh/sshd_config
  1. Wprowadź poniższe ustawienia.
PasswordAuthentication no
ChallengeResponseAuthentication no
  1. Przeładuj konfigurację.
# service ssh reload

Jeśli spróbujesz zalogować się na swoje konto nie posiadając klucza, powinieneś zobaczyć komunikat o odmowie dostępu.

Przenieś SSH na inny port

Wiele sieciowych skanerów próbuje wykorzystać luki w znanych usługach, zakładając, że są uruchomione na standardowych portach. Prostym lekarstwem na tą dolegliwość jest zmiana domyślnego portu na inny. W ten sposób możemy wyciąć większość niezbyt zaawansowanych skanerów sieciowych.

  1. Otwórz plik konfiguracyjny.
# nano /etc/ssh/sshd_config
  1. Zmień parametr Port 22 na inny, np. Port 9222 i zapisz plik.
  2. Przeładuj konfigurację.
# service ssh reload
  1. Sprawdź, czy możesz się zalogować.
$ ssh [USER]@[SERVER] -p 9222

Niestety, sprytniejsze skanery potrafią obejść taką sztuczkę. W takiej sytuacji trzeba skorzystać z bardziej wyszukanych rozwiązań.

Ukryj port SSH

Otwarte porty to zachęta dla intruzów. Co więcej, usługi często udostępniają podstawowe informacje o sobie, np. nazwę oraz wersję oprogramowania. To niestety nie jest dla nas korzystne. Im więcej atakujący o nas wie, tym lepsze metody ataku może dobrać, np. poszukać gotowych exploitów pod krytyczne błędy w usługach działających na naszym serwerze. Z tego powodu warto zablokować dostęp do portów, które nie muszą być dostępne publicznie i zezwolić na połączenia tylko z zaufanych adresów IP.

  1. Zainstaluj firewall.
# apt install ufw
  1. Ustal domyślną politykę połączeń: zablokuj cały ruch przychodzący i zezwól na cały ruch wychodzący.
# ufw default allow outgoing
# ufw default deny incoming
  1. Otwórz porty dla każdej usługi, która powinna być dostępna publicznie, np. usługa HTTP.
# ufw allow http
# ufw allow https
  1. Zezwól na dostęp do SSH z zaufanego IP.
# ufw allow from [IP] to any port 9222
  1. Aktywuj firewall.
# ufw enable
  1. Sprawdź status firewalla.
# ufw status

Jeśli spróbujesz zalogować się z niezaufanego adresu IP, serwer powinien odrzucić połączenie.

Gdy wszyscy użytkownicy posiadają stałe IP sprawa jest prosta: wystarczy dodać każdy adres do firewalla i załatwione. Problem pojawia się, gdy chcemy się logować ze zmiennych adresów IP. W tej sytuacji istnieją dwa rozwiązania: skorzystać z metody otwierania portów na żądanie lub utworzyć sieć prywatną (VPN).

Otwieranie portów na żądanie polega na wysłaniu pakietu lub sekwencji pakietów, które serwer zinterpretuje jako żądanie otwarcia danego portu. Przez określony czas lub do momentu wysłania sekwencji zamykającej, port będzie dostępny publicznie, dzięki czemu będzie można się połączyć.

Popularną, choć przestarzałą implementacją port knocking jest knockd. Główną wadą tej metody jest możliwość podsłuchania transmisji wykorzystywanej do otwierania portów. Nowszym i bezpieczniejszym rozwiązaniem jest technika single packet authorization, z której można skorzystać za pomocą fwknop.

Z kolei utworzenie sieci prywatnej wymaga wygospodarowania dodatkowego serwera, który będzie pełnił rolę węzła brzegowego. Jego IP należy dodać do listy zaufanych adresów na każdym serwerze jakim zarządzamy. Chcąc się połączyć z danym serwerem, najpierw musimy się połączyć z VPN, a dopiero potem z konkretnym serwerem.

Niewątpliwą zaletą VPN jest to, że możemy za nim schować również inne usługi, które nie powinny być dostępne dla osób postronnych. Warto jednak mieć na uwadze, że mając tylko jeden węzeł brzegowy narażamy się na ryzyko utraty dostępu do sieci w przypadku jego awarii. Z tego powodu warto mieć drugi węzeł, lub przynajmniej jedno stałe IP np. w biurze.

Czy to wystarczy?

Za pomocą tych wskazówek powinniśmy skutecznie wyciąć większość skanerów sieciowych oraz mniej doświadczonych hakerów, próbujących dobić się do naszego SSH. A tych bardziej doświadczonych… no cóż, może powinniśmy zatrudnić ;)