W dzisiejszym artykule w sekcji bezpieczeństwa serwerów zajmiemy się jedną z najważniejszych kwestii – firewallem. Zbudujemy dzisiaj skuteczny firewall, który pozwoli nam na wstępną ochronę naszego serwera przed dostępem intruzów. Dodatkowo wzmocnimy ochronę za pomocą regułek pozwalających na wstępne filtrowanie i odrzucanie pakietów, które nie powinny znaleźć się na naszym serwerze. Na koniec rozbudujemy nasz system ochrony o kilka dodatkowych elementów, dzięki którym obronimy się przed prostymi floodami lub atakami spoofingowymi.

1.    Instalacja iptables w systemie

Debian:

    apt update
    apt install iptables

CentOS:

   yum update
   yum install iptables

2.    Omówienie tablic

Iptables składa się z kilku tablic, których zadaniem jest odpowiednie filtrowanie pakietów wchodzących i wychodzących do systemu Linux. Poniżej opiszę skrótowo wszystkie cztery tablice oraz ich role w procesie przetwarzania i filtrowania pakietów.

raw – tablica najwyższego priorytetu. To tutaj pakiety wpadają na samym początku.

            INPUT – pakiety, które wpadają na wejściu dla serwera
            FORWARD – pakiety, które routujemy na lokalnym serwerze
            OUTPUT – pakiety, które są generowane lokalnie na serwerze

mangle – tablica, w której zmieniamy pakiety i modyfikujemy je

            PREROUTING– tutaj zmieniamy pakiety zanim zostaną zroutowane dalej
            INPUT – pakiety przychodzące do serwera
            OUTPUT – pakiety wychodzące z serwera przed wykonaniem routingu
            FORWARD – pakiety, które lokalnie routujemy na serwerze
            POSTROUTING – pakiety, które zmieniamy już po routingu, ale przed wysłaniem

nat – tablica, w której znajdują się pakiety nawiązujące nowe połączenie z serwerem

            PREROUTING– tutaj zmieniamy pakiety zanim zostaną zroutowane dalej
            OUTPUT – pakiety wychodzące z serwera przed wykonaniem routingu
            POSTROUTING – pakiety, które zmieniamy już po routingu, ale przed wysłaniem

filter – tablica domyślna, tu filtrujemy głównie pakiety

            INPUT – tutaj ustawiamy regułki dla pakietów, które trafiają do serwera
            FORWARD – pakiety, które routujemy wewnętrznie
            OUTPUT – pakiety, które wygenerował serwer

Tablicą domyślną jest “filter” i to tam konfigurujemy główne regułki takie, jak otwieranie i zamykanie portów, dostęp do poszczególnych usług z zewnątrz. W tablicy “nat” umieszczamy regułki służące do realizacji NAT. Tablica ta nie widzi wszystkich pakietów wchodzących na serwer, a jedynie pierwszy z nich, który zainicjalizował połączenie. W tablicy “mangle” umieszczamy regułki, które dokonują modyfikacji pakietów, np. zmiana ttl. Pakiety te nie będą NATowane. W tej tablicy serwer widzi pakiety należące do danego połączenia poddawanego modyfikacji. W tablicy “raw” umieszczamy wszystkie reguły zanim trafią gdziekolwiek i zanim przetworzy je mechanizm conntrack i zanim zostaną poddane późniejszej modyfikacji lub zmianie.

3.    Pierwsze podstawowe regułki

Wiemy już w skrócie jak wyglądają tablice iptables i gdzie wykonujemy jakie zmiany zatem czas na pierwsze regułki, które są obowiązkowe dla każdego serwera jeśli nie chcemy odciąć dostępu do serwera także sobie.

iptables -A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

Na początek utrzymujemy już nawiązane połączenie z serwerem (np. naszą sesję SSH), następnie wpuszczamy i akceptujemy wszystko co przychodzi z “localhosta”.

4.    Zezwalamy na ping

Jeżeli chcemy, aby nasz serwer odpowiadał nap ing z sieci, dodajmy poniższe regułki. Jest wiele teorii na temat wpuszczania pakietów ping na serwer ze świata. Nie będziemy dziś rozważać zasadności tego typu pakietów i zagrożeń (np. ping-of-death). Jeśli chcemy, aby nasz serwer odpowiadał wszystkim na pingi, aplikujemy poniższe regułki.

iptables -A OUTPUT -p icmp –icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp –icmp-type echo-reply -j ACCEPT
iptables -A INPUT -p icmp –icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp –icmp-type echo-reply -j ACCEPT

5.   Wpuszczamy dostęp do usług na serwerze

Jeżeli mamy na serwerze uruchomione usługi takie jak na przykład serwer www, ssh to wpuszczamy je za pomocą poniższych wpisów.

iptables -A INPUT -p tcp -m tcp –dport 80  -m conntrack –ctstate NEW,ESTABLISHED -m comment –comment „HTTP” -j ACCEPT
iptables -A INPUT -p tcp -m tcp –dport 443 -m conntrack –ctstate NEW,ESTABLISHED -m comment –comment „HTTPS” -j ACCEPT
iptables -A INPUT -p tcp -m tcp –dport 22 -m conntrack –ctstate NEW,ESTABLISHED -m comment –comment „SSH” -j ACCEPT

Wpuszczamy tu ruch na portach 80 (HTTP), 443 (HTTPS), 22 (SSH). To takie podstawowe minimum, które z pewnością będziemy chcieli mieć. Jeśli nasze usługi nasłuchują na innych portach lub mamy także inne to po prostu zmieńmy –dport {PORT} na inną wartość.

6.    Limitujemy ilość połączeń, aby nie narażać serwera na proste, potencjalne ataki np. wspomniany ping-of-death.

Dodajemy nową regułę:

iptables -N IN_LIMIT

Dodajemy limitowanie:

iptables -A IN_LIMIT -p icmp –icmp-type echo-request -m hashlimit –hashlimit 1/s –hashlimit-burst 10 –hashlimit-htable-expire 300000 –hashlimit-mode srcip –hashlimit-name t_PING_OF_DEATH -j RETURN
iptables -A IN_LIMIT -p tcp –tcp-flags RST RST -m limit –limit 50/s –limit-burst 100 -j ACCEPT
iptables -A IN_LIMIT -p tcp –dport 22 -m conntrack –ctstate NEW -m recent –set
iptables -A IN_LIMIT -p tcp –dport 22 -m conntrack –ctstate NEW -m recent –update –seconds 60 –hitcount 10 -j DROP

Blokujemy ataki:

iptables -A IN_LIMIT -j DROP
iptables -A INPUT -p icmp –icmp-type echo-request -j IN_LIMIT

7.    Blokujemy błędne pofragmentowane pakiety

Takie pakiety tylko zapychają tablice i bufor serwera. Nie są potrzebne, nie powinny być wpuszczane zatem na serwer.

iptables -A INPUT -f -j DROP
iptables -A INPUT -m conntrack –ctstate INVALID -j DROP

Blokujemy tu wszystkie pakiety, które są pofragmentowane, błędne i nie powinny biegać po serwerze.

8.    Blokujemy niepotrzebne i pofragmentowane pakiety w tablicy FORWARD

iptables -A FORWARD -m conntrack –ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i lo -j ACCEPT
iptables -A FORWARD -m conntrack –ctstate INVALID -j DROP
iptables -A FORWARD -j REJECT –reject-with icmp-host-prohibited

9.    Podkręcamy bezpieczeństwo zapory

Filtrowanie pakietów w tablicy “filter” to nie wszystko. Istnieje szereg zagrożeń jakie czyhają na serwery. Aby zapewnić większy poziom bezpieczeństwa dołożymy kilka regułek blokujących błędne pakiety, zanim jeszcze trafią one do tablicy filter.

Błędne pakiety – tablica mangle

iptables -t mangle -A PREROUTING -m conntrack –ctstate INVALID -j DROP
iptables -t mangle -A PREROUTING -p tcp ! –syn -m conntrack –ctstate NEW -j DROP
iptables -t mangle -A PREROUTING -p tcp -m conntrack –ctstate NEW -m tcpmss ! –mss 536:65535 -j DROP

Blokowanie potencjalnych floodów i ataków na nagłówki:

iptables -t mangle -A PREROUTING -p tcp –tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ACK,FIN FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ALL ALL -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ALL NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ALL FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ALL SYN,FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp –tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP

Blokujemy spoofing pakietów:

iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP
iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP
iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP

Dzięki temu pozbywamy się ryzyka wystąpienia potencjalnie szkodliwych pakietów. Umieszczenie tych regułek w tablicy “mangle” zapobiega ich dalszej trasie do serwera.

Na koniec blokujemy błędne pakiety.

iptables -t mangle -A PREROUTING -f -j DROP

10.    Wpisy końcowe

Na koniec zablokujemy całkowicie ruch na wszystko co jeszcze nie zostało zbadane, przefiltrowane.

iptables -P INPUT DROP
iptables -P FORWARD DROP

Możemy dodatkowo ograniczyć ruch w łańcuchu OUTPUT, ale wymaga to dodatkowo odpowiedniej konfiguracji wszystkiego, co ma prawo i może wychodzić z serwera, stąd z reguły większość osób pozostawia domyślną regułę ACCEPT, gdyż bardzo łatwo odciąć sobie samemu dostęp do serwera lub odciąć dostęp poszczególnym usługom.

Dodatkowym rozszerzeniem będzie zablokowanie całkowicie ruchu ipv6, jeśli nie korzystamy z tej wersji protokołu IP.

ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT DROP

11.    Zapisywanie ustawień i automatyczne przywracanie po restarcie

Nasz firewall działa, ale po restarcie serwera zostanie przywrócona konfiguracja domyślna, bez naszych wpisów. Aby tak się nie stało, konieczne będzie zapisanie na stałe regułek iptables, tak aby po ponownym uruchomieniu serwera były automatycznie ładowane.

Instalacja pakietu iptables-persistent.

Debian:

apt install iptables-persistent

CentOS

yum install iptables-persistent

Podczas instalacji tego pakietu, instalator zapyta nas czy chcemy zapisać aktualną konfigurację.

Instalator 1

Wybieramy tak, zarówno dla ipv4 jak i ipv6.

Instalator 2

Dzięki temu po ponownym uruchomieniu serwera, nasze regułki zostaną załadowane do pamięci.

Aby ręcznie zapisać reguły (np po dokonaniu w późniejszym czasie jakiś zmian) skorzystajmy z polecenia:

Debian:

iptables-save >/etc/iptables/rules.v4
ip6tables-save >/etc/iptables/rules.v6

CentOS:

iptables-save >/etc/sysconfig/iptables.v4
ip6tables-save >/etc/sysconfig/iptables.v6

12.     Słowo na koniec

Tak przygotowane wpisy do firewall’a iptables z pewnością zapobiegną większości potencjalnych i automatycznych ataków, a także zabezpieczą nas przed większością robotów skanujących każdego dnia serwery i adresy IP w poszukiwaniu potencjalnych luk w bezpieczeństwie. To oczywiście nie wszystko, co można zrobić z iptables. Bardziej zaawansowane filrewalle mają po kilkaset linijek i są bardziej skomplikowane. Powyższe jednak powinny wyeliminować typowe ataki oraz zabezpieczyć przed typowymi robotami, a takich ataków jest w sieci ok 90%. Te ukierunkowane na konkretne podatności musimy zabezpieczać na wielu płaszczyznach, nie tylko iptables, ale także w aplikacji, konfiguracji serwera, konfiguracji pakietów wspomagających jak fail2ban, rootkit huntery czy skanery antywirusowe.

Nasz firewall:

Firewall