Linux'та тез маршрутизация жана NAT

IPv4 даректери түгөнүп бараткандыктан, көптөгөн байланыш операторлору даректерди которуу аркылуу өз кардарларына тармакка кирүү мүмкүнчүлүгүн берүү зарылдыгына туш болушат. Бул макалада мен сизге товар серверлеринде Carrier Grade NAT көрсөткүчүн кантип алууга болорун айтып берем.

Бир аз тарыхы

IPv4 дареги мейкиндиктин чарчоо темасы мындан ары жаңы эмес. Кайсы бир учурда, RIPEде күтүү тизмелери пайда болду, андан кийин даректер блоктору соодаланган биржалар пайда болду жана аларды ижарага берүү боюнча келишимдер түзүлдү. Бара-бара байланыш операторлору дарек жана порт которууну колдонуу менен Интернетке кирүү кызматтарын көрсөтө башташты. Кээ бирлери ар бир абонентке “ак” дарек берүү үчүн жетиштүү даректерди ала албаса, башкалары экинчилик рынокто даректерди сатып алуудан баш тартып, акчасын үнөмдөй башташкан. Тармактык жабдууларды өндүрүүчүлөр бул идеяны колдошту, анткени бул функция адатта кошумча кеңейтүү модулдарын же лицензияларды талап кылат. Мисалы, Juniperдин MX роутерлер линиясында (акыркы MX104 жана MX204 кошпогондо) NAPT өзүнчө MS-MIC тейлөө картасында аткарылышы мүмкүн, 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

Бул жөнөкөй манипуляциялардан кийин, кардарлардын көп сандагы даректерин тышкы даректердин пулуна которо турган толук жумушчу дизайн алынат. Бирок, бул чечимдин аткарылышы көп нерсени талап кылат. NAT үчүн GNU/Linux колдонууга болгон биринчи аракеттеримде (болжол менен 2013-жылы) мен бир серверге 7 Мпп/сек ылдамдыкта 0.8 Гбит/сек ылдамдыкта иштей алдым (Xeon E5-1650v2). Ошол убактан бери GNU/Linux ядро ​​тармагынын стекинде көптөгөн ар кандай оптималдаштыруулар жасалган, бир эле жабдыкта бир сервердин иштеши 18-19 Мп/сек ылдамдыкта дээрлик 1.8-1.9 Гбит/с чейин жогорулаган (бул максималдуу маанилер болгон) , бирок бир сервер тарабынан иштетилген трафиктин көлөмүнө суроо-талап бир топ ылдам өстү. Натыйжада, ар кандай серверлердеги жүктөмдү тең салмактоо үчүн схемалар иштелип чыккан, бирок мунун баары сунушталган кызматтардын сапатын орнотуунун, тейлөөнүн жана колдоонун татаалдыгын жогорулатты.

NTFables

Бүгүнкү күндө программалык камсыздоонун модалуу тенденциясы "баштыктарды которуу" DPDK жана XDP колдонуу болуп саналат. Бул темада көптөгөн макалалар жазылды, көптөгөн ар кандай сөздөр айтылды жана коммерциялык продуктылар пайда болууда (мисалы, VasExperts компаниясынан SKAT). Бирок байланыш операторлорунун чектелген программалоо ресурстарын эске алуу менен, бул алкактардын негизинде өз алдынча кандайдыр бир "продукцияны" түзүү абдан көйгөйлүү. Келечекте мындай чечимди иштетүү алда канча кыйын болот, атап айтканда, диагностикалык каражаттарды иштеп чыгуу керек. Мисалы, DPDK менен стандарттуу tcpdump так ошондой иштебейт жана XDP аркылуу зымдарга кайра жөнөтүлгөн пакеттерди "көрбөйт". Пакетти колдонуучу мейкиндигине жөнөтүүнүн жаңы технологиялары жөнүндө сөз болуп жатканда, алар байкалбай калышты. докладдар и макалалар Пабло Нейра Аюсо, iptables тейлөөчүсү, nftablesдеги агымды түшүрүүнү өнүктүрүү жөнүндө. Бул механизмди кененирээк карап көрөлү.

Негизги идея, эгерде роутер бир сеанстан пакеттерди агымдын эки тарабында өткөрсө (TCP сеансы ОРНАЛГАН абалга өткөн), анда бул сеанстын кийинки пакеттерин брандмауэрдин бардык эрежелери аркылуу өткөрүүнүн кереги жок, анткени бардык бул текшерүүлөр дагы эле пакетти маршрутизацияга өткөрүп берүү менен аяктайт. Жана биз чындыгында маршрутту тандоонун кереги жок - биз бул сессиянын ичинде пакеттерди кайсы интерфейске жана кайсы хостко жөнөтүшүбүз керектигин билебиз. Бул маалыматты сактоо жана пакетти иштетүүнүн алгачкы этабында аны маршрутизациялоо үчүн колдонуу гана калды. NAT аткарып жатканда, nf_conntrack модулу тарабынан которулган даректердеги жана порттордогу өзгөрүүлөр жөнүндө маалыматты кошумча сактоо керек. Ооба, албетте, бул учурда ар кандай полиция кызматкерлери жана iptables башка маалымат жана статистикалык эрежелери ишин токтотот, бирок өзүнчө турган NAT тапшырмасынын алкагында же, мисалы, чек ара, бул анчалык деле маанилүү эмес, анткени кызматтар түзмөктөр арасында бөлүштүрүлөт.

тарам

Бул функцияны колдонуу үчүн бизге керек:

  • Жаңы өзөктү колдонуңуз. Функционалдык өзү 4.16 ядросунда пайда болгонуна карабастан, ал узак убакыт бою абдан "чийки" болгон жана дайыма ядро ​​​​паникасын жаратып келген. Баары 2019-жылдын декабрында, LTS ядролору 4.19.90 жана 5.4.5 чыкканда турукташкан.
  • 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), бирдей конфигурацияланган, ошол эле Linux ядросун колдонуп, бирок iptables'де NAT аткарган (NAT4) жана nftables (NAT5).

Linux'та тез маршрутизация жана NAT

Скриншотто секундасына пакеттердин графиги жок, бирок бул серверлердин жүктөө профилинде пакеттин орточо өлчөмү болжол менен 800 байт, ошондуктан баалуулуктар 1.5Mpps чейин жетет. Көрүнүп тургандай, nftables менен серверде чоң аткаруу резерви бар. Азыркы учурда, бул сервер 30Mpps ылдамдыгы 3 Гбит/сек чейин иштетет жана 40 Гбит/сек физикалык тармак чектөөсүнө жооп бере алат, ошол эле учурда бош CPU ресурстары бар.

Бул материал серверлеринин иштешин жакшыртууга аракет кылып жаткан тармак инженерлери үчүн пайдалуу болот деп ишенем.

Source: www.habr.com

Комментарий кошуу