ťařina
Obsah Soubory
Linux firewall

nftables

Aktualizováno 3 min čtení 441 slov

nftables

Nástupce iptables a to, co by ses měl učit, když začínáš dnes. Na moderních distribucích už běží pod kapotou, i když píšeš iptables.

Proč je lepší

Jedna syntaxe pro IPv4 i IPv6. Rodina inet řeší obojí naráz. Konec zapomenutého ip6tables, který je nejčastější díra v jinak slušně zajištěných serverech.

Jeden nástroj místo pěti. iptables, ip6tables, arptables a ebtables jsou v nftables sloučené.

Množiny a slovníky. Místo padesáti pravidel pro padesát portů napíšeš jedno.

Atomické změny. Celá sada se nahraje naráz, nebo vůbec. Nemůže se stát, že po půlce načtení zůstane firewall v nesmyslném stavu.

Čitelná konfigurace. Soubor, který se dá číst a verzovat, ne posloupnost příkazů.

Struktura

Podobná iptables, ale všechno si vytváříš sám — žádné předdefinované tabulky:

  • tabulka patří do rodiny (inet, ip, ip6, arp, bridge)
  • řetězec má typ, hook a prioritu
  • pravidlo je uvnitř řetězce

Rodina inet je ta, kterou chceš. Pokrývá IPv4 i IPv6 zároveň.

Kompletní konfigurace serveru

Soubor /etc/nftables.conf:

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    set povolene_tcp {
        type inet_service
        elements = { 22, 80, 443 }
    }

    set duveryhodne {
        type ipv4_addr
        flags interval
        elements = { 192.168.1.0/24, 10.10.0.0/24 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        # ICMP, ať funguje ping a hlavně PMTU
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # veřejné služby
        tcp dport @povolene_tcp accept

        # správa jen z důvěryhodných sítí
        ip saddr @duveryhodne tcp dport { 8006, 9090 } accept

        # ochrana proti hrubé síle na SSH
        tcp dport 22 ct state new limit rate 10/minute accept

        counter comment "zahozeno"
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
        ct state established,related accept
    }

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

Načtení a ověření:

nft -c -f /etc/nftables.conf     # jen kontrola syntaxe, nic neaplikuje
nft -f /etc/nftables.conf        # aplikace
systemctl enable nftables        # načte se po restartu

Ten přepínač -c používej vždycky. Ušetří ti to jeden zámek za rok.

Co za tím stojí za vysvětlení

policy drop znamená, že co neprojde žádným pravidlem, se zahodí. Bezpečnější než povolovat všechno a zakazovat výjimky, protože na co zapomeneš, to je zakázané, ne otevřené.

iif lo accept musí být první. Bez toho si rozbiješ komunikaci mezi procesy na stroji — a projeví se to nečekaně, třeba tím, že databáze nevidí sama sebe.

ip6 nexthdr icmpv6 accept není volitelné. V IPv6 stojí na ICMPv6 objevování sousedů i zjišťování MTU. Když ho zablokuješ, IPv6 přestane fungovat způsobem, který se hledá strašně těžko: něco jde, něco ne, velké soubory se zaseknou v půlce.

counter na konci ti dá číslo, kolik paketů propadlo až sem. Užitečné při ladění — když je nula, všechno prošlo dřív.

limit rate 10/minute je jednoduchá ochrana proti hrubé síle. Sofistikovanější je fail2ban, ale tohle stojí jeden řádek.

Množiny

Největší praktická výhoda proti iptables. Množinu upravíš za běhu bez načítání celé sady:

nft add element inet filter povolene_tcp { 8080 }
nft delete element inet filter povolene_tcp { 8080 }
nft list set inet filter duveryhodne

Dynamická množina s časovým omezením — sem si může fail2ban odkládat blokované adresy:

set blokovani {
    type ipv4_addr
    flags timeout
    timeout 1h
}

NAT

table inet nat {
    chain prerouting {
        type nat hook prerouting priority -100;
        iif eth0 tcp dport 443 dnat ip to 192.168.1.10:443
    }
    chain postrouting {
        type nat hook postrouting priority 100;
        oif eth0 masquerade
    }
}

Stejně jako u iptables platí, že DNAT sám nestačí — provoz musí ještě projít řetězcem forward, kde ho policy drop zahodí:

chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    ip daddr 192.168.1.10 tcp dport 443 accept
}

Diagnostika

nft list ruleset                 # kompletní stav včetně toho, co tam dal někdo jiný
nft list ruleset -a              # s handles pro mazání
nft list table inet filter
nft monitor trace                # živé sledování, kudy paket prochází

Ten nft list ruleset je nejcennější příkaz na téhle stránce. Ukáže ti všechno, včetně pravidel, která přidal Docker nebo Proxmox a o kterých ti ufw neřekne.

Pro sledování konkrétního paketu:

nft add rule inet filter input tcp dport 8080 meta nftrace set 1
nft monitor trace

Převod ze starých pravidel

iptables-save > stara.rules
iptables-restore-translate -f stara.rules > nova.nft

Výsledek projdi ručně. Překlad je mechanický a nevyužije množiny ani rodinu inet, takže dostaneš funkční, ale ošklivou konfiguraci. Ber ji jako výchozí bod k přepsání.

Docker

Docker si i na nftables systémech zapisuje pravidla přes iptables-nft a tvoje table inet filter obchází. Viz Docker a firewall — bez toho ti nftables konfigurace vytvoří falešný pocit bezpečí.