Gyors útválasztás és NAT Linuxban

Ahogy az IPv4-címek kimerülnek, sok távközlési szolgáltató szembesül azzal, hogy ügyfelei számára hálózati hozzáférést kell biztosítania címfordítással. Ebben a cikkben elmondom, hogyan érheti el a Carrier Grade NAT teljesítményt az árukiszolgálókon.

Egy kis történelem

Az IPv4 címtér kimerülésének témája már nem új keletű. Valamikor várólisták jelentek meg a RIPE-ben, majd olyan tőzsdék alakultak ki, amelyeken címblokkokkal kereskedtek, és bérleti szerződéseket kötöttek. A távközlési szolgáltatók fokozatosan cím- és portfordítással kezdtek internet-hozzáférési szolgáltatásokat nyújtani. Egyeseknek nem sikerült elég címet szerezniük ahhoz, hogy minden előfizetőnek „fehér” címet adjanak ki, mások pedig azzal kezdtek spórolni, hogy megtagadták a címek másodpiaci vásárlását. A hálózati berendezések gyártói támogatták ezt az ötletet, mert ehhez a funkcióhoz általában további bővítőmodulokra vagy licencekre van szükség. Például a Juniper MX útválasztóiban (kivéve a legújabb MX104 és MX204) a NAPT-t külön MS-MIC szervizkártyán végezheti el, a Cisco ASR1k-hez CGN licenc szükséges, a Cisco ASR9k-hez külön A9K-ISM-100 modul szükséges. és egy A9K-CGN licenc -LIC neki. Általában az élvezet sok pénzbe kerül.

IPTables

A NAT végrehajtása nem igényel speciális számítási erőforrásokat, általános célú processzorokkal megoldható, amelyek például bármely otthoni útválasztóba telepíthetők. Egy távközlési szolgáltató méretében ez a probléma megoldható a FreeBSD-t (ipfw/pf) vagy a GNU/Linuxot (iptables) futtató áruszerverekkel. Nem vesszük figyelembe a FreeBSD-t, mert... Elég régen abbahagytam ennek az operációs rendszernek a használatát, így maradunk a GNU/Linuxnál.

A címfordítás engedélyezése egyáltalán nem nehéz. Először regisztrálnia kell egy szabályt az iptables-ban a nat táblában:

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to <pool_start_addr>-<pool_end_addr> --persistent

Az operációs rendszer betölti az nf_conntrack modult, amely figyeli az összes aktív kapcsolatot és elvégzi a szükséges átalakításokat. Számos finomság van itt. Először is, mivel a NAT-ról egy távközlési szolgáltató léptékében beszélünk, módosítani kell az időtúllépéseket, mivel az alapértelmezett értékekkel a fordítási tábla mérete gyorsan katasztrofális értékekre nő. Az alábbiakban egy példa a szervereimen használt beállításokra:

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

Másodszor, mivel a fordítótábla alapértelmezett méretét nem úgy tervezték, hogy egy távközlési szolgáltató körülményei között működjön, növelni kell:

net.netfilter.nf_conntrack_max = 3145728

Ezenkívül növelni kell az összes adást tároló hash táblához tartozó gyűjtők számát (ez az nf_conntrack modul egyik opciója):

options nf_conntrack hashsize=1572864

Ezen egyszerű manipulációk után egy teljesen működőképes kialakítást kapunk, amely nagyszámú ügyfélcímet képes külső címek készletévé fordítani. Ennek a megoldásnak a teljesítménye azonban sok kívánnivalót hagy maga után. Az első kísérleteim során a GNU/Linux használatára NAT-hoz (2013 körül) körülbelül 7 Gbit/s-os teljesítményt tudtam elérni szerverenként 0.8 Mpps mellett (Xeon E5-1650v2). Azóta sokféle optimalizálás történt a GNU/Linux kernel hálózati veremében, egy szerver teljesítménye ugyanazon a hardveren közel 18-19 Gbit/s-ra nőtt 1.8-1.9 Mpps mellett (ezek voltak a maximumok értékek), de az egy szerver által feldolgozott forgalom iránti igény sokkal gyorsabban nőtt. Ennek eredményeként olyan sémákat dolgoztak ki, amelyek kiegyenlítették a különböző szerverek terhelését, de mindez megnövelte a nyújtott szolgáltatások beállításának, karbantartásának és minőségének fenntartásának bonyolultságát.

NFTable

Manapság divatos trend a szoftveres „váltótáskákban” a DPDK és XDP használata. Nagyon sok cikk született ebben a témában, sokféle felszólalás hangzott el, és megjelennek a kereskedelmi termékek (például a VasExperts SKAT-ja). De tekintettel a távközlési szolgáltatók korlátozott programozási erőforrásaira, meglehetősen problémás ezeken a keretrendszereken alapuló „termékek” önálló létrehozása. Egy ilyen megoldás működtetése a jövőben sokkal nehezebb lesz, különösen diagnosztikai eszközöket kell fejleszteni. Például a szabványos tcpdump DPDK-val nem fog csak úgy működni, és nem „látja” az XDP-n keresztül a vezetékekre visszaküldött csomagokat. A csomagtovábbítás felhasználói térbe történő továbbításának új technológiáiról folytatott szóbeszéd közepette észrevétlen maradt jelentéseket и Cikk Pablo Neira Ayuso, az iptables karbantartója az nftables folyam-kitöltésének fejlesztéséről. Nézzük meg ezt a mechanizmust részletesebben.

A fő gondolat az, hogy ha a router egy munkamenetből csomagokat adott át a folyam mindkét irányában (a TCP munkamenet ESTABLISHED állapotba került), akkor nincs szükség a munkamenet további csomagjait az összes tűzfalszabályon átengedni, mert ezek az ellenőrzések továbbra is a csomag továbbításával az útválasztáshoz érnek véget. És valójában nem kell útvonalat választanunk – már tudjuk, hogy melyik interfészhez és melyik gazdagéphez kell csomagokat küldenünk ezen a munkameneten belül. Már csak el kell tárolni ezeket az információkat és felhasználni az útválasztáshoz a csomagfeldolgozás korai szakaszában. A NAT végrehajtásakor további információkat kell tárolni az nf_conntrack modul által lefordított címek és portok változásairól. Igen, persze ilyenkor leállnak a különböző rendőrök és egyéb információs, statisztikai szabályok az iptables-ban, de egy külön álló NAT vagy például egy határ feladatának keretein belül ez nem annyira fontos, mert a szolgáltatások eszközök között vannak elosztva.

Configuration

A funkció használatához szükségünk van:

  • Használjon friss kernelt. Annak ellenére, hogy maga a funkcionalitás a 4.16-os kernelben jelent meg, elég hosszú ideig nagyon „nyers” volt, és rendszeresen kernelpánikot okozott. Minden stabilizálódott 2019 decembere körül, amikor megjelent a 4.19.90 és 5.4.5 LTS kernel.
  • Írja át az iptables szabályokat nftables formátumban az nftables meglehetősen friss verziójával. Pontosan működik a 0.9.0 verzióban

Ha az első ponttal elvileg minden világos, akkor a lényeg, hogy összeszereléskor ne felejtsük el a modult a konfigurációban szerepeltetni (CONFIG_NFT_FLOW_OFFLOAD=m), akkor a második pont magyarázatot igényel. Az nftables szabályok teljesen másképpen vannak leírva, mint az iptables-ban. dokumentáció szinte minden pontot feltár, vannak speciálisak is átalakítók szabályok az iptables-tól az nftable-ig. Ezért csak egy példát mondok a NAT és a flow offload beállítására. Egy kis legenda például: , - ezek azok a hálózati interfészek, amelyeken a forgalom áthalad, a valóságban kettőnél több is lehet. , — a „fehér” címtartomány kezdő és záró címe.

A NAT beállítása nagyon egyszerű:

#! /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
        }
}

Az áramlási tehermentesítéssel ez egy kicsit bonyolultabb, de teljesen érthető:

#! /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;
        }
}

Valójában ez az egész beállítás. Mostantól az összes TCP/UDP forgalom a fastnat táblába kerül, és sokkal gyorsabban kerül feldolgozásra.

Álláspontja

Hogy egyértelmű legyen, mennyire "sokkal gyorsabb" ez, csatolok egy képernyőképet két valódi szerver terheléséről, ugyanazzal a hardverrel (Xeon E5-1650v2), azonos konfigurációval, ugyanazt a Linux kernelt használva, de NAT-ot hajtanak végre az iptables-ban. (NAT4) és nfttables-ban (NAT5).

Gyors útválasztás és NAT Linuxban

A képernyőképen nincs másodpercenkénti csomagok grafikonja, de ezeknek a szervereknek a terhelési profiljában az átlagos csomagméret 800 bájt körül mozog, így az értékek elérik az 1.5 Mpps-t is. Mint látható, az nftables szervernek hatalmas teljesítménytartaléka van. Jelenleg ez a szerver 30 Gbit/s-ig dolgoz fel 3 Mpp/s sebességgel, és egyértelműen képes teljesíteni a 40 Gbps-os fizikai hálózati korlátot, miközben szabad CPU-erőforrásokkal rendelkezik.

Remélem, hogy ez az anyag hasznos lesz a hálózati mérnökök számára, akik megpróbálják javítani szervereik teljesítményét.

Forrás: will.com

Hozzászólás