Zapora sieciowa z ufw i nftables
Moduł 5: Zabezpieczanie sieci · Czas czytania: 12 min
Cel lekcji: Po tej lekcji potrafią Państwo skonfigurować zaporę sieciową, która przepuszcza tylko to, co niezbędne, dla IPv4 i IPv6, nie odcinając sobie przy tym dostępu, oraz wiedzą Państwo, przed czym zapora na serwerze nie chroni.
Kluczowe pojęcia: filtr pakietów, netfilter, nftables, iptables-nft, ufw, polityka domyślna, allow, deny, reject, limit, IPv6 w ufw, zapora dostawcy, firewalld, Docker a zapora
Co robi zapora sieciowa
Zapora sieciowa (firewall) na serwerze to filtr pakietów: dla każdego przychodzącego pakietu sieciowego sprawdza listę reguł i decyduje, czy może on przejść. W Linux filtr ten znajduje się w jądrze i nazywa się netfilter. Konfiguruje się go za pomocą programu:
- nftables (polecenie
nft) to obecne narzędzie. Debian używa go domyślnie od wersji Debian 10. - iptables to starsze narzędzie. W nowoczesnych systemach
iptablesjest zazwyczaj warstwą tłumaczącą na nftables (iptables-nft), dzięki czemu stare poradniki nadal działają. - ufw (Uncomplicated Firewall) to prosta warstwa nad nimi, domyślnie dostępna w Ubuntu i instalowana jednym poleceniem w Debianie. Dla pojedynczego serwera ufw jest najprostszym wyborem. Ta lekcja korzysta z ufw, a następnie pokazuje, jak te same reguły wyglądają w nftables.
Zapora jest Państwa drugą warstwą obrony. Pierwszą jest to, że usługi nasłuchują wyłącznie na właściwym adresie (lekcja 5.1). Razem sprawiają, że pomyłka w jednej warstwie nie oznacza od razu otwartych drzwi.
Najpierw: jak wrócić, gdy coś pójdzie nie tak?
Klasyczny błąd: włączają Państwo zaporę, zapominają przepuścić SSH i połączenie zostaje zerwane. Wtedy nie ma już dostępu przez SSH. Zanim Państwo zaczną:
- Proszę sprawdzić, jak otworzyć konsolę u dostawcy (lekcja 1.2). Działa ona z pominięciem sieci, a więc także wtedy, gdy zapora wszystko blokuje. Tam logują się Państwo i wpisują
ufw disable. - W razie wątpliwości proszę wykonać snapshot.
- Proszę pozostawić bieżącą sesję SSH otwartą i testować w drugiej sesji.
ufw w pięciu krokach
Krok 1: instalacja i wybór ustawień domyślnych.
anna@web1:~$ sudo apt install ufw
anna@web1:~$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
anna@web1:~$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'Polityka domyślna obowiązuje dla wszystkiego, dla czego nie ma reguły. "Deny incoming" oznacza: wszystko, co przychodzi, jest zabronione, z wyjątkiem tego, na co Państwo za chwilę zezwolą. To jedyna bezpieczna podstawa. Ruch wychodzący (serwer pobierający aktualizacje) jest dozwolony.
Krok 2: zezwolenie na SSH, zanim zapora zostanie włączona.
anna@web1:~$ sudo ufw allow OpenSSH
Rules updated
Rules updated (v6)OpenSSH to profil aplikacji znany ufw (oznacza port 22/tcp). Jeśli SSH działa na innym porcie, proszę użyć numeru: sudo ufw allow 2222/tcp. Proszę zwrócić uwagę na "Rules updated (v6)": ufw tworzy regułę również dla IPv6. Robi to, ponieważ w /etc/default/ufw znajduje się wpis IPV6=yes, co jest ustawieniem domyślnym. Warto to sprawdzić: jeśli jest tam no, zapora działa tylko dla IPv4.
Krok 3: wszystko, czego Państwo jeszcze potrzebują.
anna@web1:~$ sudo ufw allow 80/tcp
anna@web1:~$ sudo ufw allow 443/tcp
anna@web1:~$ sudo ufw allow 443/udp # tylko jeśli używają Państwo HTTP/3Regułę można ograniczyć do jednego adresu źródłowego, na przykład dla portu administracyjnego, który ma być dostępny tylko z Państwa biura:
anna@web1:~$ sudo ufw allow from 198.51.100.20 to any port 9090 proto tcpKrok 4: włączenie.
anna@web1:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startupKrok 5: sprawdzenie. Proszę otworzyć drugie okno i zalogować się ponownie. Jeśli się uda, SSH jest poprawnie skonfigurowane. Następnie proszę przejrzeć reguły:
anna@web1:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)Reguły usuwa się według numerów: sudo ufw status numbered, a następnie sudo ufw delete 3.
deny, reject i limit
- deny po cichu odrzuca pakiet: z zewnątrz port widać jako "filtrowany" (lekcja 5.1).
- reject odsyła odmowę: z zewnątrz port widać jako "zamknięty". To bardziej eleganckie dla Państwa własnych usług, ale zdradza, że serwer istnieje.
- limit przepuszcza połączenie, ale blokuje adres, który w ciągu 30 sekund próbuje połączyć się sześć lub więcej razy. Przydatne dla SSH:
sudo ufw limit OpenSSHzamiastallow. To mechanizm zgrubny (liczy połączenia, a nie nieudane logowania); fail2ban (lekcja 5.3) jest dokładniejszy.
Te same reguły w nftables
ufw w tle zapisuje reguły netfilter. Jeśli chcą Państwo pracować bez ufw, piszą Państwo własny plik nftables. W Debianie znajduje się on w /etc/nftables.conf i jest wczytywany przez usługę nftables:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
meta l4proto { icmp, ipv6-icmp } accept
tcp dport { 22, 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}Należy go czytać następująco. Tabela nazywa się filter i należy do rodziny inet: jedna tabela jednocześnie dla IPv4 i IPv6, dzięki czemu nie można zapomnieć o IPv6. W łańcuchu input polityka to drop. Dalej: odpowiedzi na już istniejące połączenia mogą wracać (established,related), wszystko na loopback jest dozwolone, ICMP jest dozwolone (potrzebne m.in. dla IPv6 i komunikatów o błędach dotyczących rozmiaru pakietów), a porty 22, 80 i 443 są otwarte.
anna@web1:~$ sudo nft -c -f /etc/nftables.conf # sprawdź bez wczytywania
anna@web1:~$ sudo systemctl enable --now nftables
anna@web1:~$ sudo nft list rulesetProszę używać albo ufw, albo własnego pliku nftables, nie obu jednocześnie: oba zapisują do tego samego netfilter i mogą sobie wzajemnie przeszkadzać.
Przed czym zapora nie chroni
- Usługi, które Państwo sami przepuszczają. Port 443 jest otwarty dla Państwa strony internetowej, więc luka w stronie jest po prostu osiągalna. Zapora chroni tylko porty, które są zamknięte.
- Docker. Gdy publikują Państwo port za pomocą Dockera (
-p 5432:5432), Docker ustawia własne reguły netfilter, które przekierowują ruch, zanim zadziałają reguły ufw. Dokumentacja Dockera wprost stwierdza, że Docker i ufw nie współpracują dobrze. Port kontenera może więc być otwarty z zewnątrz, mimo żeufw statusgo nie pokazuje. Rozwiązanie (publikowanie na127.0.0.1) poznają Państwo w lekcji 9.3. - Ruch wychodzący. Przy "allow outgoing" zhakowany program może łączyć się wszędzie. Dla większości małych serwerów jest to akceptowalny wybór; w środowiskach o wysokich wymaganiach ogranicza się także ruch wychodzący.
Zapora dostawcy
Wielu dostawców oferuje również zaporę w sieci, przed Państwa serwerem, konfigurowaną w panelu klienta (nazywaną czasem "cloud firewall" lub "security group"). To doskonała dodatkowa warstwa, która działa również wtedy, gdy na samym serwerze coś zostanie źle ustawione. Nie zastępuje ona jednak zapory na serwerze: przy przeniesieniu serwera lub zmianie dostawcy nie przechodzi razem z nim, a nie każdy dostawca ją oferuje. Dlatego zawsze warto utrzymywać zaporę na samym serwerze.
W AlmaLinux i Rocky Linux
Tam domyślnie włączony jest firewalld, korzystający ze stref. Najważniejsze polecenia:
[root@web1 ~]# firewall-cmd --list-all
[root@web1 ~]# firewall-cmd --permanent --add-service=http --add-service=https
[root@web1 ~]# firewall-cmd --reloadBez --permanent zmiana obowiązuje tylko do następnego restartu; z --permanent dopiero po --reload. SSH jest w strefie domyślnej już otwarte.
W praktyce
Jeśli mimo wszystko odetną sobie Państwo dostęp do VPS w WebOké, proszę otworzyć konsolę na ekranie VPS, zalogować się i wyłączyć zaporę (ufw disable) lub cofnąć ostatnią regułę. U innych dostawców to awaryjne wejście również nazywa się konsolą, VNC lub rescue. Warto wiedzieć, gdzie jest ten przycisk, zanim będzie potrzebny.
Podsumowanie
- Zapora to druga warstwa po zasadzie "nasłuchuj tylko tam, gdzie trzeba"; nftables to narzędzie w jądrze, a ufw prosta warstwa nad nim.
- Proszę zacząć od
default deny incoming, zezwolić na SSH przedufw enable, testować w drugiej sesji i znać konsolę swojego dostawcy. - Proszę sprawdzić, czy ufw obejmuje również IPv6 (
IPV6=yes); w nftables rodzinainetzałatwia to za jednym razem. denydaje z zewnątrz stan "filtrowany",rejectdaje "zamknięty";limitspowalnia powtarzane połączenia.- Porty Dockera omijają ufw (lekcja 9.3); zapora dostawcy jest dodatkową warstwą, a nie zamiennikiem.
Quiz
Zadanie
Zadanie O5.2: Konfiguracja zapory. Proszę włączyć na serwerze zaporę za pomocą ufw (lub nftables, albo firewalld w AlmaLinux/Rocky): domyślnie wszystko przychodzące zamknięte, SSH oraz to, czego Państwo naprawdę potrzebują. Proszę przetestować w drugiej sesji, sprawdzić, czy IPv6 jest objęte, i z zewnątrz za pomocą nc sprawdzić, czy niedozwolony port jest zamknięty lub filtrowany. Proszę wypełnić listę kontrolną i wkleić wynik ufw status verbose (lub nft list ruleset); przy każdym otwartym porcie proszę podać, do czego służy.
Zadanie O5.2: Konfiguracja zapory
To zadanie wykonuje się samodzielnie, nikt go nie sprawdza. Prosimy zaznaczyć wykonane punkty i oznaczyć zadanie jako wykonane.
Dla serwera WWW tylko 22 (lub Państwa port SSH), 80 i 443, dla IPv4 i IPv6. Porty administracyjne tylko z
Zaznaczenia i notatki pozostają tylko w tej przeglądarce; nie są nigdzie wysyłane. Po zalogowaniu w Moje kursy zapisywana jest jedynie informacja, że zadanie zostało wykonane.
Przeczytaj więcej
- Zabezpieczanie VPS: pierwsze pięć minut
- Brak dostępu do VPS: co teraz?
- Debian Wiki, nftables: https://wiki.debian.org/nftables
- Dokumentacja Ubuntu Server, Firewall (ufw): https://ubuntu.com/server/docs/how-to/security/firewalls/
- Dokumentacja Dockera, Packet filtering and firewalls: https://docs.docker.com/engine/network/packet-filtering-firewalls/
