Linuxda tezkor marshrutlash va NAT

IPv4 manzillari tugashi bilan ko'plab aloqa operatorlari o'z mijozlariga manzillarni tarjima qilish orqali tarmoqqa kirishni ta'minlash zarurati bilan duch kelishadi. Ushbu maqolada men sizga tovar serverlarida Carrier Grade NAT ishlashini qanday olishingiz mumkinligini aytib beraman.

Biroz tarix

IPv4 manzili bo'sh joyning tugashi mavzusi endi yangi emas. Bir paytlar RIPE-da kutish ro'yxatlari paydo bo'ldi, keyin manzillar bloklari sotiladigan birjalar paydo bo'ldi va ularni ijaraga olish bo'yicha bitimlar tuzildi. Asta-sekin aloqa operatorlari manzil va port tarjimasidan foydalangan holda Internetga kirish xizmatlarini ko'rsatishni boshladilar. Ba'zilar har bir abonentga "oq" manzil berish uchun etarli manzillarni ololmadilar, boshqalari esa ikkilamchi bozorda manzillarni sotib olishdan bosh tortgan holda pulni tejashni boshladilar. Tarmoq uskunalari ishlab chiqaruvchilari bu fikrni qo'llab-quvvatladilar, chunki bu funksiya odatda qo'shimcha modullar yoki litsenziyalarni talab qiladi. Masalan, Juniper MX marshrutizatorlari qatorida (oxirgi MX104 va MX204dan tashqari) siz NAPTni alohida MS-MIC xizmat kartasida bajarishingiz mumkin, Cisco ASR1k CGN litsenziyasini talab qiladi, Cisco ASR9k alohida A9K-ISM-100 modulini talab qiladi. va unga A9K-CGN litsenziyasi -LIC. Umuman olganda, zavq juda ko'p pul talab qiladi.

IPTables

NAT-ni bajarish vazifasi maxsus hisoblash resurslarini talab qilmaydi, masalan, har qanday uy routerda o'rnatilgan umumiy maqsadli protsessorlar tomonidan hal qilinishi mumkin. Telekommunikatsiya operatori miqyosida bu muammoni FreeBSD (ipfw/pf) yoki GNU/Linux (iptables) bilan ishlaydigan tovar serverlari yordamida hal qilish mumkin. Biz FreeBSD-ni ko'rib chiqmaymiz, chunki... Men ushbu operatsion tizimdan foydalanishni ancha oldin to'xtatganman, shuning uchun biz GNU/Linux-ga yopishib olamiz.

Manzil tarjimasini yoqish unchalik qiyin emas. Avval siz nat jadvalidagi iptables-da qoidani ro'yxatdan o'tkazishingiz kerak:

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

Operatsion tizim nf_conntrack modulini yuklaydi, u barcha faol ulanishlarni kuzatib boradi va kerakli konvertatsiyalarni amalga oshiradi. Bu erda bir nechta nozikliklar mavjud. Birinchidan, biz aloqa operatori miqyosida NAT haqida gapirayotganimiz sababli, kutish vaqtini to'g'rilash kerak, chunki standart qiymatlar bilan tarjima jadvalining hajmi tezda halokatli qiymatlarga o'sadi. Quyida men serverlarda ishlatgan sozlamalarimga misol keltirilgan:

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

Ikkinchidan, tarjima jadvalining standart o'lchami aloqa operatori sharoitida ishlashga mo'ljallanmaganligi sababli, uni oshirish kerak:

net.netfilter.nf_conntrack_max = 3145728

Shuningdek, barcha translyatsiyalarni saqlaydigan xesh-jadval uchun chelaklar sonini ko'paytirish kerak (bu nf_conntrack modulidagi variant):

options nf_conntrack hashsize=1572864

Ushbu oddiy manipulyatsiyalardan so'ng, ko'p sonli mijoz manzillarini tashqi ko'rinishga aylantira oladigan to'liq ishlaydigan dizayn olinadi. Biroq, bu yechimning ishlashi ko'p narsani orzu qiladi. NAT uchun GNU/Linux-dan foydalanishdagi birinchi urinishlarimda (taxminan 2013-yilda) men har bir serverga 7Mpps tezlikda 0.8Gbit/s tezlikda ishlashga muvaffaq bo'ldim (Xeon E5-1650v2). O'sha vaqtdan beri GNU/Linux yadrosi tarmog'i stekida ko'plab turli xil optimallashtirishlar amalga oshirildi, bir xil uskunada bitta serverning ishlashi 18-19 Mpps tezlikda deyarli 1.8-1.9 Gbit / s gacha oshdi (bu maksimal qiymatlar edi) , lekin bitta server tomonidan qayta ishlangan trafik hajmiga talab ancha tez o'sdi. Natijada, turli serverlardagi yukni muvozanatlash uchun sxemalar ishlab chiqildi, ammo bularning barchasi taqdim etilayotgan xizmatlar sifatini sozlash, saqlash va saqlashning murakkabligini oshirdi.

NF jadvallari

Hozirgi vaqtda dasturiy ta'minotni "o'zgartirish sumkalari" ning moda tendentsiyasi DPDK va XDP dan foydalanish hisoblanadi. Ushbu mavzu bo'yicha juda ko'p maqolalar yozildi, ko'plab turli nutqlar qilindi va tijorat mahsulotlari paydo bo'ldi (masalan, VasExperts'dan SKAT). Ammo telekommunikatsiya operatorlarining cheklangan dasturiy resurslarini hisobga olgan holda, ushbu ramkalar asosida har qanday "mahsulot" ni mustaqil ravishda yaratish juda muammoli. Kelajakda bunday yechimni ishlatish ancha qiyin bo'ladi, xususan, diagnostika vositalarini ishlab chiqish kerak. Misol uchun, DPDK bilan standart tcpdump xuddi shunday ishlamaydi va XDP yordamida simlarga qaytarilgan paketlarni "ko'rmaydi". Foydalanuvchilar bo'shlig'iga paketlarni yo'naltirishning yangi texnologiyalari haqidagi barcha gaplar orasida ular e'tibordan chetda qoldi. hisobotlar ΠΈ maqolalar Pablo Neira Ayuso, iptables ta'minotchisi, nftables-da oqimlarni tushirishning rivojlanishi haqida. Keling, ushbu mexanizmni batafsil ko'rib chiqaylik.

Asosiy g'oya shundan iboratki, agar marshrutizator paketlarni bir seansdan oqimning har ikki yo'nalishi bo'yicha ham uzatgan bo'lsa (TCP seansi O'ZBEKISTON holatiga o'tgan bo'lsa), bu seansning keyingi paketlarini barcha xavfsizlik devori qoidalari orqali o'tkazishning hojati yo'q, chunki. Ushbu tekshiruvlarning barchasi paketni marshrutga o'tkazish bilan yakunlanadi. Va biz aslida marshrutni tanlashimiz shart emas - biz ushbu seansda paketlarni qaysi interfeysga va qaysi xostga yuborishimiz kerakligini allaqachon bilamiz. Faqatgina ushbu ma'lumotni saqlash va paketlarni qayta ishlashning dastlabki bosqichida marshrutlash uchun foydalanish qoladi. NATni amalga oshirishda nf_conntrack moduli tomonidan tarjima qilingan manzillar va portlardagi o'zgarishlar haqidagi ma'lumotlarni qo'shimcha ravishda saqlash kerak. Ha, albatta, bu holda iptablesdagi turli politsiyachilar va boshqa ma'lumotlar va statistik qoidalar ishlashni to'xtatadi, lekin alohida turgan NAT yoki, masalan, chegara vazifasi doirasida, bu juda muhim emas, chunki xizmatlar qurilmalarga taqsimlanadi.

Konfiguratsiya

Ushbu funktsiyadan foydalanish uchun bizga kerak:

  • Yangi yadrodan foydalaning. Funktsionallikning o'zi 4.16 yadrosida paydo bo'lganiga qaramay, uzoq vaqt davomida u juda "xom" edi va muntazam ravishda yadro vahimasini keltirib chiqardi. Hammasi 2019-yil dekabrida, LTS yadrolari 4.19.90 va 5.4.5 chiqarilganda barqarorlashdi.
  • Iptables qoidalarini nftables-ning juda yangi versiyasidan foydalanib, nftables formatida qayta yozing. Aynan 0.9.0 versiyada ishlaydi

Agar birinchi nuqta bilan printsipial jihatdan hamma narsa aniq bo'lsa, asosiysi montaj paytida modulni konfiguratsiyaga kiritishni unutmang (CONFIG_NFT_FLOW_OFFLOAD=m), keyin ikkinchi nuqta tushuntirishni talab qiladi. nftables qoidalari iptables qoidalariga qaraganda butunlay boshqacha tasvirlangan. hujjatlar deyarli barcha nuqtalarni ochib beradi, maxsus ham bor konvertorlar iptables dan nftablesgacha bo'lgan qoidalar. Shuning uchun men faqat NAT va oqim yukini o'rnatishga misol keltiraman. Masalan, kichik bir afsona: , - bu trafik o'tadigan tarmoq interfeyslari, aslida ular ikkitadan ko'p bo'lishi mumkin. , β€” β€œoq” manzillar diapazonining boshlanish va tugash manzili.

NAT konfiguratsiyasi juda oddiy:

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

Oqim yuklanishi bilan bu biroz murakkabroq, ammo tushunarli:

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

Bu, aslida, butun sozlash. Endi barcha TCP/UDP trafigi fastnat jadvaliga tushadi va tezroq qayta ishlanadi.

Natijalar

Bu qanchalik "tezroq" ekanligini tushunish uchun men ikkita haqiqiy serverga yukning skrinshotini biriktiraman, bir xil uskuna (Xeon E5-1650v2), bir xil sozlangan, bir xil Linux yadrosidan foydalangan holda, lekin iptables-da NAT-ni bajaradi. (NAT4) va nftablelarda (NAT5).

Linuxda tezkor marshrutlash va NAT

Skrinshotda sekundiga paketlar grafigi yo'q, ammo bu serverlarning yuklanish profilida paketlarning o'rtacha hajmi 800 bayt atrofida, shuning uchun qiymatlar 1.5 Mpps ga etadi. Ko'rib turganingizdek, nftables serveri juda katta ishlash zaxirasiga ega. Hozirgi vaqtda ushbu server 30Mpps tezlikda 3Gbit/s gacha tezlikni qayta ishlaydi va bepul protsessor resurslariga ega bo'lgan holda 40Gbps jismoniy tarmoq cheklovini qondirishga qodir.

Umid qilamanki, ushbu material o'z serverlarining ish faoliyatini yaxshilashga harakat qilayotgan tarmoq muhandislari uchun foydali bo'ladi.

Manba: www.habr.com

a Izoh qo'shish