Արագ երթուղում և NAT Linux-ում

Քանի որ IPv4 հասցեները սպառվում են, հեռահաղորդակցության շատ օպերատորներ կանգնած են իրենց հաճախորդներին ցանցային հասանելիություն ապահովելու անհրաժեշտության հետ՝ օգտագործելով հասցեների թարգմանությունը: Այս հոդվածում ես ձեզ կասեմ, թե ինչպես կարող եք ստանալ Carrier Grade NAT-ի կատարումը ապրանքային սերվերների վրա:

Մի քիչ պատմություն

IPv4 հասցեների տարածքի սպառման թեման այլևս նոր չէ: Ինչ-որ պահի RIPE-ում հայտնվեցին սպասման ցուցակները, այնուհետև ի հայտ եկան փոխանակումներ, որոնց վրա հասցեների բլոկների առևտուր էր իրականացվում և գործարքներ կնքվեցին դրանք վարձակալելու համար: Աստիճանաբար հեռահաղորդակցության օպերատորները սկսեցին տրամադրել ինտերնետ հասանելիության ծառայություններ՝ օգտագործելով հասցեների և նավահանգիստների թարգմանությունը: Ոմանք չկարողացան բավարար հասցեներ ձեռք բերել յուրաքանչյուր բաժանորդի համար «սպիտակ» հասցե տրամադրելու համար, իսկ մյուսները սկսեցին գումար խնայել՝ հրաժարվելով երկրորդական շուկայում հասցեներ գնելուց։ Ցանցային սարքավորումների արտադրողները պաշտպանեցին այս գաղափարը, քանի որ այս գործառույթը սովորաբար պահանջում է լրացուցիչ ընդլայնման մոդուլներ կամ լիցենզիաներ: Օրինակ, Juniper-ի MX երթուղիչների շարքում (բացառությամբ վերջին MX104-ի և MX204-ի), դուք կարող եք կատարել NAPT առանձին MS-MIC սպասարկման քարտի վրա, Cisco ASR1k-ը պահանջում է CGN լիցենզիա, Cisco ASR9k-ը՝ առանձին A9K-ISM-100 մոդուլ: և A9K-CGN լիցենզիա -LIC նրան: Ընդհանրապես, հաճույքը մեծ գումար է պահանջում։

IPT աղյուսակներ

NAT-ի կատարման խնդիրը չի պահանջում մասնագիտացված հաշվողական ռեսուրսներ, այն կարող է լուծվել ընդհանուր նշանակության պրոցեսորների միջոցով, որոնք տեղադրված են, օրինակ, ցանկացած տնային երթուղիչում: Հեռահաղորդակցության օպերատորի մասշտաբով այս խնդիրը կարող է լուծվել՝ օգտագործելով FreeBSD (ipfw/pf) կամ GNU/Linux (iptables) աշխատող ապրանքային սերվերներ։ Մենք չենք դիտարկի FreeBSD-ն, քանի որ... Ես վաղուց դադարեցի օգտագործել այս ՕՀ-ն, ուստի կառչենք GNU/Linux-ին:

Հասցեների թարգմանությունն ակտիվացնելն ամենևին էլ դժվար չէ: Սկզբում դուք պետք է գրանցեք կանոն iptables-ում nat աղյուսակում.

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

Օպերացիոն համակարգը կբեռնի nf_conntrack մոդուլը, որը կվերահսկի բոլոր ակտիվ կապերը և կկատարի անհրաժեշտ փոխարկումները: Այստեղ կան մի քանի նրբություններ. Նախ, քանի որ մենք խոսում ենք NAT-ի մասին հեռահաղորդակցության օպերատորի մասշտաբով, անհրաժեշտ է կարգավորել ժամանակացույցը, քանի որ լռելյայն արժեքներով թարգմանության աղյուսակի չափը արագորեն կաճի դեպի աղետալի արժեքներ: Ստորև բերված է իմ սերվերների վրա օգտագործված կարգավորումների օրինակ.

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

Եվ երկրորդը, քանի որ թարգմանության աղյուսակի լռելյայն չափը նախատեսված չէ հեռահաղորդակցության օպերատորի պայմաններում աշխատելու համար, այն պետք է մեծացվի.

net.netfilter.nf_conntrack_max = 3145728

Անհրաժեշտ է նաև ավելացնել բոլոր հեռարձակումները պահող հեշ աղյուսակի դույլերի քանակը (սա nf_conntrack մոդուլի տարբերակ է).

options nf_conntrack hashsize=1572864

Այս պարզ մանիպուլյացիաներից հետո ձեռք է բերվում լիովին աշխատող դիզայն, որը կարող է մեծ թվով հաճախորդի հասցեներ վերածել արտաքին հասցեների լողավազանի: Այնուամենայնիվ, այս լուծման կատարումը շատ ցանկալի է թողնում: GNU/Linux-ի NAT-ի համար օգտագործելու իմ առաջին փորձերի ժամանակ (մոտ 2013 թ.), ես կարողացա ստանալ մոտ 7 Գբիթ/վրկ արագություն մեկ սերվերի համար 0.8 Մփ/վրկ (Xeon E5-1650v2): Այդ ժամանակվանից ի վեր GNU/Linux միջուկի ցանցի կույտում բազմաթիվ տարբեր օպտիմիզացումներ են կատարվել, նույն սարքաշարի վրա մեկ սերվերի կատարումն աճել է մինչև գրեթե 18-19 Գբիթ/վրկ՝ 1.8-1.9 Մ/վ (սրանք առավելագույն արժեքներն էին) , բայց մեկ սերվերի կողմից մշակված թրաֆիկի ծավալի պահանջարկը շատ ավելի արագ աճեց: Արդյունքում մշակվեցին տարբեր սերվերների բեռը հավասարակշռելու սխեմաներ, սակայն այս ամենը մեծացրեց մատուցվող ծառայությունների տեղադրման, պահպանման և որակի պահպանման բարդությունը:

NF սեղաններ

Մեր օրերում ծրագրային ապահովման «փոխվող պայուսակների» նորաձև միտումը DPDK-ի և XDP-ի օգտագործումն է: Այս թեմայով գրվել են բազմաթիվ հոդվածներ, հնչել են բազմաթիվ տարբեր ելույթներ, և հայտնվում են կոմերցիոն արտադրանքներ (օրինակ՝ SKAT VasExperts-ից)։ Բայց հաշվի առնելով հեռահաղորդակցության օպերատորների ծրագրավորման սահմանափակ ռեսուրսները, բավականին խնդրահարույց է ինքնուրույն ստեղծել որևէ «արտադրանք» այս շրջանակների հիման վրա: Հետագայում շատ ավելի դժվար կլինի նման լուծում գործել, մասնավորապես, պետք է մշակվեն ախտորոշիչ գործիքներ։ Օրինակ, ստանդարտ tcpdump-ը DPDK-ով չի աշխատի հենց այնպես, և այն չի «տեսնի» փաթեթները, որոնք հետ ուղարկվում են լարերին XDP-ի միջոցով: Փաթեթների վերահասցեավորման օգտատերերի տարածք նոր տեխնոլոգիաների մասին խոսակցությունների ֆոնին նրանք աննկատ մնացին զեկույցներ и Հոդված Պաբլո Նեյրա Այուսոն, iptables-ի սպասարկող, nftables-ում հոսքի բեռնաթափման զարգացման մասին: Եկեք նայենք այս մեխանիզմին ավելի մանրամասն:

Հիմնական գաղափարն այն է, որ եթե երթուղիչը մի նիստից փաթեթներ է փոխանցել հոսքի երկու ուղղություններով (TCP նիստը անցել է ESTABLISHED վիճակ), ապա կարիք չկա այս նիստի հետագա փաթեթները փոխանցել firewall-ի բոլոր կանոններով, քանի որ Այս բոլոր ստուգումները դեռ կավարտվեն փաթեթի հետագա փոխանցմամբ դեպի երթուղի: Եվ մենք իրականում երթուղի ընտրելու կարիք չունենք. մենք արդեն գիտենք, թե որ ինտերֆեյսին և որ հոսթին պետք է փաթեթներ ուղարկենք այս նիստի ընթացքում: Մնում է միայն պահպանել այս տեղեկատվությունը և օգտագործել այն փաթեթների մշակման վաղ փուլում երթուղղելու համար: NAT-ը կատարելիս անհրաժեշտ է լրացուցիչ պահել nf_conntrack մոդուլի կողմից թարգմանված հասցեների և նավահանգիստների փոփոխությունների մասին տեղեկությունները: Այո, իհարկե, այս դեպքում դադարում են աշխատել տարբեր ոստիկաններ և iptables-ում այլ տեղեկատվական ու վիճակագրական կանոններ, բայց առանձին մշտական ​​NAT-ի կամ, օրինակ, սահմանի առաջադրանքի շրջանակներում դա այնքան էլ կարևոր չէ, քանի որ ծառայությունները. բաշխվում են սարքերի վրա:

Տեսիլ

Այս ֆունկցիան օգտագործելու համար մեզ անհրաժեշտ է.

  • Օգտագործեք թարմ միջուկ: Չնայած այն հանգամանքին, որ ֆունկցիոնալությունն ինքնին հայտնվել է միջուկում 4.16-ում, բավականին երկար ժամանակ այն շատ «հում» էր և պարբերաբար միջուկի խուճապ էր առաջացնում: Ամեն ինչ կայունացավ 2019 թվականի դեկտեմբերի մոտ, երբ թողարկվեցին LTS 4.19.90 և 5.4.5 միջուկները:
  • Վերաշարադրեք iptables-ի կանոնները nftables ձևաչափով՝ օգտագործելով nftables-ի բավականին վերջին տարբերակը: Աշխատում է հենց 0.9.0 տարբերակով

Եթե ​​առաջին կետով սկզբունքորեն ամեն ինչ պարզ է, ապա գլխավորն այն է, որ չմոռանանք հավաքման ժամանակ մոդուլը ներառել կոնֆիգուրացիայի մեջ (CONFIG_NFT_FLOW_OFFLOAD=m), ապա երկրորդ կետը բացատրություն է պահանջում։ nftables կանոնները նկարագրված են բոլորովին այլ կերպ, քան iptables-ում: Փաստաթղթերով հիմնավորում բացահայտում է գրեթե բոլոր կետերը, կան նաև հատուկ փոխարկիչներ կանոններ iptable-ից մինչև nftables: Հետևաբար, ես միայն կբերեմ NAT-ի և հոսքի բեռնաթափման տեղադրման օրինակ: Մի փոքրիկ լեգենդ, օրինակ. , - սրանք ցանցային ինտերֆեյսներն են, որոնցով անցնում է երթևեկությունը, իրականում դրանցից երկուսը կարող են լինել ավելին: , — «սպիտակ» հասցեների միջակայքի մեկնարկային և ավարտական ​​հասցեն:

NAT կոնֆիգուրացիան շատ պարզ է.

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

Հոսքի բեռնաթափման դեպքում դա մի փոքր ավելի բարդ է, բայց միանգամայն հասկանալի.

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

Դա, ըստ էության, ամբողջ կարգավորումն է: Այժմ ամբողջ TCP/UDP տրաֆիկը կընկնի fastnat աղյուսակի մեջ և շատ ավելի արագ կմշակվի:

Արդյունքները

Հասկանալու համար, թե որքանով է սա «շատ ավելի արագ», ես կկցեմ բեռնվածության սքրինշոթը երկու իրական սերվերների վրա՝ նույն սարքաշարով (Xeon E5-1650v2), նույնական կազմաձևված, օգտագործելով նույն Linux միջուկը, բայց կատարում է NAT iptables-ում: (NAT4) և nftable-ներում (NAT5):

Արագ երթուղում և NAT Linux-ում

Սքրինշոթում մեկ վայրկյանում փաթեթների գրաֆիկ չկա, բայց այս սերվերների բեռնվածության պրոֆիլում փաթեթի միջին չափը կազմում է մոտ 800 բայթ, ուստի արժեքները հասնում են մինչև 1.5 Մփ/վրկ: Ինչպես տեսնում եք, nftable-ներով սերվերն ունի կատարողականության հսկայական ռեզերվ։ Ներկայումս այս սերվերը մշակում է մինչև 30 Գբիտ/վ արագությամբ 3 Մպ/վ արագությամբ և ակնհայտորեն ի վիճակի է բավարարել ցանցի ֆիզիկական սահմանափակումը 40 Գբիտ/վրկ՝ միաժամանակ ունենալով պրոցեսորի անվճար ռեսուրսներ:

Հուսով եմ, որ այս նյութը օգտակար կլինի ցանցային ինժեներների համար, ովքեր փորձում են բարելավել իրենց սերվերների աշխատանքը:

Source: www.habr.com

Добавить комментарий