Linux-da sürətli marşrutlaşdırma və NAT

IPv4 ünvanları tükəndikcə, bir çox telekommunikasiya operatorları ünvan tərcüməsindən istifadə etməklə öz müştərilərinə şəbəkəyə çıxış təmin etmək zərurəti ilə üzləşirlər. Bu yazıda sizə əmtəə serverlərində Carrier Grade NAT performansını necə əldə edə biləcəyinizi söyləyəcəyəm.

Bir az tarixi

IPv4 ünvan məkanının tükənməsi mövzusu artıq yeni deyil. Bir nöqtədə, RIPE-də gözləmə siyahıları meydana çıxdı, sonra ünvan bloklarının satıldığı birjalar meydana çıxdı və onları icarəyə götürmək üçün sövdələşmələr bağlandı. Tədricən telekommunikasiya operatorları ünvan və port tərcüməsindən istifadə edərək İnternetə çıxış xidmətləri göstərməyə başladılar. Bəziləri hər bir abunəçiyə “ağ” ünvan vermək üçün kifayət qədər ünvan əldə edə bilmədi, digərləri isə təkrar bazarda ünvan almaqdan imtina edərək pula qənaət etməyə başladılar. Şəbəkə avadanlıqlarının istehsalçıları bu fikri dəstəklədilər, çünki bu funksionallıq adətən əlavə genişləndirmə modulları və ya lisenziyalar tələb edir. Məsələn, Juniper-in MX marşrutlaşdırıcıları xəttində (ən son MX104 və MX204 istisna olmaqla) ayrıca MS-MIC xidmət kartında NAPT həyata keçirə bilərsiniz, Cisco ASR1k CGN lisenziyasını tələb edir, Cisco ASR9k üçün ayrıca A9K-ISM-100 modulu tələb olunur. və ona A9K-CGN lisenziyası -LIC. Ümumiyyətlə, zövq çox pula başa gəlir.

IPTables

NAT-ın yerinə yetirilməsi vəzifəsi xüsusi hesablama resursları tələb etmir, onu, məsələn, hər hansı bir ev marşrutlaşdırıcısında quraşdırılmış ümumi təyinatlı prosessorlar həll edə bilər. Telekommunikasiya operatoru miqyasında bu problem FreeBSD (ipfw/pf) və ya GNU/Linux (iptables) ilə işləyən əmtəə serverlərindən istifadə etməklə həll edilə bilər. FreeBSD-ni nəzərdən keçirməyəcəyik, çünki... Mən bu ƏS-dən çoxdan istifadəni dayandırdım, ona görə də GNU/Linux-a sadiq qalacağıq.

Ünvan tərcüməsini aktivləşdirmək heç də çətin deyil. Əvvəlcə nat cədvəlində iptables-də bir qayda qeydiyyatdan keçirməlisiniz:

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

Əməliyyat sistemi nf_conntrack modulunu yükləyəcək, o, bütün aktiv əlaqələrə nəzarət edəcək və lazımi çevrilmələri həyata keçirəcək. Burada bir neçə incəlik var. Birincisi, bir telekommunikasiya operatorunun miqyasında NAT haqqında danışdığımız üçün, fasilələri tənzimləmək lazımdır, çünki standart dəyərlərlə tərcümə cədvəlinin ölçüsü sürətlə fəlakətli dəyərlərə qədər böyüyəcəkdir. Aşağıda serverlərimdə istifadə etdiyim parametrlərə bir nümunə verilmişdir:

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

İkincisi, tərcümə cədvəlinin standart ölçüsü telekommunikasiya operatorunun şərtlərində işləmək üçün nəzərdə tutulmadığından, onu artırmaq lazımdır:

net.netfilter.nf_conntrack_max = 3145728

Bütün yayımları saxlayan hash cədvəli üçün vedrələrin sayını artırmaq da lazımdır (bu, nf_conntrack modulunda bir seçimdir):

options nf_conntrack hashsize=1572864

Bu sadə manipulyasiyalardan sonra çox sayda müştəri ünvanını xarici ünvanlar hovuzuna çevirə bilən tamamilə işləyən bir dizayn əldə edilir. Bununla belə, bu həllin performansı arzuolunan çox şey buraxır. NAT üçün GNU/Linux-dan istifadə etməkdə ilk cəhdlərimdə (təxminən 2013-cü ildə) hər serverə 7Mpps-də təxminən 0.8Gbit/s performans əldə edə bildim (Xeon E5-1650v2). O vaxtdan bəri GNU/Linux nüvəsinin şəbəkə yığınında çoxlu müxtəlif optimallaşdırmalar aparıldı, eyni aparatda bir serverin performansı 18-19 Mpps-də demək olar ki, 1.8-1.9 Gbit/s-ə yüksəldi (bunlar maksimum idi) dəyərlər), lakin bir server tərəfindən emal edilən trafik həcminə tələb daha sürətli artdı. Nəticədə, müxtəlif serverlərdə yükü tarazlaşdırmaq üçün sxemlər hazırlanmışdır, lakin bütün bunlar göstərilən xidmətlərin qurulması, saxlanması və keyfiyyətinin qorunmasının mürəkkəbliyini artırdı.

NF masaları

Hal-hazırda, proqram təminatının "dəyişən çantalar" da dəbli tendensiyası DPDK və XDP-nin istifadəsidir. Bu mövzuda çoxlu məqalələr yazılıb, çoxlu müxtəlif çıxışlar edilib və kommersiya məhsulları ortaya çıxır (məsələn, VasExperts-dən SKAT). Ancaq telekommunikasiya operatorlarının məhdud proqramlaşdırma resurslarını nəzərə alsaq, bu çərçivələrə əsaslanan hər hansı bir "məhsul" yaratmaq olduqca problemlidir. Gələcəkdə belə bir həlli idarə etmək daha çətin olacaq, xüsusən də diaqnostik vasitələr hazırlanmalı olacaq. Məsələn, DPDK ilə standart tcpdump belə işləməyəcək və XDP istifadə edərək naqillərə geri göndərilən paketləri "görməyəcək". İstifadəçi məkanına paket yönləndirməsini çıxarmaq üçün yeni texnologiyalar haqqında bütün söhbətlər arasında onlar diqqətdən kənarda qaldılar. hesabat verir и Məqalə Pablo Neira Ayuso, iptables baxıcısı, nftables-də axın yüklənməsinin inkişafı haqqında. Bu mexanizmə daha yaxından nəzər salaq.

Əsas ideya ondan ibarətdir ki, marşrutlaşdırıcı bir seansdan paketləri axının hər iki istiqamətində ötürmüşdürsə (TCP sessiyası MÜSTƏKİL vəziyyətə keçib), onda bu sessiyanın sonrakı paketlərini bütün firewall qaydaları vasitəsilə keçirməyə ehtiyac yoxdur, çünki bütün bu yoxlamalar hələ də paketin marşrutlaşdırmaya köçürülməsi ilə başa çatacaq. Və əslində marşrut seçməyimizə ehtiyac yoxdur - biz artıq bilirik ki, bu sessiya çərçivəsində paketləri hansı interfeysə və hansı hosta göndərməliyik. Qalan yalnız bu məlumatı saxlamaq və paket emalının ilkin mərhələsində marşrutlaşdırma üçün istifadə etməkdir. NAT yerinə yetirərkən, nf_conntrack modulu tərəfindən tərcümə edilmiş ünvanlar və portlardakı dəyişikliklər haqqında məlumatı əlavə olaraq saxlamaq lazımdır. Bəli, əlbəttə ki, bu halda iptables-də müxtəlif polislər və digər məlumatlar və statistik qaydalar işləməyi dayandırır, lakin ayrıca duran NAT və ya məsələn, bir sərhəd vəzifəsi çərçivəsində bu o qədər də vacib deyil, çünki xidmətlər cihazlar arasında paylanır.

Konfiqurasiya

Bu funksiyadan istifadə etmək üçün bizə lazımdır:

  • Təzə nüvədən istifadə edin. Funksionallığın özü kernel 4.16-da görünməsinə baxmayaraq, kifayət qədər uzun müddət çox "xam" idi və müntəzəm olaraq nüvə panikasına səbəb oldu. LTS ləpələri 2019 və 4.19.90-in buraxıldığı 5.4.5-cu ilin dekabrında hər şey sabitləşdi.
  • nftables-in kifayət qədər yeni versiyasından istifadə edərək iptables qaydalarını nftables formatında yenidən yazın. Tam olaraq 0.9.0 versiyasında işləyir

Birinci bəndlə prinsipcə hər şey aydındırsa, əsas odur ki, montaj zamanı modulu konfiqurasiyaya daxil etməyi unutmayaq (CONFIG_NFT_FLOW_OFFLOAD=m), onda ikinci bənd izahat tələb edir. nftables qaydaları iptables ilə müqayisədə tamamilə fərqli təsvir edilmişdir. Documentation Demək olar ki, bütün məqamları ortaya qoyur, xüsusi də var çeviricilər iptables-dən nftable-a qədər qaydalar. Buna görə də, mən yalnız NAT və axın yüklənməsinin qurulmasına dair bir nümunə verəcəyəm. Məsələn, kiçik bir əfsanə: , - bunlar trafikin keçdiyi şəbəkə interfeysləridir, əslində onlardan ikidən çox ola bilər. , — “ağ” ünvanlar diapazonunun başlanğıc və son ünvanı.

NAT konfiqurasiyası çox sadədir:

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

Axın yükü ilə bu bir az daha mürəkkəbdir, lakin olduqca başa düşüləndir:

#! /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, əslində, bütün quraşdırmadır. İndi bütün TCP/UDP trafiki fastnat cədvəlinə düşəcək və daha sürətli işlənəcək.

Tapıntılar

Bunun nə qədər “daha ​​sürətli” olduğunu aydınlaşdırmaq üçün mən eyni Linux nüvəsindən istifadə edərək eyni şəkildə konfiqurasiya edilmiş, lakin iptables-də NAT yerinə yetirən eyni aparatla (Xeon E5-1650v2) iki real serverə yüklənmənin ekran görüntüsünü əlavə edəcəyəm. (NAT4) və nftables (NAT5).

Linux-da sürətli marşrutlaşdırma və NAT

Ekran görüntüsündə saniyədə paketlərin qrafiki yoxdur, lakin bu serverlərin yükləmə profilində orta paket ölçüsü təxminən 800 baytdır, buna görə də dəyərlər 1.5 Mpps-ə çatır. Gördüyünüz kimi, nftables ilə server böyük performans ehtiyatına malikdir. Hal-hazırda, bu server 30Mpps-də 3Gbit/s-ə qədər emal edir və pulsuz CPU resurslarına malik olmaqla, 40Gbps fiziki şəbəkə məhdudiyyətini qarşılamaq qabiliyyətinə malikdir.

Ümid edirəm ki, bu material öz serverlərinin işini yaxşılaşdırmağa çalışan şəbəkə mühəndisləri üçün faydalı olacaq.

Mənbə: www.habr.com

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