Ātra maršrutēšana un NAT Linux

Līdz ar IPv4 adreses izsīkšanu, daudzi telekomunikāciju operatori saskārās ar nepieciešamību organizēt piekļuvi saviem klientiem internetam, izmantojot adresu tulkošanu. Šajā rakstā es pastāstīšu, kā var sasniegt Carrier Grade NAT veiktspēju uz parastajiem serveriem.

Mazliet vēstures

Tēma par IPv4 adresācijas telpas izsīkušanu jau nav jauna. Kādā brīdī RIPE parādījās gaidīšanas saraksti, pēc tam izveidojās biržas, kurās tirgoja adresu blokos un noslēdza līgumus par to nomu. Pakāpeniski telekomunikāciju operatori sāka piedāvāt interneta piekļuves pakalpojumus, izmantojot adresu un portu tulkošanu. Kāds nesagaidīja pietiekami daudz adreses, lai katram abonentam piešķirtu „baltu” adresi, bet citi sāka ietaupīt līdzekļus, atteicoties no adresu iegādes sekundārajā tirgū. Tīkla aparatūras ražotāji atbalstīja šo ideju, jo šī funkcionalitāte parasti prasa papildu paplašināšanas moduļus vai licences. Piemēram, Juniper MX maršrutētāju sērijā (izņemot jaunākos MX104 un MX204) NAPT var veikt uz atsevišķas MS-MIC pakalpojumu kartes, bet Cisco ASR1k ir nepieciešama CGN licence, savukārt Cisco ASR9k - atsevišķs A9K-ISM-100 modulis un licence A9K-CGN-LIC tam. Kopumā prieks maksā dārgi.

IPTables

NAT uzdevums neprasa specializētus aprēķinu resursus; to spēj risināt vispārējās lietošanas procesori, kas uzstādīti, piemēram, jebkurā mājas maršrutētājā. Telekomunikāciju operatora mērogā šo uzdevumu var risināt, izmantojot parastus serverus, kas darbojas ar FreeBSD (ipfw/pf) vai GNU/Linux (iptables). FreeBSD mēs neapskatīsim, jo es diezgan sen atteicos no šīs operētājsistēmas izmantošanas, tāpēc apstāsimies pie GNU/Linux.

Ieslēgt adresu tulkošanu vispār nav grūti. Vispirms ir nepieciešams definēt noteikumu iptables nat tabulā:

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to - --persistent

Operētājsistēma ielādēs nf_conntrack moduli, kas uzraudzīs visas aktīvās savienojumus un veiks nepieciešamos pārveidojumus. Ir dažas nianses. Pirmkārt, ņemot vērā, ka runa ir par NAT sakaru operatora mērogā, jāpielāgo timeout vērtības, jo ar noklusējuma vērtībām pārtveršanas tabulas izmērs diezgan ātri var pieaugt līdz katastrofālam līmenim. Zemāk ir piemērs iestatījumiem, kurus es izmantoju savos serveros:

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

Otrkārt, ņemot vērā, ka noklusējuma pārtveršanas tabulas izmērs nav paredzēts darbam sakaru operatora apstākļos, to nepieciešams palielināt:

net.netfilter.nf_conntrack_max = 3145728

Tāpat jāpalielina arī grozu skaits hesh-tabulā, kas glabā visas pārtveršanas (šī ir nf_conntrack moduļa opcija):

options nf_conntrack hashsize=1572864

Pēc šīm nekomplicētajām manipulācijām izveidojas diezgan funkcionējoša konstrukcija, kas var pārtvert lielu skaitu klientu adreses uz ārējo adresāciju. Tomēr šī risinājuma veiktspēja atstāj ko vēlēties. Manās pirmajās centienos izmantot GNU/Linux NAT (apmēram 2013. gadā) izdevās sasniegt veiktspēju ap 7Gbit/s pie 0.8Mpps uz vienu serveri (Xeon E5-1650v2). Kopš tā laika GNU/Linux kodola tīkla steka ir veikts daudz dažādu optimizāciju, un viena servera veiktspēja ar to pašu aparatūru ir pieaugusi gandrīz līdz 18-19 Gbit/s pie 1.8-1.9 Mpps (tie bija robežvērtības), taču pieprasījums pēc trafika apjoma, ko apstrādā viens serveris, pieauga daudz ātrāk. Beigās tika izstrādātas slodzes sadales shēmas dažādiem serveriem, taču tas viss palielināja konfigurācijas, apkalpošanas un sniegto pakalpojumu kvalitātes uzturēšanas sarežģītību.

NFTables

Šobrīd populārā tendence programmēšanā "paketi pārcelšanas" jomā ir DPDK un XDP izmantošana. Par šo tēmu ir uzrakstīts daudz rakstu, notikušas dažādas uzstāšanās, parādās komerciāli produkti (piemēram, SKAT no VasExperts). Taču, ņemot vērā ierobežotos resursus, kas ir pieejami sakaru operatoru programmētājiem, izstrādāt kaut ko pašu uz šo ietvaru bāzes ir diezgan sarežģīti. Turpmāk izmantot šādu risinājumu būs ievērojami grūtāk, jo būs jāsagatavo diagnostikas rīki. Piemēram, standarta tcpdump ar DPDK vienkārši nedarbosies, un arī paketi, kas nosūtītas atpakaļ vados, izmantojot XDP, tas neredzēs. Visiem šiem runām par jaunām tehnoloģijām paketu pārsūtīšanā lietotāja telpā, palika nepamanītas ziņojumi un raksti Pablo Neira Ayuso, iptables uzturētājs, par flow offloading izstrādi nftables. Apskatīsim šo mehānismu sīkāk.

Galvenā ideja ir tāda, ka, ja maršrutētājs ir palaidis cauri paketes vienā sesijā abos plūsmu virzienos (TCP sesija ir kļuvusi par ESTABLISHED stāvokli), tad nav nepieciešams palaist nākamās šīs sesijas paketes cauri visiem ugunsmūra noteikumiem, jo visi šie pārbaudījumi galu galā tāpat noslēgsies ar paketes tālāku pārsūtīšanu maršrutēšanā. Un nebūs pat nepieciešams veikt maršruta izvēli — mēs jau zinām, kurā saskarnē un kādam hostam šīs sesijas ietvaros ir jānosūta paketes. Paliek tikai saglabāt šo informāciju un izmantot to paketes apstrādes agrīnajā posmā. Veicot NAT, papildus jāuztur informācija par adresēm un portiem, ko pārvērš nf_conntrack modulis. Jā, protams, šajā gadījumā pārtrauc darboties dažādi politikas noteicēji un citi informācijas statistikas noteikumi iptables, taču atsevišķā NAT, piemēram, robežsargāšanas uzdevumos, tas nav tik būtiski, jo pakalpojumi ir sadalīti pa ierīcēm.

Konfigurācija

Lai izmantotu šo funkciju, mums ir jā:

  • Izmanto jaunu kodolu. Neskatoties uz to, ka pats funkcionalitāte parādījās jau kodolā 4.16, ilgu laiku tā bija ļoti "neizstrādāta" un regulāri izsauca kernel panikas. Viss stabilizējās aptuveni 2019. gada decembrī, kad iznāca LTS kodoli 4.19.90 un 5.4.5.
  • Pārveidot iptables noteikumus nftables formātā, izmantojot pietiekami jaunu nftables versiju. Darbojas precīzi 0.9.0 versijā.

Ja ar pirmo punktu viss principā ir skaidrs, galvenais ir neaizmirst iekļaut moduli konfigurācijā, veidojot (CONFIG_NFT_FLOW_OFFLOAD=m), tad otrais punkts prasa paskaidrojumu. Nftables noteikumi netiek aprakstīti tāpat kā iptables. Dokumentācija atklāj praktiski visus aspektus, ir arī speciālie pārvērstāji noteikumiem no iptables uz nftables. Tādēļ es sniegšu tikai NAT un flow offload iestatījuma piemēru. Neliela leģenda piemēram: <i_if>, <o_if> — ir tīkla interfeisi, caur kuriem plūst satiksme, to var būt vairāk nekā divi. <pool_addr_start>, <pool_addr_end> — ir sākuma un beigu adrese „balto” adresu diapazonā.

NAT konfigurācija ir ļoti vienkārša:

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

Ar flow offload ir nedaudz sarežģītāk, bet pilnīgi saprotami:

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

Lūk, īsumā, visa iestatīšana. Tagad visa TCP/UDP satiksme iekritīs fastnat tabulā un tiks apstrādāta ievērojami ātrāk.

Rezultāti

Lai saprastu, cik tas ir „ievērojami ātrāk”, es pievienošu ekrānšāviņu par slodzi uz diviem reāliem serveriem, ar identisku aparatūru (Xeon E5-1650v2), identiski konfigurētiem, izmantojot to pašu Linux kodolu, bet veicot NAT ar iptables (NAT4) un nftables (NAT5).

Ātra maršrutēšana un NAT Linux

Ekrānšāviņā nav pakotņu sekundē grafika, bet šo serveru slodzes profilā vidējā pakotnes izmērs ir ap 800 baitiem, tāpēc vērtības sasniedz 1.5Mpps. Kā redzams, serverim ar nftables ir milzīgs veiktspējas rezervāts. Šobrīd šis serveris apstrādā līdz 30Gbit/s pie 3Mpps un skaidri spēj sasniegt fizisko tīkla ierobežojumu 40Gbps, saglabājot brīvas CPU resursus.

Ceru, ka šis materiāls būs noderīgs tīkla inženieriem, kuri cenšas uzlabot savu serveru veiktspēju.

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster