Jedną z najchętniej i najczęściej wykorzystywanych usług na serwerze jest dostęp do powłoki SSH serwera. Bez takiego dostępu raczej trudno byłoby nam administrować serwerem i zarządzać nim. Trudno byłoby instalować i konfigurować aplikacje, usługi. 

Wszyscy wiedzą doskonale czym jest SSH, myślę, że ponad połowa wie, jak działa protokół SSH i jest świadomych faktu szyfrowania połączenia z terminalem, ale czy to wystarczy by czuć się bezpiecznie? 

Z pewnością nie jest to wystarczające, a tym bardziej domyślne ustawienia jakie otrzymujemy wraz z opiekunem pakietu (przez menadżera pakietów) są niewystarczające do tego, aby mówić o bezpieczeństwie na przynajmniej zadowalającym poziomie. 

W dzisiejszym artykule zajmiemy się bezpieczeństwem SSH, gdyż jest to najłatwiejsza droga do administracji i zarządzania serwerem wykorzystywana w codziennej pracy każdego administratora. Warto więc zadbać o to, aby praca z terminalem była bezpieczna. 

Instalacja

Aktualizujemy na początek listę pakietów, a dopiero potem instalujemy usługi. 

apt update 

apt install openssh-server ssh 

Konfiguracja

Domyślne pliki konfiguracyjne znajdują się w katalogu /etc/ssh. 

Konfiguracja samej usługi SSH znajduje się w pliku sshd_config. Co powinniśmy ustawić lub zmienić, aby praca była bezpieczna.

– Port 22

Standardowo usługa SSH nasłuchuje na porcie 22. Istnieją dwie szkoły, dwie teorie i tyle samo argumentów za i przeciw temu, aby zmienić domyślny port 22 usługi SSH na inny. Czy warto to robić? Na pewno warto wiedzieć co jest za, a co przeciw. Ja domyślnie na każdym serwerze zawsze zmieniam port SSH na wyższy, ale decyzja jest zawsze kwestią subiektywną akurat w tym zakresie. 

Za zmianą portu 22 na inny przemawia na pewno fakt, żę wyciszamy logi auth.log gdzie każdorazowa próba logowania jest rejestrowana. Boty potrafią i są niestety natrętne, jeśli nie stosujemy mechanizmów typu port-knocking, blokowania po którejś próbie itd. logi mogą szybko spuchnąć i jeżeli będziemy szukać interesującego nas wpisu może nie być tak prosto. Dodatkowo roboty skanujące sieć internet w poszukiwaniu podatnych usług często zaprogramowane są tak, aby skanować tylko domyślne porty gdyż istnieje większa szansa, że usługa na domyślnym porcie ma też domyślną konfigurację i może nie być aktualizowana przez co już łatwo o podatność i przejęcie serwera. Za zmianą portu więc przemawia fakt, że duża część robotów jeśli nie znajdzie otwartego portu SSH, po prostu pójdzie dalej i zostawi nasz serwer w spokoju. Za zmianą portu przemawia na pewno fakt, że aby dowiedzieć się na którym porcie nasłuchuje usługa, konieczne będzie przeskanowanie zakresu portów co jest i czasochłonne i jeśli mamy monitoring takich prób to szybko zorientujemy się, że ktoś na skanuje i mamy więcej czasu na obronę. 

Przeciwko zmianie portu możemy znaleźć głosy, że i tak roboty – lub potencjalny atakujący – będą chcieli znaleźć SSH, to i tak to zrobią. Przeciwko zmianie, zwłaszcza na wyższe niż 1000 porty znajdziemy głosy o tym, że poniżej portu 1000 mogą nasłuchiwać tylko usługi z uprawnieniami wyższymi, więc wyrzucenie SSH na wyższy port potencjalnie obniża jego bezpieczeństwo. Przeciwko zmianie portu znajdziemy także głosy, że trzeba pamiętać nowe, inne porty zamiast standardowych. 

Czy warto zmieniać? Ja uważam, że warto i zmieniam na każdym serwerze. 

– ListenAddress any

Ta opcja informuje nas o tym, na którym interfejsie ma nasłuchiwać usługa SSH. Jeśli pozostawimy domyślne “any” to SSH będzie nasłuchiwać zarówno na IP lokalnej karty, na zewnętrznym adresie IP, ale także na IPv6. Sugeruję zmianę tej opcji na 

– ListenAddress 0.0.0.0 (lub zamiast 0.0.0.0 wpisujemy adres IP)

Dzięki temu będziemy nasłuchiwać tylko na IP zewnętrznym na protokole v4. 

# Logging
SyslogFacility AUTH
LogLevel VERBOSE
 

Niemniej ważną kwestią jest logowanie tego, co się dzieje. Warto podnieść ten parametr ze standardowego na AUTH I VERBOSE dzięki czemu zalogujemy w pliku auth.log nieco więcej informacji, w tym np. odcisk klucza, którym dany użytkownik zalogował się do terminala. W środowiskach gdzie konieczne jest korzystanie ze wspólnego konta (np. do wdrożenia), dzięki takiemu ustawieniu dowiemy się, kto mimo wszystko zalogował się swoim kluczem na konto. 

– PermitRootLogin prohibit-password
– PubkeyAuthentication yes
– AuthorizedKeysFile .ssh/authorized_keys
– PasswordAuthentication no
– PermitEmptyPasswords no

Nie pozwalajmy na logowanie się do terminala za pomocą hasła. Dzięki takiemu ustawieniu logowanie będzie możliwe wyłącznie za pomocą klucza SSH, co kilkukrotnie zwiększy bezpieczeństwo pracy z konsolą SSH. Dodatkowo wskażmy plik z kluczami publicznymi, które będą mogły autoryzować się w kontach użytkownika. Ponadto ustawimy brak możliwości logowania hasłem oraz brak możliwości logowania się, jeśli konto mimo wszystko puste hasło ma, tak na wszelki wypadek. 

Skrypt wykonywany po poprawnej autoryzacji SSH 

Niewiele osób wie, ale usługa SSH domyślnie ma wbudowaną funkcję wykonywania skryptu bash po poprawnym zalogowaniu się do konta. 

Jeżeli w katalogu z plikami konfiguracyjnymi SSH /etc/ssh umieścimy nowy plik o nazwie dokładnie “sshrc” i tam umieścimy kod skryptu w powłoce BASH to każdorazowo po poprawnym zalogowaniu się do SSH niezależnie od tego czy zdalnie, czy przez powłokę z ograniczonym dostępem jak “rsh” czy poprzez konsolę bez tty (np przez IPMI) to usługa SSH wykona ten skrypt po poprawnej autoryzacji. 

Co możemy umieścić w takim pliku? Wszystko to co w skrypcie BASH. Możemy umieścić tam np. skrypt wysyłający e-maile do administratora o każdej autoryzacji, lub skrypt, który wyśle informację o logowaniu jeśli adres IP znajduje się poza białą listą. Możemy z tego miejsca wysłać dowolnego webhooka, dowolnego calla do api, do backendu innej aplikacji lub zablokować IP, wylogować instruza, możemy także zalogować jego sesję.  

Tak naprawdę lista rzeczy, które dzięki temu możemy zrobić jest niemal nieograniczona. Najprościej będzie skorzystać z powiadomień e-mailowych o logowaniu jeśli adres IP znajduje się poza whitelistą. 

Przykładowy prosty skrypt do powiadomień mógłby wyglądać tak: 

#!/bin/bash
whitelist=”127.0.0.1|192.168.1.10|8.8.8.8”
ip=`echo $SSH_CONNECTION | cut -d ” ” -f 1 | egrep -v „$whitelist”`
if [ ! -z „$ip” ]; then
logger -t ssh-wrapper $USER login from $ip
echo -e „Wykryto logowanie SSH na uzytkownika $USER z adresu IP $ip” | mail -E -s „SSH Logowanie na serwer” adres@email.pl
fi

Dzięki temu, jeśli ktokolwiek spoza naszego zakresu IP zaloguje się do serwera, otrzymamy o tym stosowną informację. Czy to wyczerpuje temat bezpieczeństwa? Na pewno nie, ale jest świetnym elementem startowym do dalszej analizy. W kolejnych krokach powinniśmy zająć się monitorowaniem logów, reagowaniem na próby logowania itd. W kolejnych artykułach podpowiem jak monitorować logi i jakie wnioski z nich wyciągać także w kontekście SSH i pracy z usługami na portach.