Port knocking i Single Packet Authorization

Spis treści

Poniższy wpis ma na celu zaprezentować jak w prosty sposób dozbroić nieco serwer, tak by znajdujące się na nim usługi były należycie chronione. Zostanie to pokazane na przykładzie SSH, bo chyba każdy serwer posiada zdalny dostęp przez shell'a i za bardzo nie godzi się by zostawić tę usługę otwartą na zewnętrzny świat wirtualny bez jakiegokolwiek nadzoru. Postaramy się tutaj wdrożyć port knocking, z tym, że nie będziemy wykorzystywać do tego celu narzędzia knockd . Skorzystamy za to z fwknop , który eliminuje szereg wad występujących w leciwym już knockd .

Domyślne porty

Chyba każdy już zdołał wyczytać na necie, że pierwsze co trzeba zrobić w przypadku wrażliwych usług internetowych, a do takich zalicza się SSH, to zdjęcie ich z domyślnych portów i przypisanie im portów najlepiej 5-cyfrowych. Ma to na celu zamaskowanie usługi, przez co może być ona bardziej bezpieczna. W przypadku botów skanujących domyślne porty, może i będzie ale ta zmiana nas nie uchroni przed świadomą próbą wykrycia nasłuchującej usługi, bo portów jest przecie tylko 65536. Poza tym, zmiana domyślnych portów może pociągać za sobą dostosowanie konfiguracji szeregu narzędzi klienckich. Nawet jeśli posłużymy się plikiem /etc/services i to w nim określimy domyślne porty, to zawsze pozostaje problem z użytkownikami, którzy nie lubią zmian lub też za nimi nie nadążają. Wobec tego mamy w logach pełno zdarzeń, które mogą wskazywać, że dany serwer pada właśnie ofiarą ataku, a w rzeczywistości może to być użytkownik, który próbuje się zalogować do systemu z płytki live, bo tam przecie domyślne porty są inne.

Zamiast się bawić z przepisywanie portów, dużo lepszym wyjściem jest odpowiednie skonfigurowanie filtru iptables, gdzie zezwalamy na połączenie jedynie określonym klientom. Problem w przypadku dostępu zdalnego jest taki, że wielu użytkowników może się łączyć z danym serwerem i niekoniecznie musi to robić z pewnego określonego miejsca na ziemi. Zatem nawet adresy IP mogą ulegać zmianie i stworzenie reguł dla tych użytkowników może w sporej części przypadków nie być możliwe. Zostawiając przy tym niezbyt filtrowany domyślny port 22, to proszenie się o kłopoty.

Czy jest port knocking

Port knocking ma na celu otwieranie portów, na których nasłuchują usługi, z tym, że w pewnym określonym momencie. W jakim? Tuż przed podłączeniem się zdalnego klienta. W taki sposób, mając demona SSH nasłuchującego na porcie 22, nikt z zewnątrz nie da rady się podłączyć. No bo ten port będzie zablokowany w iptables. Ci klienci, którzy będą mieli prawo się podłączyć, będą też świadomi faktu odfiltrowania portu na zaporze. Wobec tego będą musieli podjąć pewne kroki mające na celu skłonienie firewall'a, by ten im otworzył dany port, wpuścił ich, po czym po chwili ten port zamknął.

Ten mechanizm działa w oparciu o stany połączeń. Z reguły mamy do czynienia z zaporami stanowymi, tj. takimi, które rozróżniają pakiety w stanie NEW, ESTABLISHED, itp. Stan ESTABLISHED jest zawsze akceptowany. Zatem jeśli łączymy się ze zdalnym serwerem, wysyłamy mu pakiet w stanie NEW. Zapora decyduje czy go przepuścić i jeśli tak się dzieje, to po chwili połączenie przechodzi w stan ESTABLISHED i to tutaj trafiają pakiety powiązane z tym połączeniem. Port knocking ma na celu jedynie umożliwienie przejścia tego pakietu w stanie NEW przez zaporę. Odbywa się to przez dodanie do zapory pewnej określonej reguły. W taki sposób klient będzie miał do dyspozycji kilkusekundowe okno, wewnątrz którego będzie w stanie się podłączyć. Po tym czasie, ta reguła przepuszczająca pakiety w stanie NEW zostanie usunięta z zapory automatycznie.

Mechanizm port knocking'u może być jeszcze bardziej uporczywy niż zmiana domyślnego portu, zwłaszcza w przypadku korzystania z knockd . My się nie będziemy zajmować tutaj tym narzędziem, bo jest ono już przestarzałe. Poza tym, sekwencję portów wykorzystywanych przez knockd można bez problemu podsłuchać. Jest jednak o wiele lepsze oprogramowanie do port knocking'u, które wykorzystuje techniki kryptograficzne oferujące uwierzytelnianie konkretnego klienta, co czyni cały proces podłączania praktycznie niewidocznym i bezpiecznym.

Single Packet Authorization (SPA)

fwknop wykorzystuje jeden pakiet (Single Packet Authorization) do otwierania portu/portów i ma za zadanie wyeliminowanie wad, które ma wspomniany wyżej knockd. Proces uwierzytelniania i autoryzacji odbywa się przy pomocy czegoś na wzór zaszyfrowanego ciasteczka. Dane są generowane dla każdego klienta osobno i dostarczane na serwer. Później klienci przesyłają już tylko ciasteczka do serwera i po ich pomyślnym odszyfrowaniu, fwknop może dodać określone reguły do iptables, lub/i wykonywać pewne skrypty. Mając do dyspozycji dwie maszyny, serwer oraz klient, na pierwszej z nich instalujemy pakiet fwknop-server , a na drugiej fwknop-client .

Konfiguracja klienta

Najpierw zajmijmy się konfiguracją klientów. Musimy wygenerować klucze szyfrujące. Wpisujemy zatem w terminalu tę poniższą linijkę:

$ fwknop -A tcp/22 -a 192.168.1.20 -D 192.168.1.50 --key-gen --use-hmac --save-rc-stanza

Poniżej znajduje się wyjaśnienie użytych parametrów:

  • -A -- określa porty, do których klient chce mieć dostęp. Można podać kilka, np. tcp/22,udp/53 .
  • -a -- definiuje adres IP, z którego klient będzie mógł nawiązywać połączenia z serwerem. Ten adres zostanie uwzględniony w regułach iptables.
  • -D -- precyzuje adres serwera.
  • --key-gen -- generuje klucze, które są używane do zaszyfrowania pakietu.
  • --use-hmac -- ustawia tryb HMAC w przypadku szyfrowania uwierzytelnionych komunikacji.
  • --save-rc-stanza -- zapisuje wprowadzone w linijce opcje w pliku ~/.fwknoprc

Zajrzymy zatem do pliku ~/.fwknoprc :

[192.168.1.20]
ALLOW_IP                    192.168.1.50
ACCESS                      tcp/22
SPA_SERVER                  192.168.1.20
KEY_BASE64                  OtJlYqHPeROSwpYbeQt6OVkQykThqPZHUf6m+CBJBos=
HMAC_KEY_BASE64             1OceLkRVoGUIPj7ExOVk7vRZl3Q4uNyusI36ojgx4hJqCL6K6aDys1twjw0o4tFbqE8ZHa6UgTKLVf0aZNf8VQ==
USE_HMAC                    Y

KEY_BASE64 oraz HMAC_KEY_BASE64 to klucze, które musimy przesłać w bezpieczny sposób na serwer. Opcji do precyzowania jest dość sporo i nie będziemy ich tutaj wszystkich omawiać. Niemniej jednak, powyższy kawałek to niezbędne minimum.

Konfiguracja serwera

W przypadku serwera, musimy oczywiście włączyć demona w pliku /etc/default/fwknop-server . Mamy dodatkowo dwa inne pliki, na które musimy rzucić okiem: access.conf oraz fwknopd.conf , oba znajdują się w katalogu /etc/fwknop/ . W pliku access.conf musimy umieścić klucze wszystkich klientów, którzy będą mieć prawo łączyć się do serwera, przykładowo:

SOURCE                      192.168.1.50
OPEN_PORTS                  tcp/22
FW_ACCESS_TIMEOUT           20
REQUIRE_SOURCE_ADDRESS      Y
KEY_BASE64                  OtJlYqHPeROSwpYbeQt6OVkQykThqPZHUf6m+CBJBos=
HMAC_KEY_BASE64             1OceLkRVoGUIPj7ExOVk7vRZl3Q4uNyusI36ojgx4hJqCL6K6aDys1twjw0o4tFbqE8ZHa6UgTKLVf0aZNf8VQ==

Tego typu zwrotek można umieszczać ile się chce. Trzeba jednak pamiętać, że plik jest przeszukiwany od góry do dołu pod kątem dopasowań i pierwsze z nich zostanie zaakceptowane. Opcja FW_ACCESS_TIMEOUT określa czas (w sekundach) otwarcia okna.

Z kolei w pliku fwknopd.conf określamy opcje dla samego demona:

VERBOSE                 1;
PCAP_INTF               eth0;
IPT_INPUT_ACCESS        ACCEPT, filter, tcp, 2, fwknop_input, 1;

Ostatnia linijka z tych powyżej określa, w którym miejscu umieścić łańcuch fwknop_input, do którego to trafiać będą reguły generowane przez fwknopd . W tym przypadku ACCEPT określa politykę reguły, filter tablicę iptables, tcp łańcuch w tej tablicy. Cyfra 2, definiuje pozycję, na której umieścić łańcuch fwknop_input, z kolei zaś cyfra 1 precyzuje, na której pozycji będą dodawane reguły.

Jeśli mamy niestandardową konfigurację interfejsów sieciowych, trzeba sprecyzować, który z nich ma być poddany analizie. W moim przypadku jest to eth0. Jeśli podamy błędy interfejs, np. nie będzie miał adresu IP, demon nie wystartuje. Warto także ustawić tryb verbose i obserwować logi w syslog'u.

Test port knocking'u

Jeśli ustawiliśmy wszystko zgodnie z powyższym opisem, to po przesłaniu ciasteczka, będziemy mieć okno otwarte przez 20s. Na ten czas zostanie dopisana reguła do iptables. Odpalmy zatem na serwerze demona i z maszyny klienckiej przesyłamy ciasteczko do serwera za pomocą poniższej linijki (użyj -v by uzyskać więcej info):

# fwknop -n 192.168.1.20

Pakiet powinien zostać przechwycony, a reguła dodana do iptables. Po 20s, okno powinno się automatycznie zamknąć, a reguła iptables zostać usunięta, co spowoduje odcięcie dostępu do serwera dla nowych połączeń. Dzięki mechanizmowi jaki oferuje fwknop możemy spać spokojnie nawet w przypadku gdy do publicznej wiadomości zostanie podana informacja o jakiejś luce 0day.

Mikhail Morfikov avatar
Mikhail Morfikov
Po ponad 10 latach spędzonych z różnej maści linux'ami (Debian/Ubuntu, OpenWRT, Android) mogę śmiało powiedzieć, że nie ma rzeczy niemożliwych i problemów, których nie da się rozwiązać. Jedną umiejętność, którą ludzki umysł musi posiąść, by wybrnąć nawet z tej najbardziej nieprzyjemniej sytuacji, to zdolność logicznego rozumowania.