Routing rapidu è NAT in Linux

Siccomu l'indirizzi IPv4 sguassate, parechji operatori di telecomunicazioni sò affruntati cù a necessità di furnisce i so clienti cù l'accessu à a rete cù a traduzzione di l'indirizzu. In questu articulu vi dicu cumu pudete ottene u rendimentu di Carrier Grade NAT in i servitori di mercerie.

Un pocu di storia

U tema di l'esaurimentu di u spaziu di indirizzu IPv4 ùn hè più novu. À un certu puntu, listi d'attesa apparsu in RIPE, dopu emergenu scambii nantu à quale blocchi d'indirizzi sò stati scambiati è affari sò stati cunclusi per affittu. Pocu à pocu, l'operatori di telecomunicazioni cuminciaru à furnisce servizii d'accessu à Internet utilizendu indirizzu è traduzzione portu. Qualchidunu ùn anu micca riesciutu à ottene abbastanza indirizzi per emette un indirizzu "biancu" à ogni abbonatu, mentri àutri cuminciaru à risparmià soldi ricusendu di cumprà indirizzi in u mercatu secundariu. I pruduttori di l'equipaggiu di rete sustenevanu sta idea, perchè sta funziunalità generalmente richiede moduli di estensione supplementari o licenze. Per esempiu, in a linea di router MX di Juniper (eccettu l'ultimi MX104 è MX204), pudete fà NAPT nantu à una carta di serviziu MS-MIC separata, Cisco ASR1k richiede una licenza CGN, Cisco ASR9k richiede un modulu A9K-ISM-100 separatu. è una licenza A9K-CGN -LIC à ellu. In generale, u piacè custa assai soldi.

IPTables

U compitu di realizà NAT ùn hè micca bisognu di risorse informatiche specializate; pò esse risolta da i processori di u scopu generale, chì sò stallati, per esempiu, in ogni router di casa. À a scala di un operatore di telecomunicazione, stu prublema pò esse risolta cù i servitori di mercurie chì eseguinu FreeBSD (ipfw/pf) o GNU/Linux (iptables). Ùn cunsideremu micca FreeBSD, perchè ... Aghju cessatu d'utilizà stu OS da un bellu pezzu, cusì ci fermamu à GNU/Linux.

Attivà a traduzzione di l'indirizzu ùn hè micca difficiule. Prima avete bisognu di registrà una regula in iptables in a tavola nat:

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

U sistema operatore carricà u modulu nf_conntrack, chì monitorarà tutte e cunnessione attive è eseguisce e cunversione necessarie. Ci sò parechje suttilità quì. Prima, postu chì parlemu di NAT in a scala di un operatore di telecomunicazione, hè necessariu aghjustà i timeouts, perchè cù i valori predeterminati, a dimensione di a tavola di traduzzione cresce rapidamente à i valori catastròfichi. Quì sottu hè un esempiu di i paràmetri chì aghju utilizatu nantu à i mo servitori:

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

E siconda, postu chì a dimensione predeterminata di a tavola di traduzzione ùn hè micca pensata per travaglià in e cundizioni di un operatore di telecomunicazione, deve esse aumentata:

net.netfilter.nf_conntrack_max = 3145728

Hè ancu necessariu d'aumentà u nùmeru di buckets per a tavola hash chì almacenà tutte e broadcasts (questa hè una opzione in u modulu nf_conntrack):

options nf_conntrack hashsize=1572864

Dopu à sti manipulazioni simplici, un disignu cumplettamente funziunamentu hè ottenutu chì pò traduce un gran numaru di indirizzi di i clienti in una piscina di quelli esterni. Tuttavia, u funziunamentu di sta suluzione abbanduneghja assai per esse desideratu. In i mo primi tentativi di utilizà GNU/Linux per NAT (circa 2013), aghju pussutu ottene prestazioni di circa 7Gbit/s à 0.8Mpps per servitore (Xeon E5-1650v2). Da quellu tempu, assai ottimisazioni diffirenti sò stati fatti in a pila di rete di u kernel GNU / Linux, u rendiment di un servitore nantu à u stessu hardware hè aumentatu à quasi 18-19 Gbit / s à 1.8-1.9 Mpps (questi eranu u massimu. valori), ma a dumanda di u voluminu di trafficu, trattatu da un servitore hà crisciutu assai più veloce. In u risultatu, i schemi sò stati sviluppati per equilibrà a carica in diversi servitori, ma tuttu questu hà aumentatu a cumplessità di stallà, mantene è mantene a qualità di i servizii furniti.

NTFables

Oghje, una tendenza di moda in u software "sacchetti shifting" hè l'usu di DPDK è XDP. Molti articuli sò stati scritti nantu à questu tema, parechji discorsi diffirenti sò stati fatti, è i prudutti cummirciali si prisentanu (per esempiu, SKAT da VasExperts). Ma datu i risorsi limitati di prugrammazione di l'operatori di telecomunicazioni, hè abbastanza problematicu per creà qualsiasi "pruduttu" basatu annantu à sti frameworks per sè stessu. Serà assai più difficiuli di uperà una tale suluzione in u futuru; in particulare, i strumenti di diagnostichi anu da esse sviluppati. Per esempiu, tcpdump standard cù DPDK ùn funziona micca cusì, è ùn "vede" micca i pacchetti mandati à i fili cù XDP. À mezu à tutte e discussioni nantu à e novi tecnulugii per l'invio di pacchetti in u spaziu di l'utilizatori, sò passati inosservati rapporti и articuli Pablo Neira Ayuso, manutentore iptables, circa u sviluppu di u flussu offloading in nftables. Fighjemu stu mecanismu in più detail.

L'idea principale hè chì, se u router hà passatu i pacchetti da una sessione in i dui sensi di u flussu (a sessione TCP hè andata in u statu ESTABLISHED), ùn ci hè bisognu di passà i pacchetti successivi di sta sessione per tutte e regule di firewall, perchè tutti sti cuntrolli finiscinu sempre cù u pacchettu esse trasferitu in più à u routing. È ùn avemu micca veramente bisognu di selezziunà una strada - sapemu digià à quale interfaccia è à quale host avemu bisognu di mandà pacchetti in questa sessione. Tuttu ciò chì resta hè di almacenà sta informazione è l'utilizanu per u routing in una prima tappa di u prucessu di pacchetti. Quandu eseguisce NAT, hè necessariu di almacenà in più infurmazioni nantu à i cambiamenti in l'indirizzi è i porti tradotti da u modulu nf_conntrack. Iè, sicuru, in questu casu, diversi pulizzeri è altre informazioni è regule statistiche in iptables cessanu di travaglià, ma in u quadru di u compitu di un NAT standing separatu o, per esempiu, una fruntiera, questu ùn hè micca cusì impurtante, perchè i servizii. sò distribuiti in i dispositi.

Cunfigurazione

Per utilizà sta funzione, avemu bisognu:

  • Aduprate un kernel frescu. Malgradu u fattu chì a funziunalità stessu apparsu in u kernel 4.16, per un bellu pezzu era assai "cru" è regularmente hà causatu u panicu di u kernel. Tuttu s'hè stabilizatu intornu à dicembre 2019, quandu i kernels LTS 4.19.90 è 5.4.5 sò stati liberati.
  • Riscrivite e regule iptables in u formatu nftables usendu una versione abbastanza recente di nftables. Funziona esattamente in a versione 0.9.0

Se tuttu in principiu hè chjaru cù u primu puntu, a cosa principal ùn hè micca di scurdà di include u modulu in a cunfigurazione durante l'assemblea (CONFIG_NFT_FLOW_OFFLOAD = m), allura u sicondu puntu deve esse spiegazione. I reguli di nftables sò descritti in modu completamente diversu cà in iptables. Documentazione palesa quasi tutti i punti, ci sò dinù spiciali cunvertitori regule da iptables à nftables. Dunque, daraghju solu un esempiu di creazione di NAT è flussu offload. Una piccula legenda per esempiu: , - Quessi sò l'interfacce di rete attraversu quale u trafficu passa; in realtà, pò esse più di dui. , - l'indirizzu iniziale è finale di a gamma di indirizzi "bianchi".

A cunfigurazione NAT hè assai simplice:

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

Cù u flussu offload hè un pocu più complicatu, ma abbastanza comprensibile:

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

Chì, in fatti, hè tutta a stallazione. Avà tuttu u trafficu TCP / UDP cascarà in a tavola fastnat è esse processatu assai più veloce.

Risultati

Per fà chjaru quantu "quantu più veloce" questu hè, aghjustà una screenshot di a carica nantu à dui servitori veri, cù u stessu hardware (Xeon E5-1650v2), cunfiguratu in modu identicu, utilizendu u stessu kernel Linux, ma eseguendu NAT in iptables. (NAT4) è in nftables (NAT5).

Routing rapidu è NAT in Linux

Ùn ci hè micca un graficu di pacchetti per seconda in a screenshot, ma in u prufilu di carica di questi servitori a dimensione media di u pacchettu hè di circa 800 byte, cusì i valori righjunghjenu finu à 1.5Mpps. Comu pudete vede, u servitore cù nftables hà una riserva di rendiment enormi. Attualmente, stu servitore processa finu à 30Gbit / s à 3Mpps è hè chjaramente capace di scuntrà a limitazione fisica di a rete di 40Gbps, mentre avè risorse di CPU gratuiti.

Spergu chì stu materiale serà utile à l'ingegneri di rete chì provanu à migliurà a prestazione di i so servitori.

Source: www.habr.com

Add a comment