W systemach linuxowych rolę zapory ogniowej stanowią najczęściej regułki iptables ewentualnie w przypadku dystrybucji Ubuntu mamy „ułatwiacza” dla iptables w postaci pakietu ufw. Celem zapory ogniowej jest odpowiednie filtrowanie ruchu sieciowego w przypadku serwerów skupiamy się najczęściej na filtrowaniu pakietów przychodzących. Poniżej przedstawiam kilka podstaw dotyczących konfiguracji firewalla jak również praktyczny przykład, który może stanowić podstawę do rozszerzenia filtrowania pakietów o kolejne regułki.
Podstawy
W przypadku serwera, który świadczy podstawowe usługi sieciowe np. WWW, FTP, DNS pracujące na domyślnych portach sprawdzamy także pozostałe usługi na których nasłuchuje nasz serwer. Celem tego procesu jest decyzja, które porty i na jakich protokołach ( tcp / udp ) przepuszczać do naszego serwera.
netstat -tulpn
Na podstawie powyższych informacji uzyskanych za pomocą netstat decydujemy, które usługi mają być odblokowane. Szczegółowy spis usług i przypisanych do nich portów znajdziemy w pliku:
/etc/services
Ustawianie reguł w iptables odbywa się od szczegółu do ogółu ( od góry w dół listy regułek ) jest to bardzo istotna kwestia podczas wpisywania kolejnych regułek do filtrowania ruchu. Jak ktoś jest programistą i korzysta z wyjątków to dobrze wie o co chodzi podczas wyłapywania wyjątków.
Tak więc jeśli bardziej ogólna regułą np. blokująca cały ruch będzie na początku to kolejne reguły zapisane pod nią nie będą już brane pod uwagę. Takie reguły blokujący cały ruch dodajemy na końcu a reguły przed nią będą określały co ma wejść i wyjść z naszego serwera.
W opcjach iptables możemy zauważyć opcje REJECT i DROP, które odrzucają połączenie w kontekście danej reguły. Różnica polega na tym, iż REJECT odrzucając połączenie wysyła do clienta odpowiedni komunikat, natomiast w REJECT nie ma takiej odpowiedzi i pakiet idzie do /dev/null.
Przykład Firewalla
Poniżej praktyczny przykład pliku z zapisanymi regułkami iptables:
#!/bin/bash # Kasowanie wcześniejszych ustawień iptables -F iptables -X # Filtrowanie pakietów iptables -A INPUT -p icmp -j ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -p tcp --dport 53 -j ACCEPT iptables -A INPUT -p udp --dport 53 -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 25 -j ACCEPT iptables -A INPUT -p tcp --dport 587 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT # Poniżej reguła dla połączeń pasywnych dla FTP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Zapisywanie odrzuconych pakietów na wejściu w logach iptables -A INPUT -j LOG --log-prefix "IPTABLES INPUT REJECT: " --log-level 4 iptables -A INPUT -j REJECT iptables -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT # Zapisanie przekierowania pakietów w logach iptables -A FORWARD -j LOG --log-prefix "IPTABLES FORWARD REJECT: " --log-level 4 iptables -A FORWARD -j REJECT # Przepuszczanie pakietów wyjściowych iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Plik z regułkami zapisujemy sobie w bezpiecznym miejscu na przykład w katalogu roota lub w miejscu gdzie trzymane są skrypty dla uruchamianego interfejsu sieciowego.
Ważna kwestią jest możliwość zapisywania informacji z iptables do logów. Najlepiej wymusić stosowanie zapisywania do pliku z logami informacji o zablokowanych połączeniach. Pamiętajmy o odpowiedniej kolejności podczas umieszczania linii z iptables z opcją logowania.
iptables -A INPUT -j LOG --log-prefix "IPTABLES REJECT: " --log-level 4 iptables -A INPUT -j REJECT
Jak widać umieściłem regułę z funkcją zapisu do logów przed regułą najbardziej ogólną a przed pozostałymi regułami dla INPUT, dzięki temu mamy pewność, że w logach będzie informacja o wszystkich zablokowanych pakietach wejściowych INPUT !
Domyślny plik z logami dotyczącymi pracy iptables w dystrybucjach Debian/Ubuntu znajduje się w poniżej lokalizacji:
/var/log/syslog
URUCHAMIANIE FIREWALLA PODCZAS STARTU:
Jeśli chcemy aby skrypt z regułkami iptables był uruchamiany każdorazowo po restarcie systemu to dodajemy odpowiedni wpis do pliku konfiguracyjnego odpowiedzialnego za interfejsy sieciowe.
W dystrybucji Debian/Ubuntu plik z konfiguracją interfejsów znajduje się w lokalizacji: /etc/network/interfaces. Dodajemy poniższą opcję post-up na końcu pliku z ścieżką do pliku z naszymi regułami iptables:
post-up /root/firewall.sh
Plik firewall.sh możemy dla większego porządku zapisać w odpowiednim katalogu przeznaczonym do tego celu:
/etc/network/if-up.d/firewall.sh
Oczywiście nie zapominając aby w opcji post-up w pliku z konfiguracją interfejsów sieciowych zmienić ścieżkę do skryptu z regułami iptables !
+ Opis podstawowych opcji
Opcja | Opis |
---|---|
A | dodanie nowej reguły do łańcucha |
p | protokół jakiego dotyczy reguła ( tcp, udp, icmp itp. ) |
i | interfejs sieciowy dla podanej reguły |
dport | określenie portu docelowego |
j | jakie polecenie ma zostać wykonane po dopasownaiu reguły ( np. ACCEPT, REJECT, DROP, etc. ) |
Przydatne komendy:
Zapis i odczyt konfiguracji firewall dla ipv4:
iptables-save > firewall.txt
iptables-restore < firewall.txt
Status:
iptables -L -n -v
Polecam również program Fail2Ban, który dodaje czasowe ograniczenia wykorzystując iptables monitorując logi serwera pod kątem podejrzanych połączeń. Możemy na przykład zablokować IP clienta po 3-ciej próbie nieudanego logowania na FTP.
Całość była testowana na dystrybucjach Linuksa: Debian, Ubuntu Mate, Raspbian
Słowa kluczowe: firewall, iptables, przykłady firewall, linux, ubuntu, debian, przykład, fail2ban, raspberry