Zabezpieczanie serwera w wariancie dla umiarkowanych paranoików

dodał 15 marca 2017 o 07:00 w kategorii HowTo  z tagami:
Zabezpieczanie serwera w wariancie dla umiarkowanych paranoików

Aby zabezpieczyć serwer przed większością ataków wystarczy wdrożyć kilka prostych rozwiązań. Co jednak, jeśli ktoś się na naszą maszynę uweźmie i będzie dysponował dużą ilością czasu i pomysłów? Można mu bardziej utrudnić zadanie.

We współpracy z firmą ArubaCloud pokazaliśmy Wam, jak postawić swój serwer backupów, jak skonfigurować własny serwer VPN i podłączyć do niego komputer, telefony komórkowe oraz domowy ruter a także jak schować się przed cenzurą sieci i jak zacząć serwer zabezpieczać, jak postawić swój własny zdalny pulpit i swój serwer WWW oraz jak monitorować dowolnie wybrane pliki lub katalogi. Dzisiaj pokażemy pewną rzadziej spotykaną metodę zabezpieczenia serwera przed wyjątkowo natrętnymi atakującymi.

Po co mi to

Kilka miesięcy temu pokazaliśmy Wam, jak serwer zabezpieczyć – logować się po SSH za pomocą klucza, skonfigurować proste banowanie natrętnych intruzów i aktywować automatyczne aktualizacje. Wiemy jednak, że sporo z Was lubi podnosić poziom swoich zabezpieczeń dużo powyżej przeciętnego, dlatego dzisiaj pokażemy, jak serwer zabezpieczyć tak, by praktycznie nikt nie mógł się do niego połączyć. Nikt – oprócz Was.

Konfigurację pokażemy na przykładzie serwera w Aruba Cloud, sponsora naszych poradników. Jeśli nie macie jeszcze swojej własnej maszyny, to jest to dobra okazja by się w taką wyposażyć. Aruba oferuje dwa miesiące korzystania ze swojego podstawowego serwera gratis – a po zakończeniu promocji będzie on Was kosztował zaledwie 4 złote miesięcznie. Instrukcję jak krok po kroku skorzystać z promocji i uruchomić swój serwer znajdziecie w tym artykule. Jeśli macie już swój serwer – to zapraszamy do lektury kolejnych akapitów.

Pokażemy Wam dzisiaj, jak serwer skonfigurować tak, by nie odpowiadał na połączenia na żadnym porcie – ale byście mogli się do niego połączyć gdy tego zechcecie. Oczywiście można to zrealizować za pomocą reguł firewalla, ograniczających zakres źródłowych adresów IP. Kiedy jednak nie wiecie, z jakiego IP będzie się łączyć, z pomocą przychodzi tzw. port knocking, czyli pukanie do portów. Serwer będzie miał zamknięty port SSH dopóki nie wykonacie określonej w konfiguracji sekwencji połączeń. Gdy Wasz komputer połączy się z odpowiednimi portami we właściwej kolejności za pomocą odpowiednich pakietów, serwer otworzy dla Was SSH. Gdy skończycie pracę, będziecie mogli ten port w podobny sposób zamknąć. Jak takie cudo skonfigurować?

Konfigurujemy serwer

Zainstalujemy usługę knockd która będzie odpowiedzialna za otwieranie portu ssh (tcp/22) po uzyskaniu odpowiedniej sekwencji.

Na początku instalujemy wymagane pakiety do skompilowania usługi knockd ze źródeł:

$ sudo yum install git libpcap-devel.x86_64 autoconf automake

Następnie musimy pozyskać źródło usługi knockd. Usługa ta jest dostępna w serwisie GitHub pod tym adresem. Pozyskujemy źródła knockd za pomocą polecenia git:

git clone https://github.com/jvinet/knock

oraz kompilujemy w następujący sposób:

$ cd knock
$ autoreconf -fi
$ ./configure --prefix=/usr/local/
$ make
$ sudo make install

Po wydaniu polecenia make install plik binarny knockd został skopiowany do katalogu /usr/local/sbin/knockd, natomiast przykładowy plik konfiguracyjny knockd.conf został skopiowany do katalogu /usr/local/etc/.

Edytujemy plik /usr/local/etc/knockd.conf według naszych potrzeb:

[options]
        logfile = /var/log/knockd.log

[openSSH]
        sequence = 4444,8989,6500
        seq_timeout = 5
        tcpflags = syn
        Start_command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

[closeSSH]
        sequence = 4445,8990,6501
        seq_timeout = 5
        tcpflags = syn
        command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT 

W powyższej konfiguracji w sekcji [options] ustawiamy plik logowania – /var/log/knockd.log – w tym pliku będą zapisane wszelkie informacje o zdarzeniach. Następnie w sekcji [openSSH] ustawiamy sekwencję na portach 4444,8989, 6500. Seq_timeout określa maksymalny czas na uzyskanie pełnej sekwencji połączeń do wskazanych przez nas portów – w naszym przykładzie jest to 5 sekund. Tcpflags określa które pakiety mają być uwzględniane – w naszym przypadku są to pakiety tcp z ustawioną flagą SYN.

Jeśli sekwencja będzie poprawna nastąpi uruchomienie polecenia zdefiniowanego w start_command. W opisywanym przykładzie wykonujemy polecenie iptables które dodaje regułę zezwalającą na nawiązanie połączenia z adresu ip, który wykonał poprawną sekwencję do naszego serwera na port 22 (ssh).

Bardzo podobną regułę zastosowano w dyrektywie [closeSSH] w której określono połączenia na porty 4445, 8990, 6501. Wysłanie pakietów tcp z flagą SYN w czasie nie dłuższym niż 5 sekund spowoduje wywołanie komendy iptables w której zdefiniowano zablokowanie dostępu do portu 22 dla adresu ip, który wykonał poprawną sekwencje połączeń.

Plik startowy

Tworzymy i edytujemy plik /etc/systemd/system/knockd.service:

[Unit]
Description=knockd service
After=network.target

[Service]
ExecStart=/usr/local/sbin/knockd -d -c /usr/local/etc/knockd.conf
Type=forking
PIDFile=/var/run/knockd.pid

[Install]
WantedBy=multi-user.target

Aby zastosować zmiany w systemie wydajemy polecenie:

sudo systemctl daemon-reload

i uruchamiamy usługę knockd:

sudo service knockd start

Jeśli chcemy aby usługa była uruchamiana podczas rozruchu systemu, wydajemy polecenie:

sudo systemctl enable knockd

Wysyłamy sekwencję

Serwer otworzy nam port 22/tcp jeśli wykonamy sekwencję prób połączeń na porty określone w konfiguracji: 4444, 8989, 6500.

Sekwencję możemy wykonać za pomocą:

nmap -p 4444,8989,6500 adres-ip-naszego-serwera

lub za pomocą klienta, który został utworzony podczas kompilowania usługi knockd:

knock adres-ip-naszego-serwera 4444:tcp 8989:tcp 6500:tcp

Po wykonaniu powyższych sekwencji usługa knockd powinna otworzyć port 22/tcp, a w logu (/var/log/knockd.log) powinno pojawić się następujące zdarzenie:

[2017-03-07 11:00] nasz-ip: openSSH: Stage 1
[2017-03-07 11:00] nasz-ip: openSSH: Stage 2
[2017-03-07 11:00] nasz-ip: openSSH: Stage 3
[2017-03-07 11:00] nasz-ip: openSSH: OPEN SESAME
[2017-03-07 11:00] openSSH: running command: /sbin/iptables -I INPUT -s nasz-ip -p tcp --dport 22 -j ACCEPT

Przedstawiliśmy przykładową konfigurację która umożliwia otwarcie portu 22/tcp dla usługi ssh po wykonaniu sekwencji połączeń do naszego serwera. Usługę można dostosować do swoich potrzeb jak chociażby ustawienie jakie pakiety tcp powinny być uwzględniane do wykrycia sekwencji – do wyboru mamy pakiety z flagą fin, syn, rst, psh,ack,urg.

Gdy już jesteśmy pewni, że wszystko działa jak należy, możemy zablokować dostęp do ssh wydając polecenie:

iptables -A INPUT -p tcp --dport 22 -j DROP

Dostęp do 22/tcp (ssh) będzie otwierany adresom IP, które wykonały poprawną sekwencję połączeń. Poniżej znajdziecie powyższą instrukcję w wersji wideo:

Wady i zalety

Zalety port knockingu:

  • zabezpiecza przed atakami brute force w ramach protokołu np. SSH,
  • zabezpiecza przed atakami na sam protokół,
  • nawet prosta sekwencja (jak opisana powyżej) wymaga dużego nakładu sił do przełamania,
  • może być jedną z warstw obrony (oprócz uwierzytelnienia loginem, hasłem czy kluczem),
  • otwiera port tylko dla konkretnego adresu IP, który może być zmienny (lub dla wielu, jeśli jest wielu użytkowników znających sekwencję).

Wady port knockingu:

  • w razie awarii demona nasłuchującego połączeń może odciąć od serwera (wtedy przydaje się procedura awaryjna opisana w tym artykule),
  • jeśli ktoś uzyska w inny sposób dostęp do serwera (np. przez dostęp fizyczny), to może w logach zaobserwować prawidłową sekwencję,
  • sekwencja może zostać podsłuchana w ataku MiTM.

Jak w przypadku każdego mechanizmu obronnego to do Was należy decyzja czy warto go zastosować.

Dla pełnej przejrzystości – za przygotowanie oraz opublikowanie powyższego artykułu otrzymujemy wynagrodzenie.