Kiire marsruutimine ja NAT Linuxis

IPv4 aadresside lõppemisega seisavad paljud teenusepakkujad silmitsi vajadusega korraldada oma klientide juurdepääs võrku aadresside tõlkimise abil. Antud artiklis selgitan, kuidas saavutada Carrier Grade NAT tasemel jõudlust kaupade serverites.

Veidi ajalugu

IPv4-aadressiruumi ammendumise teema pole enam uus. Millalgi tekkis RIPE-s ootejärjekord (waiting list), seejärel tekkisid turud, kus kaupleti aadressiblokkidega ja tehti tehinguid nende üürimiseks. Aja jooksul hakkasid sideoperaatorid pakkuma Interneti-juurdepääsu aadresside ja portide maskeerimise (NAT) abil. Mõnedel ei olnud piisavalt aadresse, et iga tellija jaoks välja anda „valget” aadressi, samas kui teised hakkasid kulusid kokku hoidma, loobudes aadresside ostmisest teisest turust. Võrguseadmete tootjad toetasid seda ideed, kuna see funktsioon nõuab tavaliselt täiendavaid laiendusi või litsentse. Näiteks Juniperi MX marsruuterite seerias (välja arvatud viimased MX104 ja MX204) saab NAPT-i teostada eraldi teenusekaardil MS-MIC, Cisco ASR1k jaoks on vajalik SGN-litsents, Cisco ASR9k puhul aga eraldi moodul A9K-ISM-100 ja sellele litsents A9K-CGN-LIC. Üldiselt maksab see lõbu korralikku raha.

IPTables

NAT-i täitmise ülesanne ei vaja spetsialiseeritud arvutusressursse, seda suudavad lahendada tavalised protsessorid, nagu need, mis on näiteks igas koduses ruuteris. Sideoperaatori mastaabis saab seda ülesannet lahendada kaupade serverite kasutamisega, mis on hallatavad FreeBSD (ipfw/pf) või GNU/Linuxi (iptables) süsteemi all. FreeBSD-d me ei käsitle, kuna olen juba ammu sellest operatsioonisüsteemist loobunud, nii et peatume GNU/Linuxil.

Aadresside tõlke sisselülitamine pole sugugi keeruline. Esiteks tuleb kirjutada reegel iptables'i nat-tabelisse:

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

Operatsioonisüsteem laadib mooduli nf_conntrack, mis jälgib kõiki aktiivseid ühendusi ja teeb vajalikud muundamised. Siin on mõned nüansid. Esiteks, kuna räägime NAT-ist sideoperaatori mastaabis, tuleb aegumisi kohandada, sest vaikeväärtustega suureneb tõlketabeli suurus üsna kiiresti katastroofiliste väärtusteni. Allpool on näide seadistustest, mida olen oma serverites kasutanud:

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

Teiseks, kuna vaikimisi ei ole tõlketabeli suurus mõeldud töötamiseks sideoperaatori tingimustes, on seda vaja suurendada:

net.netfilter.nf_conntrack_max = 3145728

Samuti on vajalik suurendada ka bucket'ite arvu kõigi tõlkete haldava hash-tabeli jaoks (see on nf_conntrack mooduli valik):

options nf_conntrack hashsize=1572864

Pärast neid lihtsaid toiminguid on asi korralikult töövalmis, suudab ta suunata suure hulga klientide aadresse välisse punt. Siiski jätab selle lahenduse jõudlus soovida. Oma esimestel katsetel GNU/Linuxi kasutamisel NAT-i jaoks (umbes 2013. aastal) suutsin saavutada 7 Gbit/s jõudluse koos 0.8 Mpps-ga ühel serveril (Xeon E5-1650v2). Sellest ajast on GNU/Linuxi tuuma võrguhalduskiht läbimas mitmeid erinevaid optimeerimisi ja ühe serveri jõudlus samadel komponentidel on peaaegu kahekordistunud, ulatudes 18-19 Gbit/s ja 1.8-1.9 Mpps-ni (need olid maksimaalsed näitajad), kuid ühe serveri töötleva liikluse vajadus on kasvanud palju kiiremini. Lõpuks töötati välja erinevad koormuse tasakaalustamise skeemid mitme serveri vahel, kuid kõik see suurendas seadistamise, hooldamise ja pakutava teenuse kvaliteedi säilitamise keerukust.

NFTables

Praegune trend programmistikas "pakettide ülekandmisel" on DPDK ja XDP kasutamine. Selle teema kohta on kirjutatud palju artikleid, toimunud on mitmeid ettekandeid ja turule on tulnud erinevad kommertstoodete lahendused (näiteks Scat VasExpertsilt). Kuid piiratud ressurssidega programmijate seas on teleringiteenustes nende raamistikude järgi oma lahenduse loomine üsna keeruline. Sellist lahendust hiljem kasutada on veelgi keerulisem, eelkõige tuleb arendada diagnostikavahendeid. Näiteks ei tööta standardne tcpdump DPDK-ga lihtsalt nii, ja XDP abil saatud paketid ei "näe" seda tagasipöördudes juhtmes. Kõikide arutelude taustal uute tehnoloogiate kohta, mis on seotud pakettide edastamise viiga user-space'i, on jaanud tähelepanuta ettekanded ja artikkel Pablo Neira Ayuso, iptables'i hooldaja, flow offloading'i arendamisest nftables'is. Vaatame seda mehhanismi lähemalt.

Peamine idee on see, et kui ruuter on edastanud ühe seansi pakette mõlemale poole voogu (TCP seanss on jõudnud olekusse ESTABLISHED), siis ei ole vajalik edastada järgmisi selle seansi pakette läbi kõigi tulemüürireeglite, kuna kõik need kontrollid lõppevad nagunii paketi edastamisega edasi suunamisse. Ega marsruudi valimisega pole midagi teha – me teame juba, millisele liidesele ja millele hostile tuleb pakette selle seansi piires edastada. Tuleb vaid säilitada see teave ja kasutada seda pakkide marsruudistamiseks varases paketi töötlemise etapis. NAT-i teostamisel tuleb lisaks säilitada teave aadresside ja sadamate muutuste kohta, mille on muutnud nf_conntrack moodul. Jah, loomulikult lakkavad sel juhul toimimast erinevad poliitikad ja muud teabe-statistilised reeglid iptables'is, kuid üksiku NAT-i ülesande või näiteks piiriülese ülesande raames pole see nii olulist, kuna teenused on jaotatud seadmete vahel.

Konfiguratsioon

Selle funktsiooni kasutamiseks peame:

  • Kasutage värsket tuuma. Kuigi funktsionaalsus ilmus tuumas 4.16, oli see pikka aega väga „toores” ja põhjustas regulaarselt kernel panic. Kõik stabiliseerus umbes 2019. aasta detsembris, kui ilmusid LTS tuumad 4.19.90 ja 5.4.5.
  • Kandke iptables'i reeglid nftablesi formaati, kasutades piisavalt värsket versiooni nftablesist. Töötab täpselt versioonis 0.9.0.

Kui esimese punkti osas on kõik põhimõtteliselt selge, siis peamine on mitte unustada lisada moodul konfiguratsiooni kogumise ajal (CONFIG_NFT_FLOW_OFFLOAD=m), siis teine punkt vajab selgitusi. Nftablesi reeglid ei ole üldse samamoodi kirjeldatud kui iptablesi omad. Dokumentatsioon avaldab praktiliselt kõik punktid, samuti on olemas spetsiaalsed konverterid reeglite tõlkimiseks iptablesist nftablesisse. Seetõttu toon ainult NAT-i ja flow offloadi seadistuse näite. Väike legend näite jaoks: , — need on võrgu liidesed, mille kaudu liiklus läbib, neid võib olla tegelikult rohkem kui kaks. , — valgete aadresside vahemiku algus- ja lõppaadress.

NAT-i konfiguratsioon on väga lihtne:

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

Flow offload on veidi keerulisem, kuid täiesti arusaadav:

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

Siin on kogu seadistus. Nüüd suunatakse kogu TCP/UDP liiklus fastnat tabelisse ja töödeldakse palju kiiremini.

Tulemused

Et mõista, kui palju kiiremini, jagan ma ekraanipilti kahe reaalse serveri koormusest, millel on sama riistvara (Xeon E5-1650v2), samad seaded ja mis kasutavad sama Linuxi tuuma, kuid teostavad NAT-d iptables'is (NAT4) ja nftables'is (NAT5).

Kiire marsruutimine ja NAT Linuxis

Ekraanipildil ei ole pakettide sekundi graafikut, aga nende serverite koormuse profiilis on paketi keskmine suurus umbes 800 baiti, seega jõuavad väärtused 1.5Mpps-ni. Nagu näha, on nftablesiga serveril tohutu jõudlusreserv. Praegu suudab see server töödelda kuni 30Gbit/s kiirusel 3Mpps ja on selgelt suuteline ulatuma füüsilistesse 40Gbps piiridesse, omades samas CPU ressursse vaba.

Loodan, et see materjal on kasulik võrguinseneridele, kes püüavad parandada oma serverite tootlikkust.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster