Rrugë e shpejtë dhe NAT në Linux

Ndërsa adresat IPv4 shterohen, shumë operatorë të telekomit përballen me nevojën për t'u siguruar klientëve të tyre akses në rrjet duke përdorur përkthimin e adresave. Në këtë artikull do t'ju tregoj se si mund të merrni performancën NAT të klasës së transportuesit në serverët e mallrave.

Pak histori

Tema e shterimit të hapësirës së adresave IPv4 nuk është më e re. Në një moment, listat e pritjes u shfaqën në RIPE, më pas u shfaqën shkëmbime mbi të cilat tregtoheshin blloqet e adresave dhe u lidhën marrëveshje për t'i dhënë me qira. Gradualisht, operatorët e telekomit filluan të ofrojnë shërbime të aksesit në internet duke përdorur përkthimin e adresës dhe portit. Disa nuk arritën të merrnin adresa të mjaftueshme për të lëshuar një adresë "të bardhë" për secilin abonent, ndërsa të tjerët filluan të kursenin para duke refuzuar të blinin adresa në tregun sekondar. Prodhuesit e pajisjeve të rrjetit e mbështetën këtë ide, sepse ky funksion zakonisht kërkon module shtesë ose licenca shtesë. Për shembull, në linjën e ruterëve MX të Juniper (me përjashtim të MX104 dhe MX204 më të fundit), mund të kryeni NAPT në një kartë shërbimi të veçantë MS-MIC, Cisco ASR1k kërkon një licencë CGN, Cisco ASR9k kërkon një modul të veçantë A9K-ISM-100 dhe një licencë A9K-CGN -LIC për të. Në përgjithësi, kënaqësia kushton shumë para.

iptables

Detyra e kryerjes së NAT nuk kërkon burime të specializuara llogaritëse; ajo mund të zgjidhet nga procesorë me qëllime të përgjithshme, të cilët janë instaluar, për shembull, në çdo ruter shtëpiak. Në shkallën e një operatori telekomi, ky problem mund të zgjidhet duke përdorur serverë të mallrave që përdorin FreeBSD (ipfw/pf) ose GNU/Linux (iptables). Ne nuk do ta konsiderojmë FreeBSD, sepse... Unë e ndalova përdorimin e këtij OS shumë kohë më parë, kështu që ne do t'i përmbahemi GNU/Linux.

Aktivizimi i përkthimit të adresës nuk është aspak i vështirë. Së pari ju duhet të regjistroni një rregull në iptables në tabelën nat:

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

Sistemi operativ do të ngarkojë modulin nf_conntrack, i cili do të monitorojë të gjitha lidhjet aktive dhe do të kryejë konvertimet e nevojshme. Këtu ka disa hollësi. Së pari, meqenëse po flasim për NAT në shkallën e një operatori telekomunikacioni, është e nevojshme të rregulloni afatet, sepse me vlerat e paracaktuara, madhësia e tabelës së përkthimit do të rritet shpejt në vlera katastrofike. Më poshtë është një shembull i cilësimeve që kam përdorur në serverët e mi:

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

Dhe së dyti, meqenëse madhësia e paracaktuar e tabelës së përkthimit nuk është krijuar për të punuar në kushtet e një operatori telekomi, ajo duhet të rritet:

net.netfilter.nf_conntrack_max = 3145728

Është gjithashtu e nevojshme të rritet numri i kovave për tabelën hash që ruan të gjitha transmetimet (ky është një opsion në modulin nf_conntrack):

options nf_conntrack hashsize=1572864

Pas këtyre manipulimeve të thjeshta, merret një dizajn plotësisht funksional që mund të përkthejë një numër të madh adresash klientësh në një grup të atyre të jashtëm. Megjithatë, performanca e kësaj zgjidhjeje lë shumë për të dëshiruar. Në përpjekjet e mia të para për të përdorur GNU/Linux për NAT (rreth 2013), arrita të marr performancë prej rreth 7 Gbit/s me 0.8Mpps për server (Xeon E5-1650v2). Që nga ajo kohë, janë bërë shumë optimizime të ndryshme në grupin e rrjetit të kernelit GNU/Linux, performanca e një serveri në të njëjtin harduer është rritur në pothuajse 18-19 Gbit/s në 1.8-1.9 Mpps (këto ishin maksimumi vlerat), por kërkesa për volumin e trafikut, e përpunuar nga një server u rrit shumë më shpejt. Si rezultat, u zhvilluan skema për të balancuar ngarkesën në serverë të ndryshëm, por e gjithë kjo rriti kompleksitetin e konfigurimit, ruajtjes dhe ruajtjes së cilësisë së shërbimeve të ofruara.

Tabelat NF

Në ditët e sotme, një prirje në modë në softuerët "shifting bags" është përdorimi i DPDK dhe XDP. Janë shkruar shumë artikuj mbi këtë temë, janë mbajtur shumë fjalime të ndryshme dhe shfaqen produkte komerciale (për shembull, SKAT nga VasExperts). Por duke pasur parasysh burimet e kufizuara të programimit të operatorëve të telekomit, është mjaft problematike të krijoni vetë ndonjë "produkt" bazuar në këto korniza. Do të jetë shumë më e vështirë të përdoret një zgjidhje e tillë në të ardhmen; në veçanti, do të duhet të zhvillohen mjete diagnostikuese. Për shembull, tcpdump standard me DPDK nuk do të funksionojë ashtu si dhe nuk do të "shohë" paketat e dërguara në tela duke përdorur XDP. Mes gjithë bisedave për teknologjitë e reja për dërgimin e paketave në hapësirën e përdoruesit, ato kaluan pa u vënë re raporton и Artikull Pablo Neira Ayuso, mirëmbajtësi i iptables, në lidhje me zhvillimin e shkarkimit të rrjedhës në nftables. Le të hedhim një vështrim më të afërt në këtë mekanizëm.

Ideja kryesore është që nëse ruteri kalon paketat nga një seancë në të dy drejtimet e rrjedhës (sesioni TCP kaloi në gjendjen ESTABLISHED), atëherë nuk ka nevojë të kalojë paketat pasuese të këtij sesioni përmes të gjitha rregullave të murit të zjarrit, sepse të gjitha këto kontrolle ende do të përfundojnë me transferimin e paketës më tej në drejtim. Dhe ne në fakt nuk kemi nevojë të zgjedhim një rrugë - ne tashmë e dimë se në cilën ndërfaqe dhe në cilin host duhet të dërgojmë paketa brenda këtij sesioni. E tëra që mbetet është të ruhet ky informacion dhe të përdoret për rrugëtim në një fazë të hershme të përpunimit të paketave. Kur kryeni NAT, është e nevojshme të ruani gjithashtu informacione rreth ndryshimeve në adresat dhe portet e përkthyera nga moduli nf_conntrack. Po, sigurisht, në këtë rast policë të ndryshëm dhe informacione e rregulla të tjera statistikore në iptables pushojnë së punuari, por brenda kuadrit të detyrës së një NAT të veçantë në këmbë ose, për shembull, një kufiri, kjo nuk është aq e rëndësishme, sepse shërbimet shpërndahen nëpër pajisje.

konfiguracion

Për të përdorur këtë funksion na duhen:

  • Përdorni një bërthamë të freskët. Përkundër faktit se vetë funksionaliteti u shfaq në kernel 4.16, për një kohë mjaft të gjatë ishte shumë "i papërpunuar" dhe shkaktonte rregullisht panik të kernelit. Gjithçka u stabilizua rreth dhjetorit 2019, kur u lëshuan kernelet LTS 4.19.90 dhe 5.4.5.
  • Rishkruaj rregullat iptables në formatin nftables duke përdorur një version mjaft të fundit të nftables. Punon saktësisht në versionin 0.9.0

Nëse gjithçka në parim është e qartë me pikën e parë, gjëja kryesore është të mos harroni të përfshini modulin në konfigurim gjatë montimit (CONFIG_NFT_FLOW_OFFLOAD=m), atëherë pika e dytë kërkon shpjegim. Rregullat e nftables përshkruhen krejtësisht ndryshe nga iptables. Records zbulon pothuajse të gjitha pikat, ka edhe të veçanta konvertuesit rregullat nga iptables në nftables. Prandaj, unë do të jap vetëm një shembull të konfigurimit të NAT dhe shkarkimit të rrjedhës. Një legjendë e vogël për shembull: , - këto janë ndërfaqet e rrjetit nëpër të cilat kalon trafiku; në realitet mund të ketë më shumë se dy prej tyre. , — adresa e fillimit dhe e mbarimit të gamës së adresave "të bardha".

Konfigurimi NAT është shumë i thjeshtë:

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

Me shkarkimin e rrjedhës është pak më e ndërlikuar, por mjaft e kuptueshme:

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

Ky, në fakt, është i gjithë organizimi. Tani i gjithë trafiku TCP/UDP do të bjerë në tabelën fastnat dhe do të përpunohet shumë më shpejt.

Gjetjet

Për ta bërë të qartë se sa "shumë më i shpejtë" është kjo, unë do të bashkëngjit një pamje të ngarkesës në dy serverë të vërtetë, me të njëjtin harduer (Xeon E5-1650v2), të konfiguruar në mënyrë identike, duke përdorur të njëjtin kernel Linux, por që kryen NAT në iptables (NAT4) dhe në nftables (NAT5).

Rrugë e shpejtë dhe NAT në Linux

Nuk ka grafik të paketave për sekondë në pamjen e ekranit, por në profilin e ngarkesës së këtyre serverëve, madhësia mesatare e paketës është rreth 800 bajt, kështu që vlerat arrijnë deri në 1.5Mpps. Siç mund ta shihni, serveri me nftables ka një rezervë të madhe të performancës. Aktualisht, ky server përpunon deri në 30 Gbit/s në 3Mpps dhe është qartësisht i aftë të përmbushë kufizimin fizik të rrjetit prej 40 Gbps, ndërkohë që ka burime të lira CPU.

Shpresoj se ky material do të jetë i dobishëm për inxhinierët e rrjetit që përpiqen të përmirësojnë performancën e serverëve të tyre.

Burimi: www.habr.com

Shto një koment