Линукс дээрх хурдан чиглүүлэлт ба NAT

IPv4 хаягууд хомсдохын хэрээр олон харилцаа холбооны операторууд хаягийн орчуулга ашиглан үйлчлүүлэгчдэдээ сүлжээний хандалт өгөх шаардлага тулгарч байна. Энэ нийтлэлд би та бараа бүтээгдэхүүний серверүүд дээр Carrier Grade NAT гүйцэтгэлийг хэрхэн авах талаар танд хэлэх болно.

Түүх бага

IPv4 хаягийн зай хомсдох сэдэв шинэ байхаа больсон. Хэзээ нэгэн цагт RIPE-д хүлээлгийн жагсаалт гарч ирсэн бөгөөд дараа нь аль блок хаягаар арилжаалагдаж байсан биржүүд гарч ирэн, тэдгээрийг түрээслэх гэрээ байгуулсан. Аажмаар харилцаа холбооны операторууд хаяг, порт орчуулгыг ашиглан интернетэд нэвтрэх үйлчилгээг үзүүлж эхлэв. Зарим нь захиалагч бүрт "цагаан" хаяг олгох хангалттай хаяг авч чадаагүй бол зарим нь хоёрдогч зах зээл дээр хаяг худалдаж авахаас татгалзаж мөнгөө хэмнэж эхлэв. Сүлжээний тоног төхөөрөмж үйлдвэрлэгчид энэ санааг дэмжсэн, учир нь Энэ функц нь ихэвчлэн нэмэлт өргөтгөлийн модулиуд эсвэл лиценз шаарддаг. Жишээлбэл, Juniper-ийн MX чиглүүлэгчийн шугамд (хамгийн сүүлийн үеийн MX104 ба MX204-ээс бусад) та тусдаа MS-MIC үйлчилгээний карт дээр NAPT хийх боломжтой, Cisco ASR1k нь CGN лиценз шаарддаг, Cisco ASR9k нь тусдаа A9K-ISM-100 модулийг шаарддаг. болон түүнд A9K-CGN лиценз -LIC. Ерөнхийдөө таашаал авах нь маш их мөнгө шаарддаг.

IPTables

NAT-ийг гүйцэтгэх даалгавар нь тусгай тооцоолох нөөц шаарддаггүй бөгөөд үүнийг жишээлбэл, гэрийн аль ч чиглүүлэгч дээр суулгасан ерөнхий зориулалттай процессороор шийдэж болно. Харилцаа холбооны операторын хэмжээнд энэ асуудлыг FreeBSD (ipfw/pf) эсвэл GNU/Linux (iptables) дээр ажилладаг барааны серверүүдийг ашиглан шийдэж болно. Бид FreeBSD-г авч үзэхгүй, учир нь... Би энэ үйлдлийн системээ ашиглахаа нэлээд удаж байгаа тул бид GNU/Linux-ийг ашиглах болно.

Хаягийн орчуулгыг идэвхжүүлэх нь тийм ч хэцүү биш юм. Эхлээд та nat хүснэгтэд iptables-д дүрмийг бүртгүүлэх хэрэгтэй.

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 онд) би нэг сервер (Xeon E7-0.8v5) тутамд 1650Mpps хурдтайгаар 2Gbit/s-ийн гүйцэтгэлийг авч чадсан. Тэр цагаас хойш GNU/Linux цөмийн сүлжээний стек дээр олон янзын оновчлолууд хийгдсэн бөгөөд нэг техник хангамж дээрх нэг серверийн гүйцэтгэл 18-19 Mpps хурдтайгаар бараг 1.8-1.9 Гбит/с хүртэл нэмэгдсэн (эдгээр нь хамгийн дээд утга байсан) , гэхдээ нэг серверээр боловсруулсан траффикийн эрэлт илүү хурдан өссөн. Үүний үр дүнд янз бүрийн серверүүдийн ачааллыг тэнцвэржүүлэх схемийг боловсруулсан боловч энэ бүхэн үзүүлж буй үйлчилгээний чанарыг тохируулах, хадгалах, хадгалахад төвөгтэй байдлыг нэмэгдүүлсэн.

NF хүснэгт

Өнөө үед "цүнх шилжүүлэх" програм хангамжийн моод хандлага бол DPDK болон XDP ашиглах явдал юм. Энэ сэдвээр маш олон нийтлэл бичсэн, олон янзын илтгэл тавигдаж, арилжааны бүтээгдэхүүнүүд гарч ирж байна (жишээлбэл, VasExperts-ийн SKAT). Гэхдээ харилцаа холбооны операторуудын програмчлалын нөөц хязгаарлагдмал байгаа тул эдгээр хүрээн дээр суурилсан аливаа "бүтээгдэхүүн" -ийг бие даан бүтээх нь нэлээд бэрхшээлтэй байдаг. Ирээдүйд ийм шийдлийг ашиглах нь илүү хэцүү байх болно, ялангуяа оношлогооны хэрэгслийг боловсруулах шаардлагатай болно. Жишээлбэл, DPDK-тэй стандарт tcpdump нь ийм байдлаар ажиллахгүй бөгөөд XDP ашиглан утас руу буцаж илгээгдсэн пакетуудыг "хардаггүй". Хэрэглэгчийн орон зайд пакет дамжуулах шинэ технологийн тухай бүх ярианы дунд тэд анзаарагдсангүй. тайлангууд и нийтлэл Пабло Нейра Аюсо, iptables засварлагч, nftables дахь урсгалыг буулгах хөгжлийн тухай. Энэ механизмыг илүү нарийвчлан авч үзье.

Гол санаа нь хэрвээ чиглүүлэгч нэг сессээс пакетуудыг урсгалын хоёр чиглэлд дамжуулсан бол (TCP сесс ТОГТООГДСОН төлөвт орсон) энэ сессийн дараагийн пакетуудыг галт ханын бүх дүрмээр дамжуулах шаардлагагүй болно. Эдгээр бүх шалгалтууд нь багцыг чиглүүлэлт рүү шилжүүлснээр дуусна. Бид үнэндээ маршрут сонгох шаардлагагүй - бид энэ сессийн хүрээнд аль интерфейс, аль хост руу пакет илгээх ёстойгоо аль хэдийн мэддэг болсон. Үлдсэн зүйл бол энэ мэдээллийг хадгалах, пакет боловсруулах эхний шатанд чиглүүлэхэд ашиглах явдал юм. NAT-г гүйцэтгэхдээ nf_conntrack модулийн орчуулсан хаяг, портуудын өөрчлөлтийн талаарх мэдээллийг нэмэлтээр хадгалах шаардлагатай. Тийм ээ, мэдээжийн хэрэг, энэ тохиолдолд iptables дахь янз бүрийн цагдаа, бусад мэдээлэл, статистикийн дүрмүүд ажиллахаа больсон боловч тусдаа байнгын NAT эсвэл жишээлбэл хилийн даалгаврын хүрээнд энэ нь тийм ч чухал биш, учир нь үйлчилгээ төхөөрөмжүүдэд тараагдсан байдаг.

Тохиргоо

Энэ функцийг ашиглахын тулд бидэнд хэрэгтэй:

  • Шинэ цөм ашигла. Хэдийгээр функц нь өөрөө цөмийн 4.16-д гарч ирсэн ч нэлээд удаан хугацаанд энэ нь маш "түүхий" байсан бөгөөд цөмийн үймээнийг байнга үүсгэдэг. 2019 оны 4.19.90-р сард LTS цөм 5.4.5 болон XNUMX гарсан үед бүх зүйл тогтворжсон.
  • Nftables-ийн нэлээд сүүлийн үеийн хувилбарыг ашиглан iptables дүрмийг nftables форматаар дахин бичээрэй. 0.9.0 хувилбар дээр яг ажилладаг

Хэрэв эхний зүйлд зарчмын хувьд бүх зүйл тодорхой бол хамгийн гол зүйл бол угсрах явцад модулийг тохиргоонд оруулахаа бүү мартаарай (CONFIG_NFT_FLOW_OFFLOAD = m), дараа нь хоёр дахь цэг нь тайлбарыг шаарддаг. nftables дүрмийг iptables-ээс тэс өөрөөр тайлбарласан байдаг. Баримт бичиг бараг бүх оноо илчилдэг, бас онцгой байдаг хувиргагчид iptables-ээс 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) хоёр бодит сервер дээрх ачааллын дэлгэцийн агшинг хавсаргана. (NAT4) болон nftables (NAT5).

Линукс дээрх хурдан чиглүүлэлт ба NAT

Дэлгэцийн агшинд секундын багцын график байхгүй боловч эдгээр серверүүдийн ачааллын профайлд багцын хэмжээ дунджаар 800 байт байдаг тул утгууд нь 1.5Mpps хүртэл байдаг. Таны харж байгаагаар nftables-тэй сервер нь гүйцэтгэлийн асар их нөөцтэй байдаг. Одоогийн байдлаар энэ сервер нь 30Mpps хурдаар 3Gbit/s хүртэл хурдацтай боловсруулдаг ба 40Gbps-ийн физик сүлжээний хязгаарлалтыг хангах чадвартай, харин CPU-ийн нөөц үнэгүй.

Энэ материал нь серверийнхээ ажиллагааг сайжруулахыг оролдож буй сүлжээний инженерүүдэд хэрэг болно гэж найдаж байна.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх