V minulém článku z našeho seriálu jsme si vysvětlili, jak fungují tabulky a řetězce v nich. Poté jsme si ukázali, jak do řetězce vložit pravidlo a jak to nakonec celé zálohovat do souboru. Dnes se podíváme podrobně na správu pravidel v našich řetězcích.
Co se dozvíte v článku
Přidání nového pravidla
Pokud už máme vytvořenou alespoň jednu tabulku a v ní alespoň jeden řetězec, můžeme do něj přidat vlastní pravidlo. Použijeme opět naši oblíbenou univerzální utilitu nft
, které musíme kromě samotného pravidla sdělit, do jaké tabulky a řetězce jej chceme přidat.
# nft add rule inet filter output ip daddr 8.8.8.8 accept
V tomto příkladu jsme použili příkaz add
, který přidá nové pravidlo na konec řetězce. Pokud chceme přidat pravidlo na začátek, použijeme místo toho příkaz insert
. Poté uvedeme název tabulky (v našem případě filter
) a řetězce ( output
) a následuje samotný zápis pravidla.
Můžeme se podívat, jak v tuhle chvíli vypadá aktuální konfigurace:
# nft list table inet filter table inet filter { chain output { type filter hook output priority 0; policy accept; ip daddr 8.8.8.8 accept } }
Přidání na určenou pozici
Tímto způsobem můžeme přidat či odebrat pravidlo na začátek nebo na konec. Máme ale také samozřejmě možnost přidat pravidlo mezi už existující položky. Ty jsou interně očíslovány a čísla pravidel si můžeme vypsat pomocí parametru -a
. Pro názornost jsem do řetězce přidal několik dalších podobných pravidel.
# nft list table inet filter -a table inet filter { # handle 1 chain output { # handle 1 type filter hook output priority 0; policy accept; ip daddr 8.8.8.8 accept # handle 2 ip daddr 8.8.4.4 accept # handle 3 ip daddr 1.1.1.1 accept # handle 4 } }
Vidíte, že do výpisu přibyly komentáře. Ty obsahují popisky s čísly jednotlivých položek. Pokud bychom nyní chtěli vložit další pravidlo doprostřed výpisu, stačí nám vybrat pozici sousedního už existujícího pravidla. Opět můžeme nové pravidlo přidat za něj ( add
) nebo před něj ( insert
).
# nft add rule inet filter output position 3 ip daddr 1.0.0.1 accept # nft list table inet filter -a table inet filter { # handle 1 chain output { # handle 1 type filter hook output priority 0; policy accept; ip daddr 8.8.8.8 accept # handle 2 ip daddr 8.8.4.4 accept # handle 3 ip daddr 1.0.0.1 accept # handle 5 ip daddr 1.1.1.1 accept # handle 4 } }
Za pozici číslo 3 jsme přidali další pravidlo. Všimněte si, že dostalo další číslo v sekvenci, tedy číslo 5. Zařadilo se na správnou pozici.
Velmi podobně můžeme pomocí parametru replace
zvolit, že chceme pravidlo s konkrétním číslem nahradit. Například takto:
# nft replace rule inet filter output handle 3 ip daddr 8.8.4.4 reject
Odstranění pravidla
Pomocí čísla můžeme také pravidlo jednoduše odstranit. Řekněme, že se nám nelíbí hned to první, tedy s číslem 2. Odstranění je dílem jednoduchého příkazu.
# nft delete rule inet filter output handle 2 # nft list table inet filter -a table inet filter { # handle 1 chain output { # handle 1 type filter hook output priority 0; policy accept; ip daddr 8.8.4.4 accept # handle 3 ip daddr 1.0.0.1 accept # handle 5 ip daddr 1.1.1.1 accept # handle 4 } }
Pravidla a jejich parametry
Abychom mohli zapisovat skutečná pravidla, musíme znát jejich názvy. Každé pravidlo má také různé parametry, které umožňují přesně popsat, co chceme na daném paketu zkoumat. Níže uvádím přehled nejběžnějších možností používaných s nftables.
meta – meta informace, například o rozhraní oif <index výstupního rozhraní> iif <index vstupního rozhraní> oifname <název výstupního rozhraní> iifname <název vstupního rozhraní> icmp – protokol ICMP type <typ icmp> icmpv6 – protokol ICMP type <typ icmpv6> ip – protokol IPv4 protocol <protokol> daddr <cílová adresa> saddr <zdrojová adresa> ip6 – protokol IPv6 daddr <cílová adresa> saddr <zdrojová adresa> tcp – protokol TCP dport <cílový port> sport <zdrojový port> udp – protokol UDP dport <cílový port> sport <zdrojový port> sctp – protokol SCTP dport <cílový port> sport <zdrojový port> ct – connection tracking, sledování spojení state <new | established | related | invalid>
Počítadla
Firewall nftables umožňuje zapínat u jednotlivých pravidel počítadla. Je potřeba o to ale explicitně požádat. Ve výchozím stavu se žádný provoz automaticky nepočítá. Můžeme ovšem snadno využít toho, že při splnění jednoho výrazu je možné provést více akcí. Můžeme tedy paket například propustit a zároveň ho započítat.
Provedeme to tak, že při přidávání pravidla na jeho konec zapíšeme více akcí za sebou. Například takto:
# nft add rule inet filter output ip daddr 8.8.8.8 counter accept # nft list table inet filter -a table inet filter { # handle 1 chain output { # handle 1 type filter hook output priority 0; policy accept; ip daddr 8.8.8.8 counter packets 0 bytes 0 accept # handle 8 } }
Vidíte, že jsme zapsali nové pravidlo, které má u sebe nově i počítadlo. Můžeme rovnou vyzkoušet jeho funkci:
# ping 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=56 time=27.6 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=56 time=18.9 ms 64 bytes from 8.8.8.8: icmp_seq=3 ttl=56 time=22.1 ms 64 bytes from 8.8.8.8: icmp_seq=4 ttl=56 time=48.6 ms 64 bytes from 8.8.8.8: icmp_seq=5 ttl=56 time=38.5 ms ^C --- 8.8.8.8 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 10ms rtt min/avg/max/mdev = 18.947/31.156/48.601/10.982 ms # nft list table inet filter -a table inet filter { # handle 1 chain output { # handle 1 type filter hook output priority 0; policy accept; ip daddr 8.8.8.8 counter packets 5 bytes 420 accept # handle 8 } }
Komentáře
Velmi užitečné je mít přímo ve firewallu komentáře. Umožňují nám lépe se orientovat v našich pravidlech, případně v pravidlech dalších kolegů, kteří s námi síť spravují. Tyto komentáře jsou pevnou součástí pravidel a při výpisu je vždy uvidíme. Uvádějí se na konci definice nového pravidla.
# nft add rule inet filter output ip daddr 8.8.8.8 counter accept comment \"DNS resolver Google\"
Všimněte si, že jsem musel uvozovky escapovat, aby je shell neodstranil. Pokud to neuděláte, utilita nft
dostane jednotlivá slova v komentáři jako samostatné parametry a nebude jim rozumět. Teď už zbývá jen vypsat si současný stav, ve kterém komentář uvidíme:
# nft list table inet filter -a table inet filter { # handle 1 chain output { # handle 1 type filter hook output priority 0; policy accept; ip daddr 8.8.8.8 counter packets 0 bytes 0 accept comment "DNS resolver Google" # handle 10 } }
Příště budeme akční
Dnes jsme si ukázali, jak můžeme vytvářet pravidla pro filtrování jednotlivých paketů. V dalším článku si ukážeme, jaké akce je možné s pakety provádět. Můžeme je zaznamenávat, nastavovat u nich metainformace, upravovat hlavičky nebo třeba využívat NAT.