Rapida vojigo kaj NAT en Linukso

Ĉar IPv4-adresoj malpleniĝas, multaj teleentreprenistoj alfrontas la bezonon provizi siajn klientojn per retaliro uzante adrestradukon. En ĉi tiu artikolo mi rakontos al vi kiel vi povas akiri Carrier Grade NAT-agadon sur varaj serviloj.

Iom da historio

La temo pri elĉerpiĝo de adresspaco IPv4 ne plu estas nova. En iu momento, atendlistoj aperis en RIPE, tiam aperis interŝanĝoj, sur kiuj blokoj de adresoj estis komercitaj kaj interkonsentoj estis finitaj por lui ilin. Iom post iom, teleentreprenistoj komencis disponigi retalirservojn uzante adreson kaj haventradukon. Iuj ne sukcesis akiri sufiĉe da adresoj por doni "blankan" adreson al ĉiu abonanto, dum aliaj komencis ŝpari monon rifuzante aĉeti adresojn sur la malĉefa merkato. Fabrikistoj de retaj ekipaĵoj subtenis ĉi tiun ideon, ĉar ĉi tiu funkcio kutime postulas pliajn etendaĵojn aŭ licencojn. Ekzemple, en la linio de MX-enkursigiloj de Juniper (krom la plej novaj MX104 kaj MX204), vi povas plenumi NAPT sur aparta MS-MIC-servokarto, Cisco ASR1k postulas CGN-licencon, Cisco ASR9k postulas apartan A9K-ISM-100-modulon. kaj A9K-CGN-licenco -LIC al li. Ĝenerale, la plezuro kostas multe da mono.

IPTables

La tasko plenumi NAT ne postulas specialajn komputikajn rimedojn; ĝi povas esti solvita per ĝeneraluzeblaj procesoroj, kiuj estas instalitaj, ekzemple, en iu ajn hejma enkursigilo. Sur la skalo de teleentreprenisto, ĉi tiu problemo povas esti solvita per varserviloj kurantaj FreeBSD (ipfw/pf) aŭ GNU/Linukso (iptables). Ni ne konsideros FreeBSD, ĉar... Mi ĉesis uzi ĉi tiun OS antaŭ sufiĉe longa tempo, do ni restos al GNU/Linukso.

Ebligi adrestradukadon tute ne estas malfacila. Unue vi devas registri regulon en iptables en la nat-tabelo:

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

La operaciumo ŝarĝos la modulon nf_conntrack, kiu kontrolos ĉiujn aktivajn konektojn kaj faros la necesajn konvertiĝojn. Estas pluraj subtilecoj ĉi tie. Unue, ĉar ni parolas pri NAT laŭ la skalo de telekomunika operatoro, necesas ĝustigi la tempodaŭrojn, ĉar kun defaŭltaj valoroj la grandeco de la traduktabelo rapide kreskos al katastrofaj valoroj. Malsupre estas ekzemplo de la agordoj, kiujn mi uzis sur miaj serviloj:

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

Kaj due, ĉar la defaŭlta grandeco de la traduktabelo ne estas desegnita por funkcii sub la kondiĉoj de telekomunika operatoro, ĝi devas esti pliigita:

net.netfilter.nf_conntrack_max = 3145728

Necesas ankaŭ pliigi la nombron da siteloj por la hashtabelo stokanta ĉiujn elsendojn (ĉi tio estas opcio en la modulo nf_conntrack):

options nf_conntrack hashsize=1572864

Post ĉi tiuj simplaj manipuladoj, plene funkcianta dezajno estas akirita, kiu povas traduki grandan nombron da klientaj adresoj en grupon de eksteraj. Tamen, la agado de ĉi tiu solvo lasas multon por deziri. En miaj unuaj provoj uzi GNU/Linukson por NAT (ĉirkaŭ 2013), mi povis akiri rendimenton de ĉirkaŭ 7Gbit/s je 0.8Mpps per servilo (Xeon E5-1650v2). Ekde tiu tempo, multaj malsamaj optimumigoj estis faritaj en la GNU/Linukso-kerna reto-stako, la rendimento de unu servilo sur la sama aparataro pliiĝis al preskaŭ 18-19 Gbit/s je 1.8-1.9 Mpps (ĉi tiuj estis la maksimumaj valoroj) , sed la postulo pri trafika volumo, prilaborita de unu servilo kreskis multe pli rapide. Kiel rezulto, kabaloj estis evoluigitaj por ekvilibrigi la ŝarĝon sur malsamaj serviloj, sed ĉio ĉi pliigis la kompleksecon de agordo, konservado kaj konservado de la kvalito de la servoj provizitaj.

NTFables

Nuntempe, moda tendenco en programaro "ŝanĝaj sakoj" estas la uzo de DPDK kaj XDP. Multaj artikoloj estis verkitaj pri ĉi tiu temo, multaj diversaj paroladoj estis faritaj, kaj komercaj produktoj aperas (ekzemple SKAT de VasExperts). Sed konsiderante la limigitajn programajn rimedojn de telekomunikaj telefonistoj, estas sufiĉe probleme krei ajnan "produkton" bazitan sur ĉi tiuj kadroj memstare. Estos multe pli malfacile funkciigi tian solvon en la estonteco; precipe, diagnozaj iloj devos esti evoluigitaj. Ekzemple, norma tcpdump kun DPDK ne funkcios ĝuste tiel, kaj ĝi ne "vidos" pakaĵetojn senditajn reen al la dratoj uzante XDP. Inter ĉiuj paroladoj pri novaj teknologioj por eligi pakaĵeton al uzantspaco, ili pasis nerimarkitaj raportoj и artikoloj Pablo Neira Ayuso, prizorganto de iptables, pri la evoluo de fluo-malŝarĝado en nftables. Ni rigardu pli detale ĉi tiun mekanismon.

La ĉefa ideo estas, ke se la enkursigilo pasis pakaĵetojn de unu sesio en ambaŭ direktoj de la fluo (TCP-sesio eniris la staton ESTABLISHED), tiam ne necesas pasi postajn pakaĵetojn de ĉi tiu sesio tra ĉiuj fajroŝirmigaj reguloj, ĉar ĉiuj ĉi tiuj kontroloj ankoraŭ finiĝos kun la pakaĵeto translokigita plu al la vojigo. Kaj ni fakte ne bezonas elekti itineron - ni jam scias al kiu interfaco kaj al kiu gastiganto ni devas sendi pakaĵojn ene de ĉi tiu sesio. Restas nur stoki ĉi tiun informon kaj uzi ĝin por vojigo en frua etapo de paka pretigo. Farante NAT, necesas aldone konservi informojn pri ŝanĝoj en adresoj kaj pordoj tradukitaj per la modulo nf_conntrack. Jes, kompreneble, ĉi-kaze diversaj policistoj kaj aliaj informaj kaj statistikaj reguloj en iptables ĉesas funkcii, sed kadre de la tasko de aparta staranta NAT aŭ ekzemple limo, tio ne tiom gravas, ĉar la servoj estas distribuitaj tra aparatoj.

Agordo

Por uzi ĉi tiun funkcion ni bezonas:

  • Uzu freŝan kernon. Malgraŭ tio, ke la funkcieco mem aperis en kerno 4.16, dum sufiĉe longa tempo ĝi estis tre "kruda" kaj regule kaŭzis kernan panikon. Ĉio stabiliĝis ĉirkaŭ decembro 2019, kiam LTS-kernoj 4.19.90 kaj 5.4.5 estis liberigitaj.
  • Reskribi regulojn de iptables en formato nftables uzante sufiĉe lastatempan version de nftables. Funkcias ĝuste en versio 0.9.0

Se ĉio principe estas klara kun la unua punkto, la ĉefa afero estas ne forgesi inkluzivi la modulon en la agordo dum kunigo (CONFIG_NFT_FLOW_OFFLOAD=m), tiam la dua punkto postulas klarigon. nftables reguloj estas priskribitaj tute malsame ol en iptables. Dokumentado malkaŝas preskaŭ ĉiujn punktojn, ekzistas ankaŭ specialaj konvertiloj reguloj de iptables ĝis nftables. Tial mi nur donos ekzemplon pri agordo de NAT kaj fluo-malŝarĝo. Eta legendo ekzemple: , - ĉi tiuj estas la retaj interfacoj tra kiuj trafiko pasas; fakte povas esti pli ol du el ili. , — la komenca kaj fina adreso de la gamo de "blankaj" adresoj.

NAT-agordo estas tre simpla:

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

Kun flua malŝarĝo ĝi estas iom pli komplika, sed sufiĉe komprenebla:

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

Tio, fakte, estas la tuta aranĝo. Nun ĉiuj TCP/UDP-trafiko falos en la fastnat-tabelon kaj estos prilaborita multe pli rapide.

Результаты

Por klarigi kiom "multe pli rapida" tio estas, mi aldonos ekrankopion de la ŝarĝo sur du veraj serviloj, kun la sama aparataro (Xeon E5-1650v2), idente agordita, uzante la saman Linuksan kernon, sed plenumante NAT en iptables. (NAT4) kaj en nftables (NAT5).

Rapida vojigo kaj NAT en Linukso

Ne estas grafikaĵo de pakoj sekundo en la ekrankopio, sed en la ŝarĝa profilo de ĉi tiuj serviloj la meza paka grandeco estas ĉirkaŭ 800 bajtoj, do la valoroj atingas ĝis 1.5Mpps. Kiel vi povas vidi, la servilo kun nftables havas grandegan rendimentan rezervon. Nuntempe, ĉi tiu servilo procesas ĝis 30Gbit/s je 3Mpps kaj klare kapablas renkonti la fizikan retan limigon de 40Gbps, havante senpagajn CPU-resursojn.

Mi esperas, ke ĉi tiu materialo estos utila al retaj inĝenieroj, kiuj provas plibonigi la rendimenton de siaj serviloj.

fonto: www.habr.com

Aldoni komenton