Sätt upp en brandvägg i Debian 11 med nftables

Introduktion

Att ha en fungerande brandvägg på servern är ett viktigt steg i säkerhetsarbetet. I den här guiden kommer vi att skapa en grundläggande brandvägg som du sedan kan bygga vidare på med egna regler. Guiden utgår från en nyinstallerad Cloud VPS med Debian 11. Om du vill sätta upp en brandvägg i Ubuntu 22.04 har vi en guide för det här: Sätt upp en brandvägg i Ubuntu 22.04 med UFW

I Debian 11 och framåt har iptables ersatts med nftables. Det finns flera fördelar med nftables, bland annat att det går att skapa regler som gäller för både IPv4 och IPv6. Syntaxen i nftables är också något förenklad. En annan fördel är att det finns en färdig fil där vi kan placera reglerna, och en färdig systemd-fil för att starta och stoppa brandväggen.

Aktivera brandväggen


Alla program som behövs är redan installerade i Debian 11. Däremot behöver vi aktivera och starta brandväggen. Det gör vi med följande två kommandon:

sudo systemctl enable nftables.service
sudo systemctl start nftables.service

Nu kan vi testa att brandväggen fungerar genom att lista reglerna. Som standard filtreras inget, men det finns en grundkonfiguration i Debian för input, forward och output. Vi listar reglerna med kommandot:

sudo nft list ruleset

Svaret bör se ut som nedan:

table inet filter {
        chain input {
                type filter hook input priority filter; policy accept;
        }

        chain forward {
                type filter hook forward priority filter; policy accept;
        }

        chain output {
                type filter hook output priority filter; policy accept;
        }
}

Den grundläggande konfigurationen vi ser ovan kommer från filen /etc/nftables.conf och nu vet vi att nftables fungerar. Skriver vi ut innehållet i den filen kommer det att matcha utdatan från kommandot vi körde nyss. Vi testar detta med cat /etc/nftables.conf. Resultatet bör vara:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority 0;
        }
        chain forward {
                type filter hook forward priority 0;
        }
        chain output {
                type filter hook output priority 0;
        }
}

Skapa regler i brandväggen


Nu är det dags att lägga till regler för brandväggen. De regler vi kommer att skapa här tillåter inkommande trafik till SSH, HTTP och HTTPS. Vi tillåter också ICMP (ping) och traceroute. För att IPv6 ska fungera tillåter vi både ICMP och "next header". För det lokala nätverkskortet lo tillåter vi all trafik. För att trafik som har initierats av oss själva – från servern – ska fungera tillåter vi också inkommande trafik som är relaterad eller redan upprättad.

För utgående trafik från servern tillåter vi också HTTP, HTTPS och ICMP (ping) och traceroute. För att namnuppslag ska fungera tillåter vi DNS-förfrågningar på UDP-port 53. Vi tillåter också NTP-frågor på UDP-port 123 för tidssynkronisering.

Den sista regeln för både inkommande och utgående trafik är en regel som blockerar (drop) all trafik. Reglerna utvärderas i den ordning de ligger, så de regler som tillåter trafik kommer att utvärderas före den sista regeln som blockerar allt.

Samtliga av dessa regler gäller för både IPv4 och IPv6 – med undantag av specialreglerna för ICMPv6 och "next header" som enbart gäller IPv6.

Vi lägger till reglerna i filen /etc/nftables.conf. Öppna filen med nano eller vi och redigera den så att den ser ut som nedan (filen ägs av root så du behöver öppna den med sudo nano /etc/nftables.conf eller sudo vi /etc/nftables.conf).

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority 0;
                # acceptera all trafik på lo-kortet (localhost)
                iif lo accept

                # acceptera inkommande trafik som har initierats av oss
                ct state established,related accept

                # acceptera inkommande anslutningar till SSH, HTTP och HTTPS
                tcp dport { 22, 80, 443 } ct state new counter accept

                # tillåt inkommande traceroute
                udp dport 33434-33524 ct state new counter accept

                # tillåt "next header" och ping över IPv6, annars tappar vi IPv6 anslutningen
                ip6 nexthdr icmpv6 counter accept

                # tillåt inkommande icmp (ping) över IPv4
                ip protocol icmp counter accept

                # blockera (och räkna) all annan inkommande trafik
                counter drop
        }
        chain forward {
                type filter hook forward priority 0;
        }
        chain output {
                type filter hook output priority 0;
                # acceptera all trafik på lo-kortet (localhost)
                iif lo accept

                # acceptera all utgående trafik som redan har initierats
                ct state established,related accept

                # acceptera utgående anslutningar till HTTP och HTTPS
                tcp dport { 80, 443 } ct state new counter accept

                # acceptera förfrågningar till DNS-servrar och NTP-servrar
                udp dport { 53, 123 } ct state new counter accept

                # tillåt traceroute
                udp dport 33434-33524 ct state new counter accept

                # tillåt "next header" och ping över IPv6, annars tappar vi IPv6 anslutningen
                ip6 nexthdr icmpv6 counter accept

                # tillåt icmp (ping) över IPv4
                ip protocol icmp counter accept

                # blockera (och räkna) all annan utgående trafik
                counter drop
        }
}

När vi har lagt till alla reglerna och sparat filen behöver vi ladda om brandväggsreglerna för att de ska få effekt. Det gör vi med systemctl-kommandot:

sudo systemctl reload nftables.service

Nu kontrollerar vi att det fungerar med sudo nft list ruleset. Svaret bör vara:

table inet filter {
        chain input {
                type filter hook input priority filter; policy accept;
                iif "lo" accept
                ct state established,related accept
                tcp dport { 22, 80, 443 } ct state new counter packets 2 bytes 84 accept
                udp dport 33434-33524 ct state new counter packets 0 bytes 0 accept
                ip6 nexthdr ipv6-icmp counter packets 0 bytes 0 accept
                ip protocol icmp counter packets 0 bytes 0 accept
                counter packets 17 bytes 1321 drop
        }

        chain forward {
                type filter hook forward priority filter; policy accept;
        }

        chain output {
                type filter hook output priority filter; policy accept;
                iif "lo" accept
                ct state established,related accept
                tcp dport { 80, 443 } ct state new counter packets 0 bytes 0 accept
                udp dport { 53, 123 } ct state new counter packets 0 bytes 0 accept
                udp dport 33434-33524 ct state new counter packets 0 bytes 0 accept
                ip6 nexthdr ipv6-icmp counter packets 0 bytes 0 accept
                ip protocol icmp counter packets 0 bytes 0 accept
                counter packets 0 bytes 0 drop
        }
}

I en del av raderna från utdatan ser vi counter packets 2 bytes 84. Detta är en räknare som håller reda på antalet paket som har matchat just den regeln och storleken på dem. Om du inte har något behov av att räkna paketen tar du helt enkelt bort nyckelordet counter från reglerna i /etc/nftables.conf. Om du inte vill öppna nftables.conf med en texteditor och göra ändringarna manuellt, kan du göra det automatiskt med följande SED-kommando:

sed -i 's/counter//g' /etc/nftables.conf

Om du gör ändringar i filen /etc/nftables.conf måste du återigen ladda om brandväggsreglerna med sudo systemctl reload nftables.service för att ändringarna ska få effekt.

Att göra tillfälliga ändringar


Ändringar som vi gör i /etc/nftables.conf är permanenta och laddas in automatiskt vid en omstart av servern. Ibland kan vi dock behöva skapa tillfälliga regler, till exempel vid tester eller när vi labbar med nya tjänster. Då kan vi använda oss av kommandot nft add rule. Dessa regler är tillfälliga i den bemärkelsen att de försvinner vid en omstart.

Nya regler som läggs till med nft add rule hamnar dock sist i listan, det vill säga efter regeln som blockerar all trafik. Vi behöver därför kunna lägga till reglerna på specifika positioner i listan. Vi börjar med att lista alla reglerna igen, men denna gången lägger vi till flaggan -a.

sudo nft -a list ruleset

Utdatan innehåller nu numrerade handles som vi kan använda oss av:

table inet filter { # handle 13
        chain input { # handle 1
                type filter hook input priority filter; policy accept;
                iif "lo" accept # handle 7
                ct state established,related accept # handle 8
                tcp dport { 22, 80, 443 } ct state new counter packets 0 bytes 0 accept # handle 9
                udp dport 33434-33524 ct state new counter packets 0 bytes 0 accept # handle 10
                ip6 nexthdr ipv6-icmp counter packets 0 bytes 0 accept # handle 11
                ip protocol icmp counter packets 0 bytes 0 accept # handle 12
                counter packets 0 bytes 0 drop # handle 13
        }

        chain forward { # handle 2
                type filter hook forward priority filter; policy accept;
        }

        chain output { # handle 3
                type filter hook output priority filter; policy accept;
                iif "lo" accept # handle 14
                ct state established,related accept # handle 15
                tcp dport { 80, 443 } ct state new counter packets 0 bytes 0 accept # handle 16
                udp dport { 53, 123 } ct state new counter packets 0 bytes 0 accept # handle 17
                udp dport 33434-33524 ct state new counter packets 0 bytes 0 accept # handle 18
                ip6 nexthdr ipv6-icmp counter packets 0 bytes 0 accept # handle 19
                ip protocol icmp counter packets 0 bytes 0 accept # handle 20
                counter packets 0 bytes 0 drop # handle 21
        }
}

I det här exemplet lägger vi till en ny regel för att tillåta inkommande trafik på TCP-port 8080 (http-alt) för att sedan ta bort den igen. Vi placerar regeln efter traceroute-regeln, det vill säga efter handle 10. Detta gör vi med:

sudo nft add rule inet filter input handle 10 tcp dport 8080 accept

Nu listar vi reglerna igen, men denna gången begränsar vi listan till input-reglerna. Den nya regeln ska ligga efter handle 10:

sudo nft -a list chain inet filter input

Resultatet blir:

table inet filter {
        chain input { # handle 1
                type filter hook input priority filter; policy accept;
                iif "lo" accept # handle 7
                ct state established,related accept # handle 8
                tcp dport { 22, 80, 443 } ct state new counter packets 12 bytes 568 accept # handle 9
                udp dport 33434-33524 ct state new counter packets 0 bytes 0 accept # handle 10
                tcp dport 8080 accept # handle 22
                ip6 nexthdr ipv6-icmp counter packets 15 bytes 1080 accept # handle 11
                ip protocol icmp counter packets 0 bytes 0 accept # handle 12
                counter packets 184 bytes 21043 drop # handle 13
        }
}

För att ta bort regeln igen använder vi dess handle, 22:

sudo nft delete rule inet filter input handle 22

Om du låser dig ute av misstag


Var försiktig när du laddar in nya brandväggsregler så att du inte låser dig ute från SSH-tjänsten (TCP-port 22). Skulle du trots allt råka låsa dig ute kan du logga in via konsolen i GleSYS Cloud. Du hittar den under InfrastrukturServrar. Klicka på Funktioner bredvid namnet på din server och välj Konsol. När du loggat in kan du redigera filen /etc/nftables.conf och rätta till felet.

Bilden nedan: Har du inte satt något lösenord för din användare kan du dock inte logga in som vanligt. Du kan däremot starta om servern till ett underhållsläge för att få åtkomst till den. När servern startas visas under en kort stund en blå GRUB-skärm. Första valet i listan är Debian GNU/Linux. Tryck på e när Debian GNU/Linux är markerat.


Debians GRUB-skärm


Bilden nedan: Rulla sedan ner i filen med piltangenterna. I slutet av raden som börjar med linux /boot/vmlinuz lägger du till init=/bin/bash (efter ordet quiet). När du har gjort det startar du servern genom att trycka på Ctrl+x.


Starta datorn i underhållsläge


När servern är startad måste du först montera filsystemet i skrivläge. Det gör du med kommandot mount -o remount,rw /. Därefter kan du redigera filen /etc/nftables.conf och rätta till felet som låser dig ute från SSH.

När du är klar och har sparat filen startar du om servern genom att klicka på knappen Ctrl-Atl-Del uppe i vänster hörn i konsolfönstret. Nu kommer servern att starta som vanligt.

Hittar du inte det du söker?

Kontakta oss gärna för mer information. Vi hjälper dig att komma fram till den bästa lösningen för dina behov.

Skicka e-post Ring 0200-23 88 00