Snabb routing och NAT-ingÄng Linux

NÀr IPv4-adresser blir uttömda stÄr mÄnga telekomoperatörer inför behovet av att ge sina kunder nÀtverksÄtkomst med hjÀlp av adressöversÀttning. I den hÀr artikeln kommer jag att berÀtta hur du kan fÄ Carrier Grade NAT-prestanda pÄ rÄvaruservrar.

Lite historia

Ämnet om utmattning av IPv4-adressutrymme Ă€r inte lĂ€ngre nytt. Vid nĂ„got tillfĂ€lle dök vĂ€ntelistor upp i RIPE, sedan uppstod börser dĂ€r adressblock handlades och affĂ€rer slöts för att hyra dem. SĂ„ smĂ„ningom började telekomoperatörer tillhandahĂ„lla InternetaccesstjĂ€nster med hjĂ€lp av adress- och portöversĂ€ttning. Vissa lyckades inte fĂ„ tillrĂ€ckligt mĂ„nga adresser för att utfĂ€rda en "vit" adress till varje abonnent, medan andra började spara pengar genom att vĂ€gra köpa adresser pĂ„ andrahandsmarknaden. Tillverkare av nĂ€tverksutrustning stödde denna idĂ©, eftersom denna funktion krĂ€ver vanligtvis ytterligare tillĂ€ggsmoduler eller licenser. Till exempel, i Junipers linje av MX-routrar (förutom de senaste MX104 och MX204), kan du utföra NAPT pĂ„ ett separat MS-MIC-servicekort, Cisco ASR1k krĂ€ver en CGN-licens, Cisco ASR9k krĂ€ver en separat A9K-ISM-100-modul och en A9K-CGN-licens -LIC till honom. Generellt sett kostar nöjet mycket pengar.

IPTables

NAT-implementering krÀver inga specialiserade datorresurser; den kan hanteras av generella processorer, som de som finns i vilken hemmarouter som helst. PÄ telekomoperatörsnivÄ kan denna uppgift utföras med hjÀlp av standardservrar som kör FreeBSD (ipfw/pf) eller GNU/Linux (iptables). Vi kommer inte att titta pÄ FreeBSD, eftersom jag slutade anvÀnda det operativsystemet för ett tag sedan, sÄ lÄt oss hÄlla oss till GNU/Linux.

Att aktivera adressöversÀttning Àr inte alls svÄrt. Först mÄste du registrera en regel i iptables i nat-tabellen:

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

Operativsystemet kommer att ladda modulen nf_conntrack, som kommer att övervaka alla aktiva anslutningar och utföra nödvÀndiga omvandlingar. Det finns flera subtiliteter hÀr. För det första, eftersom vi talar om NAT pÄ skalan av en telekomoperatör, Àr det nödvÀndigt att justera timeouts, för med standardvÀrden kommer storleken pÄ översÀttningstabellen snabbt att vÀxa till katastrofala vÀrden. Nedan Àr ett exempel pÄ instÀllningarna jag anvÀnde pÄ mina servrar:

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

Och för det andra, eftersom standardstorleken pÄ översÀttningstabellen inte Àr utformad för att fungera under en teleoperatörs villkor, mÄste den ökas:

net.netfilter.nf_conntrack_max = 3145728

Det Àr ocksÄ nödvÀndigt att öka antalet hinkar för hashtabellen som lagrar alla sÀndningar (detta Àr ett alternativ i modulen nf_conntrack):

options nf_conntrack hashsize=1572864

Efter dessa enkla manipulationer erhĂ„lls en fullt fungerande design som kan sĂ€nda ett stort antal klientadresser till en pool av externa adresser. Prestandan för denna lösning lĂ€mnar dock mycket övrigt att önska. I mina första försök att anvĂ€nda GNU/Linux För NAT (cirka 2013) kunde jag fĂ„ prestanda pĂ„ runt 7 Gbit/s vid 0.8 Mpps pĂ„ en enda server (Xeon E5-1650v2). Sedan dess har GNU-kĂ€rnans nĂ€tverksstack/Linux MĂ„nga optimeringar gjordes, och prestandan för en enda server pĂ„ samma hĂ„rdvara ökade till nĂ€stan 18–19 Gbit/s vid 1.8–1.9 Mpps (dessa var maxvĂ€rdena), men efterfrĂ„gan pĂ„ trafik som hanterades av en enda server vĂ€xte mycket snabbare. I slutĂ€ndan utvecklades lastbalanseringsscheman för olika servrar, men allt detta ökade komplexiteten i installation, underhĂ„ll och upprĂ€tthĂ„llande av kvaliteten pĂ„ de tillhandahĂ„llna tjĂ€nsterna.

NFT-tabeller

Nuförtiden Àr en fashionabel trend inom mjukvaruvÀskor att anvÀnda DPDK och XDP. Det har skrivits mÄnga artiklar om detta Àmne, mÄnga olika tal har hÄllits och kommersiella produkter dyker upp (till exempel SKAT frÄn VasExperts). Men med tanke pÄ de begrÀnsade programmeringsresurserna hos telekomoperatörer Àr det ganska problematiskt att skapa nÄgon "produkt" baserad pÄ dessa ramverk pÄ egen hand. Det kommer att bli mycket svÄrare att anvÀnda en sÄdan lösning i framtiden, sÀrskilt diagnostiska verktyg mÄste utvecklas. Till exempel kommer standard tcpdump med DPDK inte att fungera bara sÄ, och det kommer inte att "se" paket som skickas tillbaka till ledningarna med XDP. Mitt i allt prat om ny teknik för att skicka paketvidarebefordran till anvÀndarutrymmet gick de obemÀrkt förbi rapporterar О Artikel Pablo Neira Ayuso, underhÄllare av iptables, om utvecklingen av flödesavlastning i nftables. LÄt oss ta en nÀrmare titt pÄ denna mekanism.

Huvudtanken Àr att om routern skickade paket frÄn en session i bÄda riktningarna av flödet (TCP-sessionen gick in i ETABLISHED-tillstÄndet), sÄ finns det inget behov av att skicka efterföljande paket av denna session genom alla brandvÀggsregler, eftersom alla dessa kontroller kommer fortfarande att sluta med att paketet överförs vidare till routing. Och vi behöver faktiskt inte vÀlja en rutt - vi vet redan till vilket grÀnssnitt och till vilken vÀrd vi behöver skicka paket inom denna session. Allt som ÄterstÄr Àr att lagra denna information och anvÀnda den för routing i ett tidigt skede av paketbearbetningen. NÀr du utför NAT Àr det nödvÀndigt att dessutom lagra information om Àndringar i adresser och portar som översatts av modulen nf_conntrack. Ja, naturligtvis, i det hÀr fallet slutar olika poliser och annan information och statistiska regler i iptables att fungera, men inom ramen för uppgiften med en separat stÄende NAT eller till exempel en grÀns Àr detta inte sÄ viktigt, eftersom tjÀnsterna Àr fördelade över enheter.

konfiguration

För att anvÀnda denna funktion behöver vi:

  • AnvĂ€nd en fĂ€rsk kĂ€rna. Trots att sjĂ€lva funktionaliteten dök upp i kĂ€rnan 4.16, var den under ganska lĂ„ng tid vĂ€ldigt "rĂ„" och orsakade regelbundet kĂ€rnpanik. Allt stabiliserades runt december 2019, nĂ€r LTS-kĂ€rnorna 4.19.90 och 5.4.5 slĂ€pptes.
  • Skriv om iptables-regler i nftables-format med en ganska ny version av nftables. Fungerar exakt i version 0.9.0

Om allt i princip Ă€r klart med den första punkten, Ă€r det viktigaste att inte glömma att inkludera modulen i konfigurationen under monteringen (CONFIG_NFT_FLOW_OFFLOAD=m), dĂ„ krĂ€ver den andra punkten förklaring. nftables regler beskrivs helt annorlunda Ă€n i iptables. Đ”ĐŸĐșŃƒĐŒĐ”ĐœŃ‚Đ°Ń†ĐžŃ avslöjar nĂ€stan alla punkter, det finns ocksĂ„ speciella omvandlare regler frĂ„n iptables till nftables. DĂ€rför kommer jag bara att ge ett exempel pĂ„ hur man stĂ€ller in NAT och flow offload. En liten legend till exempel: , - Det hĂ€r Ă€r nĂ€tverksgrĂ€nssnitten genom vilka trafik passerar; i verkligheten kan det finnas fler Ă€n tvĂ„ av dem. , — start- och slutadressen för intervallet av "vita" adresser.

NAT-konfigurationen Àr mycket enkel:

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

Med flödesavlastning Àr det lite mer komplicerat, men ganska förstÄeligt:

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

Det Àr faktiskt hela upplÀgget. Nu kommer all TCP/UDP-trafik att falla in i fastnat-tabellen och bearbetas mycket snabbare.

Resultat

För att tydliggöra hur mycket snabbare detta Àr, bifogar jag en skÀrmdump av belastningen pÄ tvÄ riktiga servrar, med samma hÄrdvara (Xeon E5-1650v2), konfigurerade identiskt, med samma kÀrna. Linux, men utför NAT i iptables (NAT4) och i nftables (NAT5).

Snabb routing och NAT-ingÄng Linux

Det finns ingen graf över paket per sekund i skÀrmdumpen, men i laddningsprofilen för dessa servrar Àr den genomsnittliga paketstorleken runt 800 byte, sÄ vÀrdena nÄr upp till 1.5Mpps. Som du kan se har servern med nftables en enorm prestandareserv. För nÀrvarande bearbetar den hÀr servern upp till 30Gbit/s vid 3Mpps och klarar tydligt den fysiska nÀtverksbegrÀnsningen pÄ 40Gbps, samtidigt som den har lediga CPU-resurser.

Jag hoppas att detta material kommer att vara anvÀndbart för nÀtverksingenjörer som försöker förbÀttra prestanda pÄ sina servrar.

KĂ€lla: will.com

Köp pĂ„litlig hosting för webbplatser med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster