S rostoucím nedostatkem IPv4 adres se mnoho poskytovatelů internetu setkalo s nutností organizovat přístup svých klientů do sítě prostřednictvím překladů adres. V tomto článku si povíme, jak lze dosáhnout výkonu na úrovni Carrier Grade NAT na komoditních serverech.
Trocha historie
Téma vyčerpání adresního prostoru IPv4 již není nové. V určitém okamžiku se v RIPE objevily čekací seznamy, poté vznikly burzy, na kterých se obchodovalo s bloky adres a uzavíraly se dohody o jejich pronájmu. Postupně začali poskytovatelé služeb internetu poskytovat služby připojení k internetu pomocí překladů adres a portů. Někteří nestihli získat dostatečný počet adres, aby mohli poskytnout „bílou“ adresu každému uživateli, zatímco jiní začali šetřit a odmítli nákup adres na sekundárním trhu. Výrobci síťového vybavení podpořili tuto myšlenku, protože tato funkce obvykle vyžaduje další rozšiřující moduly nebo licence. Například u Juniperu v řadě směrovačů MX (kromě posledních MX104 a MX204) lze provádět NAPT na samostatné servisní kartě MS-MIC, na Cisco ASR1k je potřeba licence CGN license, a na Cisco ASR9k samostatný modul A9K-ISM-100 a licence A9K-CGN-LIC k němu. Celkově to není levná záležitost.
IPTables
Úloha provádění NAT nevyžaduje specializované výpočetní zdroje, je schopna ji vyřešit procesor pro obecné použití, který je nainstalován například v jakémkoliv domácím směrovači. V měřítku poskytovatele služeb lze tuto úlohu vyřešit pomocí komoditních serverů s operačním systémem FreeBSD (ipfw/pf) nebo GNU/Linux (iptables). FreeBSD zvažovat nebudeme, protože jsem už dávno přestal tuto operační soustavu používat, a tak se zaměříme na GNU/Linux.
Zapnutí překladů adres není nijak složité. Nejprve je třeba vytvořit pravidlo v iptables v tabulce nat:
iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to - --persistent
Operační systém načte modul nf_conntrack, který bude sledovat všechna aktivní spojení a provádět potřebné transformace. Existuje zde několik jemností. Za prvé, protože se jedná o NAT na úrovni telekomunikačního operátora, je nutné upravit timeouty, protože s hodnotami ve výchozím stavu se velikost tabulky překladů velmi rychle zvýší na katastrofální hodnoty. Níže je příklad nastavení, která jsem použil na svých serverech:
net.ipv4.ip_forward = 1
net.ipv4.ip_local_port_range = 8192 65535
net.netfilter.nf_conntrack_generic_timeout = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 600
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 45
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_checksum=0
A za druhé, protože velikost tabulky překladů ve výchozím nastavení není určena pro práci v podmínkách telekomunikačního operátora, je nutné ji zvýšit:
net.netfilter.nf_conntrack_max = 3145728
Je také nutné zvýšit počet buckets pro hashovací tabulku, která ukládá všechny překlady (to je volba modulu nf_conntrack):
options nf_conntrack hashsize=1572864
Po těchto jednoduchých manipulacích vzniká plně funkční konstrukce, která může překládat velké množství klientských adres do zásobníku externích adres. Nicméně, výkonnost tohoto řešení zůstává nedostatečná. V mých prvních pokusech využití GNU/Linux pro NAT (kolem roku 2013) jsem dokázal dosáhnout výkonnosti přibližně 7Gbit/s při 0.8Mpps na jeden server (Xeon E5-1650v2). Od té doby bylo v síťovém zásobníku jádra GNU/Linux provedeno mnoho různých optimalizací, výkonnost jednoho serveru na stejném hardwaru vzrostla téměř na 18-19 Gbit/s při 1.8-1.9 Mpps (to byly krajní hodnoty), ale potřeba objemu provozu zpracovávaného jedním serverem rostla mnohem rychleji. V důsledku toho byly vypracovány schémata vyvažování zátěže na různé servery, ale to vše zvýšilo složitost konfigurace, údržby a udržení kvality poskytovaných služeb.
NFTables
Aktuálním trendy v oblasti programového „přebalování paketů“ je používání DPDK a XDP. O této tématice bylo napsáno spousta článků, uskutečněno mnoho různých prezentací a objevují se komerční produkty (například SKAT od VasExperts). Nicméně, v podmínkách omezených zdrojů programátorů u telekomunikačních operátorů je poměrně problematické vyvinout nějaký „výrobek“ na základě těchto frameworků. Další využívání takového řešení bude mnohem složitější, především bude nutné vyvinout diagnostické nástroje. Například standardní tcpdump s DPDK prostě nefunguje, a pakety, které byly odeslány zpět do drátů pomocí XDP, nebudou „viditelné“. Na pozadí všech diskuzí o nových technologiích směrování paketů do user-space zůstaly bez povšimnutí a Pablo Neira Ayuso, udržovatel iptables, o vývoji flow offloading v nftables. Podívejme se na tento mechanismus podrobněji.
Hlavní myšlenka spočívá v tom, že pokud router propustil pakety jedné relace oběma směry toku (TCP relace přešla do stavu ESTABLISHED), není třeba propouštět další pakety této relace přes všechna pravidla firewallu, protože všechny tyto kontroly stejně skončí předáním paketu do směrování. A vlastně není potřeba vybírat trasu — už víme, na které rozhraní a kterému hostiteli je třeba pakety v rámci této relace předat. Zbývá pouze uchovat tyto informace a použít je pro směrování v rané fázi zpracování paketu. Při provádění NAT je navíc nutné uchovávat informace o změnách adres a portů, které byly transformovány modulem nf_conntrack. Ano, samozřejmě, v tomto případě přestávají fungovat různé policery a další informačně-statistická pravidla v iptables, ale v rámci úkolu samostatného stojícího NAT nebo například borderu — to není tak důležité, protože služby jsou distribuovány mezi zařízeními.
Konfigurace
Abyste mohli využít tuto funkci, potřebujeme:
- Použít novou verzi jádra. I když se sama funkčnost objevila již v jádře 4.16, byla poměrně dlouho velmi „syrová“ a pravidelně vyvolávala kernel panic. Vše se stabilizovalo přibližně v prosinci 2019, kdy vyšly LTS verze jádra 4.19.90 a 5.4.5.
- Převeďte pravidla iptables do formátu nftables pomocí dostatečně nové verze nftables. Funkční v verzi 0.9.0
Pokud je první bod v zásadě jasný, hlavně nezapomeňte zahrnout modul do konfigurace při sestavení (CONFIG_NFT_FLOW_OFFLOAD=m), druhý bod vyžaduje vysvětlení. Pravidla nftables se popisují zcela jinak než v iptables. odhaluje prakticky všechny aspekty, také existují speciální pravidel z iptables do nftables. Proto uvedu pouze příklad nastavení NAT a flow offload. Malá legenda pro příklad: <i_if>, <o_if> — to jsou síťové rozhraní, přes která prochází provoz, ve skutečnosti jich může být více než dvě. <pool_addr_start>,<pool_addr_end> — počáteční a koncová adresa rozsahu „bílých“ adres.
Konfigurace NAT je velmi jednoduchá:
#! /usr/sbin/nft -f
table nat {
chain postrouting {
type nat hook postrouting priority 100;
oif <o_if> snat to <pool_addr_start>-<pool_addr_end> persistent
}
}
S flow offload je to o něco složitější, ale docela srozumitelné:
#! /usr/sbin/nft -f
table inet filter {
flowtable fastnat {
hook ingress priority 0
devices = { <i_if>, <o_if> }
}
chain forward {
type filter hook forward priority 0; policy accept;
ip protocol { tcp , udp } flow offload @fastnat;
}
}
A to je vlastně celé nastavení. Nyní veškerý TCP/UDP provoz bude směřován do tabulky fastnat a zpracováván mnohem rychleji.
Výsledky
Aby bylo jasné, jak moc je to „mnohem rychleji“, připojím snímek zátěže na dvou skutečných serverech, se stejnou konfigurací (Xeon E5-1650v2), stejným nastavením, používajících jádro Linux, ale provádějících NAT v iptables (NAT4) a v nftables (NAT5).

Na snímku není graf paketů za sekundu, ale v profilu zatížení těchto serverů má průměrná velikost paketu kolem 800 bajtů, takže hodnoty dosahují až 1.5Mpps. Jak je vidět, server s nftables má obrovský výkonový potenciál. V současné době tento server zpracovává až 30Gbit/s při 3Mpps a je zjevně schopen narazit na fyzické omezení sítě 40Gbps, přičemž má stále volné CPU prostředky.
Doufám, že tento materiál bude užitečný síťovým inženýrům, kteří se snaží zlepšit výkon svých serverů.
Zdroj: habr.com
