Mabilis na pagruruta at NAT sa Linux

Habang nauubos ang mga IPv4 address, maraming operator ng telecom ang nahaharap sa pangangailangang bigyan ang kanilang mga kliyente ng access sa network gamit ang pagsasalin ng address. Sa artikulong ito sasabihin ko sa iyo kung paano ka makakakuha ng pagganap ng Carrier Grade NAT sa mga server ng kalakal.

Ang isang maliit na kasaysayan

Ang paksa ng IPv4 address space exhaustion ay hindi na bago. Sa ilang mga punto, lumitaw ang mga listahan ng naghihintay sa RIPE, pagkatapos ay lumitaw ang mga palitan kung saan ipinagpalit ang mga bloke ng mga address at napagpasyahan ang mga deal upang i-lease ang mga ito. Unti-unti, nagsimula ang mga operator ng telecom na magbigay ng mga serbisyo sa pag-access sa Internet gamit ang pagsasalin ng address at port. Ang ilan ay hindi nakakuha ng sapat na mga address upang magbigay ng "puting" address sa bawat subscriber, habang ang iba ay nagsimulang makatipid ng pera sa pamamagitan ng pagtanggi na bumili ng mga address sa pangalawang merkado. Sinuportahan ng mga tagagawa ng kagamitan sa network ang ideyang ito, dahil ang pagpapaandar na ito ay karaniwang nangangailangan ng mga karagdagang module ng extension o lisensya. Halimbawa, sa linya ng mga MX router ng Juniper (maliban sa pinakabagong MX104 at MX204), maaari kang magsagawa ng NAPT sa isang hiwalay na MS-MIC service card, nangangailangan ang Cisco ASR1k ng lisensya ng CGN, nangangailangan ang Cisco ASR9k ng hiwalay na A9K-ISM-100 module at isang lisensya ng A9K-CGN -LIC sa kanya. Sa pangkalahatan, ang kasiyahan ay nagkakahalaga ng maraming pera.

IPTables

Ang gawain ng pagsasagawa ng NAT ay hindi nangangailangan ng dalubhasang mga mapagkukunan ng computing; maaari itong malutas ng mga pangkalahatang layunin na mga processor, na naka-install, halimbawa, sa anumang home router. Sa sukat ng isang telecom operator, ang problemang ito ay malulutas gamit ang mga commodity server na tumatakbo sa FreeBSD (ipfw/pf) o GNU/Linux (iptables). Hindi namin isasaalang-alang ang FreeBSD, dahil... Matagal na akong tumigil sa paggamit ng OS na ito, kaya mananatili kami sa GNU/Linux.

Ang pagpapagana ng pagsasalin ng address ay hindi mahirap. Una kailangan mong magrehistro ng isang panuntunan sa iptables sa nat table:

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

Ilo-load ng operating system ang module ng nf_conntrack, na susubaybayan ang lahat ng aktibong koneksyon at gagawin ang mga kinakailangang conversion. Mayroong ilang mga subtleties dito. Una, dahil pinag-uusapan natin ang tungkol sa NAT sa sukat ng isang telecom operator, kinakailangan upang ayusin ang mga timeout, dahil sa mga default na halaga ang laki ng talahanayan ng pagsasalin ay mabilis na lalago sa mga sakuna na halaga. Nasa ibaba ang isang halimbawa ng mga setting na ginamit ko sa aking mga server:

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

At pangalawa, dahil ang default na sukat ng talahanayan ng pagsasalin ay hindi idinisenyo upang gumana sa ilalim ng mga kondisyon ng isang telecom operator, kailangan itong dagdagan:

net.netfilter.nf_conntrack_max = 3145728

Kinakailangan din na dagdagan ang bilang ng mga bucket para sa hash table na nag-iimbak ng lahat ng mga broadcast (ito ay isang opsyon sa nf_conntrack module):

options nf_conntrack hashsize=1572864

Pagkatapos ng mga simpleng manipulasyong ito, ang isang ganap na gumaganang disenyo ay nakuha na maaaring magsalin ng malaking bilang ng mga address ng kliyente sa isang pool ng mga panlabas. Gayunpaman, ang pagganap ng solusyon na ito ay nag-iiwan ng maraming nais. Sa aking mga unang pagtatangka sa paggamit ng GNU/Linux para sa NAT (circa 2013), nakuha ko ang pagganap ng humigit-kumulang 7Gbit/s sa 0.8Mpps bawat server (Xeon E5-1650v2). Mula noong panahong iyon, maraming iba't ibang mga pag-optimize ang ginawa sa GNU/Linux kernel network stack, ang pagganap ng isang server sa parehong hardware ay tumaas sa halos 18-19 Gbit/s sa 1.8-1.9 Mpps (ito ang pinakamataas na halaga) , ngunit ang pangangailangan para sa dami ng trapiko, na naproseso ng isang server ay lumago nang mas mabilis. Bilang resulta, ang mga scheme ay binuo upang balansehin ang pagkarga sa iba't ibang mga server, ngunit lahat ng ito ay nagpapataas ng pagiging kumplikado ng pag-set up, pagpapanatili at pagpapanatili ng kalidad ng mga serbisyong ibinigay.

Mga NFTable

Sa ngayon, isang naka-istilong trend sa software na "shifting bags" ay ang paggamit ng DPDK at XDP. Maraming artikulo ang naisulat sa paksang ito, maraming iba't ibang talumpati ang ginawa, at lumalabas ang mga komersyal na produkto (halimbawa, SKAT mula sa VasExperts). Ngunit dahil sa limitadong mapagkukunan ng programming ng mga operator ng telecom, medyo may problemang gumawa ng anumang "produkto" batay sa mga framework na ito nang mag-isa. Magiging mas mahirap na patakbuhin ang gayong solusyon sa hinaharap; lalo na, kailangang bumuo ng mga diagnostic tool. Halimbawa, ang karaniwang tcpdump na may DPDK ay hindi gagana nang ganoon lang, at hindi nito "makikita" ang mga packet na ipinadala pabalik sa mga wire gamit ang XDP. Sa gitna ng lahat ng usapan tungkol sa mga bagong teknolohiya para sa pag-output ng packet forwarding sa user-space, hindi sila napansin. mga ulat ΠΈ Artikulo Pablo Neira Ayuso, iptables maintainer, tungkol sa pagbuo ng flow offloading sa nftables. Tingnan natin ang mekanismong ito nang mas detalyado.

Ang pangunahing ideya ay kung ang router ay nagpasa ng mga packet mula sa isang session sa magkabilang direksyon ng daloy (TCP session ay napunta sa ESTABLISHED state), hindi na kailangang ipasa ang mga kasunod na packet ng session na ito sa lahat ng mga panuntunan sa firewall, dahil lahat ng mga pagsusuring ito ay matatapos pa rin sa paglilipat ng packet sa pagruruta. At hindi talaga namin kailangang pumili ng ruta - alam na namin kung saang interface at kung aling host ang kailangan naming magpadala ng mga packet sa loob ng session na ito. Ang natitira na lang ay iimbak ang impormasyong ito at gamitin ito para sa pagruruta sa isang maagang yugto ng pagproseso ng packet. Kapag nagsasagawa ng NAT, kinakailangan din na mag-imbak ng impormasyon tungkol sa mga pagbabago sa mga address at port na isinalin ng nf_conntrack module. Oo, siyempre, sa kasong ito, ang iba't ibang mga pulis at iba pang impormasyon at mga patakaran sa istatistika sa mga iptable ay huminto sa pagtatrabaho, ngunit sa loob ng balangkas ng gawain ng isang hiwalay na nakatayo na NAT o, halimbawa, isang hangganan, hindi ito napakahalaga, dahil ang mga serbisyo ay ipinamamahagi sa mga device.

Configuration

Upang magamit ang function na ito kailangan namin:

  • Gumamit ng sariwang kernel. Sa kabila ng katotohanan na ang pag-andar mismo ay lumitaw sa kernel 4.16, sa loob ng mahabang panahon ito ay napaka "raw" at regular na nagdulot ng kernel panic. Nag-stabilize ang lahat noong Disyembre 2019, nang ilabas ang mga kernel ng LTS 4.19.90 at 5.4.5.
  • Isulat muli ang mga panuntunan ng iptables sa format na nftables gamit ang isang medyo kamakailang bersyon ng nftables. Eksaktong gumagana sa bersyon 0.9.0

Kung ang lahat sa prinsipyo ay malinaw sa unang punto, ang pangunahing bagay ay huwag kalimutang isama ang module sa pagsasaayos sa panahon ng pagpupulong (CONFIG_NFT_FLOW_OFFLOAD=m), kung gayon ang pangalawang punto ay nangangailangan ng paliwanag. Ang mga panuntunan ng nftables ay ganap na naiibang inilarawan kaysa sa iptables. Records inilalantad ang halos lahat ng mga punto, mayroon ding mga espesyal mga nagko-convert mga panuntunan mula sa iptables hanggang sa nftables. Samakatuwid, magbibigay lamang ako ng isang halimbawa ng pag-set up ng NAT at flow offload. Isang maliit na alamat halimbawa: , - ito ang mga interface ng network kung saan dumadaan ang trapiko; sa katotohanan ay maaaring mayroong higit sa dalawa sa kanila. , β€” ang panimulang at pangwakas na address ng hanay ng mga "puting" address.

Ang pagsasaayos ng NAT ay napaka-simple:

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

Sa daloy ng offload ay medyo mas kumplikado, ngunit medyo naiintindihan:

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

Iyon, sa katunayan, ay ang buong setup. Ngayon ang lahat ng trapiko ng TCP/UDP ay mahuhulog sa fastnat table at mapoproseso nang mas mabilis.

Natuklasan

Upang gawing malinaw kung gaano ito "mas mabilis", mag-attach ako ng isang screenshot ng pag-load sa dalawang tunay na server, na may parehong hardware (Xeon E5-1650v2), magkaparehong na-configure, gamit ang parehong Linux kernel, ngunit gumaganap ng NAT sa iptables (NAT4) at sa nftables (NAT5).

Mabilis na pagruruta at NAT sa Linux

Walang graph ng mga packet bawat segundo sa screenshot, ngunit sa load profile ng mga server na ito ang average na laki ng packet ay humigit-kumulang 800 bytes, kaya ang mga value ay umabot ng hanggang 1.5Mpps. Tulad ng nakikita mo, ang server na may mga nftable ay may malaking reserbang pagganap. Sa kasalukuyan, ang server na ito ay nagpoproseso ng hanggang 30Gbit/s sa 3Mpps at malinaw na may kakayahang matugunan ang pisikal na limitasyon ng network na 40Gbps, habang may mga libreng mapagkukunan ng CPU.

Umaasa ako na ang materyal na ito ay magiging kapaki-pakinabang sa mga inhinyero ng network na nagsisikap na mapabuti ang pagganap ng kanilang mga server.

Pinagmulan: www.habr.com

Magdagdag ng komento