nftables

Tato kapitola výrazně navazuje na předešlou kapitolu o iptables a pro pochopení některých souvislostí je nutné znát i iptables.

nftables je podsystém jádra Linux, sloužící pro filtrování síťové komunikace. Nahrazuje nástroj iptables a zároveň mění vnitřní fungování Netflitru. Oproti iptables přináší také podporu pro IPv6 a ARP filtrování. Pro manipulaci s nftables používáme utilitu nft

nftables vs. iptables

Nástroje iptables a nftables jsou podobné, ale najdeme mezi nimi podstatné rozdíly, mezi ty hlavní patří tyto:

  • nftables již neobsahují žádné výchozí tabulky ani řetězce, ty si při konfiguraci nastavujeme sami za pomocí tzv. hooks

  • pravidla v nftables mohou vykonávat několik akcí, narozdíl od iptables, kde jedno pravidlo = jedna akce

  • nftables pravidla jsou dynamická, což zlepšuje jejich správu a výkon.

Ruleset

Tímto pojmem označujeme celou konfiguraci nftables, tedy všechny tabulky, řetězce apod. Pro jeho vypsání můžeme použít příkaz:

nft list ruleset

Naopak pro smazání celé konfigurace můžeme použít příkaz:

nft flush ruleset

Address families

Definují jaký protokol budeme v tabulce využívat. Mezi ty základní patří tyto:

Název Využití
ip Pouze IPv4 adresy
ip6 Pouze IPv6 adresy
inet Internet neboli jak IPv4, tak IPv6 adresy
arp ARP protokol pro IPv4 adresy

Tabulky

Tabulky stejně jako v iptables sdružují řetězce, ale narozdíl od iptables nejsou v nftables žádné předdefinované a tedy si všechny tvoříme sami. Při tvoření definujeme address family, neboli s jakým protokolem bude tabulka pracovat a její název.

Pro základní manipulaci s tabulkami používáme příkazy:

add - pro vytvoření tabulky

delete - pro smazání tabulky

list - pro vypsání všech řetězců a pravidel v dané tabulce, pokud místo table použijeme tables, vypíší se všechny tabulky v rulesetu

flush - pro smazání všech řetězců a pravidel v dané tabulce

Syntaxe je následující:

nft [příkaz] table [address family] [název tabulky]

Například pro vytvoření tabulky pro IPv4 a IPv6 adresy s názvem nase_tabulka využijeme příkaz

nft add table inet nase_tabulka

A pro její smazání příkaz

nft delete table inet nase_tabulka

Řetězce

Opět stejně jako v iptables řetězce sdružují pravidla a jsou umístěné v tabulkách a opět nejsou žádné v nftables předdefinované, takže si všechny tvoříme sami. V nftables najdeme dva druhy řetězců a to základní (base) a standardní (regular). Rozdíl je, že základní řetězce přijímají pakety automaticky dle nastaveného hook a typu, zatímco běžné řetězce slouží jenom jako cíle.

Pro základní manipulaci s řetězci používáme příkazy:

add - pro vytvoření řetězce

delete - pro smazání řetězce

rename - pro přejmenování řetězce

list - pro vypsání všech pravidel daného řetězce

flush - pro vymazání všech pravidel daného řetězce

Tvorba základních řetězců

Pro tvorbu základních řetězců používáme následující syntaxi

nft [příkaz] chain [address family] [název tabulky] [název řetězce] '{type [typ řetězce] hook [hook] priority [priorita]; }'

typ řetězce nám určuje jaké akce bude řetězec provádět, jejich seznam se nachází v tabulce níže, hook nám určuje v jaké fázi zpracování chceme aby řetězec paket zachytil a nakonec priorita určuje v jakém pořadí se bude řetězec zpracovávat, čím nižší číslo, tím dříve se bude řetězec zpracovávat.

Typy řetězců

Název Využití
filter Nejpoužívanější typ, určen pro filtrování
nat Typ pro aplikaci Network address translation - pouze ip, ip6 a inet address families a prerouting, input, output, postrouting hooks
route Typ pro routování - pouze ip a ip6 address families a output hook

ip/ip6/inet hooks

Název Využití
input Příchozí pakety
output Odchozí pakety
forward Procházející pakety
prerouting Pakety před zpracováním routovací tabulkou
postrouting Pakety po zpracování routovací tabulkou

arp hooks

Název Využití
input Příchozí pakety
output Odchozí pakety

Například pro tvorbu řetězce nas_retezec který bude filtrovat všechny příchozí pakety v tabulce nase_tabulka s prioritou 0, využijeme následující příkaz:

nft add chain inet nase_tabulka nas_retezec '{type filter hook input priority 0; }'

Tvorba standardních řetězců

Pro manipulaci se standardními řetězci používame stejnou syntaxi, jako pro základní řetězce, jen vynecháme typ, hook a prioritu neboli syntaxe vypadá takto:

nft [příkaz] chain [address family] [název tabulky] [název řetězce]

Pravidla

Pravidla jsou obsažena v řetězcích a skládají se typicky z expression a verdiktu. Expression určuje shodu (např. při shodě IP adresy, při shodě portu…). Verdikt určuje akci, která se při shodě provede (např. zahodit paket, propustit paket…).

Pro základní manipulaci s pravidly používáme příkazy:

add - pro vytvoření pravidla na konci řetězce

delete - pro smazání pravidla

insert - pro vytvoření pravidla na začátku řetězce

replace - pro nahrazení zvoleného pravidla

A používáme následující syntaxi

nft [příkaz] rule [address family] [název tabulky] [název řetězce] [expresion] [verdikt]

Expression

Zde je základní výběr shod a argumentů, pomocí kterých budeme tvořit naše první pravidla.

ip: daddr: Cílová IP adresa saddr: Zdrojová IP adresa

ipv6: daddr: Cílová IPv6 adresa saddr: Zdrojová IPv6 adresa

tcp: dport: Cílový TCP port sport: Zdrojový TCP port

udp: dport: Cílový UDP port sport: Zdrojový UDP port

ct: state: Stav připojení <new | established | related | invalid>

icmp: type: Typ ICMP požadavku

icmpv6: type: Typ ICMPv6 požadavku

Verdikty

accept - Přijme paket

drop - Zahodí paket

counter - Započítá paket do čítače

jump - Skočí na jiný řetězec

Seznamy

Seznamy nám umožňují seskupit několik prvků, např. TCP porty. V nftables nalezneme dva typy, a to nepojmenované a pojmenované. Nepojmenovaný seznam je integrovaný v pravidlu a nelze ho měnit. V příkazu níže ho nalezneme označený tučně.

nft add rule inet nase_tabulka nas_retezec tcp dport **{http, https}** accept

Pojmenovaný seznam vytváříme v tabulce samostatně a můžeme ho upravovat. Pro manipulaci s pojmenovanými seznamy používáme příkazy:

add - pro vytvoření pojmenovaného seznamu

delete - pro smazání pojmenovaného seznamu

list - pro vypsání pojmenovaného seznamu

flush - pro smazání všech prvků z pojmenovaného seznamu

Příklad tvorby jednoduchého rulesetu

Nyní si můžeme ukázat tvorbu jednoduchého rulesetu za pomocí příkazů, které jsem si v této kapitole ukázali.

Vytvoříme si ruleset s jednou tabulkou pro IPv4 i IPv6 adresy, tato tabulka bude obsahovat 2 řetězce, a to pro filtrování příchozí a odchozí komunikace. Následně vytvoříme pravidlo pro započtení každého paketu s destinací na IP 1.1.1.1 a naposled nastavit politiku zahodit všechny příchozí pakety. Doporučuji se zadání nejdříve vypracovat samostatně a až poté se podívat na řešení.

Na začátek je vhodné, pokud již nemáme něco cíleně nakonfigurovaného, vymazat si celý ruleset. To provedeme následujícím příkazem:

nft flush ruleset

Nyní si vytvoříme tabulku, kam vše umístíme, je vhodné si jí pojmenovat podle účelu nebo podle jejího obsahu, abychom se v rulesetu později vyznali. V našem případě to bude inet_table. K tomu použijeme tento příkaz:

nft add table inet inet_table

Následně v tabulce vytvoříme dva základní řetězce, jeden pro filtrování příchozí komunikace a jeden pro filtrování odchozí komunikace. To učiníme následujícími příkazy:

nft add chain inet inet_table output_chain '{type filter hook output priority 0; }'
nft add chain inet inet_table input_chain '{type filter hook input priority 0; }'

Následně si vytvoříme pravidlo pro počítaní paketů s destinací na IP 1.1.1.1. Na to využijeme tento příkaz:

nft add rule inet inet_table output_chain ip daddr 1.1.1.1 counter

A nakonec přenastavíme politiku input_chain aby veškeré pakety zahazoval. Na to pooužijeme tento příkaz:

nft chain inet inet_table input_chain '{ policy drop ; }'

Nyní si můžeme ruleset vypsat

nft list ruleset

Pokud jsme vše udělali správně, měl by výstup vypadat takto:

table inet inet_table {
    chain output_chain {
        type filter hook output priority filter; policy accept;
            ip daddr 1.1.1.1 counter packets 0 bytes 0    
    }

    chain input_chain {
        type filter hook input priority filter; policy accept;
    }
}

Aplikace NAT

V této části si pouze rozebereme konfiguraci NAT v nftables, teorii NAT jsme již rozebírali v kapitole o iptables.

Konfigurace SNAT

Pro konfiguraci SNAT využijeme tabulku ip/ip6/inet, dle nastavení naší sítě a řetězec napojený na hook postrouting. V tomto řetězci vytvoříme samotné pravidlo, které zachytí správné pakety a přepíše jejich zdrojovou IP adresu.

Konfigurace může například vypadat následovně:

nft add table ip nat_table
nft add chain ip nat_table snat_chain '{ type nat hook postrouting priority 100; }'
nft add rule ip nat_table snat_chain ip saddr 192.168.1.0/24 oif eth0 snat 146.6.177.31

Pro konfiguraci maškarády využijeme tento příkaz:

nft add rule ip nat_table snat_chain masquerade

Konfigurace DNAT

Používáme stejný postup jako při konfiguraci SNAT akorát s rozdílem, že se napojujeme na hook prerouting místo postrouting.

Konfigurace na přesměrování na náš webserver může vypadat například takto:

nft add table ip nat_table
nft add chain ip nat_table dnat_chain '{ type nat hook prerouting priority -100; }'
nft add rule ip nat_table dnat_chain iif eth0 tcp dport { 80, 443 } dnat 192.168.1.10

A pro konfiguraci přesměrování například následující příkaz:

nft add rule ip nat_table dnat_chain tcp dport 80 redirect to 8080

Diagnostika pravidel

V diagnostice pravidel nftables nám především pomohou 2 verdikty a to log a counter. Za pomocí log můžeme provést záznam do systémového logu a za pomocí counter můžeme počítat kolik paketů mělo shodu z daným pravidlem.

Překlad iptables

Pokud již máme pravidla v iptables formátu, můžeme je jednoduše přeložit do nft formátu pomocí utility iptables-translate případně můžeme přeložit i celou iptables konfiguraci pomocí iptables-restore-translate.

Uložení stavu

Jelikož nft ukládá ruleset do paměti, při restartu počítače se ruleset nezachová. Pokud chceme aktuální ruleset zachovat použijeme následující příkaz:

nft list ruleset > /etc/nftables.conf

Systémy používající systemd automaticky tento soubor hledají a načítají z něho.

results matching ""

    No results matching ""