markdown
nftables.md
markdown
# nftables Nástupce [iptables](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 -fflush 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í: ```bashnft -c -f /etc/nftables.conf # jen kontrola syntaxe, nic neaplikujenft -f /etc/nftables.conf # aplikacesystemctl 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](Jak-funguje-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](Fail2ban-a-CrowdSec), 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: ```bashnft 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 ```bashnft 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 filternft 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](ufw) neřekne. Pro sledování konkrétního paketu: ```bashnft add rule inet filter input tcp dport 8080 meta nftrace set 1nft monitor trace``` ## Převod ze starých pravidel ```bashiptables-save > stara.rulesiptables-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](Docker-a-firewall) — bez toho ti nftables konfigurace vytvoří falešný pocit bezpečí.