Schnelles Routing und NAT in Linux

Mit dem Schwinden der IPv4-Adressen stehen viele Telekommunikationsanbieter vor der Notwendigkeit, den Zugang ihrer Kunden zum Netzwerk ĂŒber Address Translation zu organisieren. In diesem Artikel werde ich erklĂ€ren, wie man Carrier Grade NAT-Leistung auf Commodity-Servern erreichen kann.

Ein wenig Geschichte

Das Thema des Schwunds des IPv4-Adressraums ist nicht neu. So gab es irgendwann in RIPE Wartelisten, dann entstanden MĂ€rkte, auf denen Adressblöcke gehandelt und MietvertrĂ€ge fĂŒr diese abgeschlossen wurden. Nach und nach begannen die Telekommunikationsanbieter, Internetzugangsdienste mithilfe von Address- und Port-Translation anzubieten. Einige konnten nicht genĂŒgend Adressen erhalten, um jedem Abonnenten eine „weiße“ Adresse zuzuweisen, wĂ€hrend andere begannen, Kosten zu sparen, indem sie auf den Kauf von Adressen auf dem SekundĂ€rmarkt verzichteten. Die Hersteller von NetzwerkausrĂŒstung unterstĂŒtzten diese Idee, da diese FunktionalitĂ€t in der Regel zusĂ€tzliche Erweiterungsmodule oder Lizenzen erfordert. Zum Beispiel kann man bei Juniper in der MX-Router-Linie (außer bei den neuesten MX104 und MX204) NAPT auf einer separaten Servicekarte MS-MIC durchfĂŒhren, bei Cisco ASR1k ist eine CGN-Lizenz erforderlich, bei Cisco ASR9k ein separates Modul A9K-ISM-100 und eine Lizenz A9K-CGN-LIC dafĂŒr. Insgesamt kostet der Spaß eine Menge Geld.

IPTables

Die Aufgabe, NAT zu implementieren, erfordert keine spezialisierten Rechenressourcen; sie kann von allgemeinen Prozessoren bewÀltigt werden, die beispielsweise in jedem Heimrouter installiert sind. Im Rahmen einer Telekommunikationsgesellschaft kann diese Aufgabe mit Commodity-Servern unter FreeBSD (ipfw/pf) oder GNU/Linux (iptables) gelöst werden. FreeBSD wollen wir hierbei nicht betrachten, da ich diese Betriebssystem vor einiger Zeit aufgehört habe zu nutzen, also werden wir uns auf GNU/Linux konzentrieren.

Es ist ĂŒberhaupt nicht schwierig, die AdressĂŒbersetzung zu aktivieren. ZunĂ€chst mĂŒssen Sie eine Regel in iptables in die nat-Tabelle einfĂŒgen:

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -j SNAT --to - --persistent

Das Betriebssystem lĂ€dt das Modul nf_conntrack, das alle aktiven Verbindungen ĂŒberwacht und die erforderlichen Umwandlungen durchfĂŒhrt. Es gibt dabei einige Feinheiten. Erstens, da es sich um NAT im Umfang eines Telekommunikationsanbieters handelt, mĂŒssen die Timeouts angepasst werden, da die Standardwerte dazu fĂŒhren, dass die GrĂ¶ĂŸe der Translations-Tabelle schnell auf katastrophale Werte anwĂ€chst. Hier ein Beispiel fĂŒr die Einstellungen, die ich auf meinen Servern verwendet habe:

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

Und zweitens, da die StandardgrĂ¶ĂŸe der Translations-Tabelle nicht fĂŒr den Betrieb bei einem Telekommunikationsanbieter ausgelegt ist, muss sie erhöht werden:

net.netfilter.nf_conntrack_max = 3145728

Außerdem muss auch die Anzahl der Buckets fĂŒr die Hash-Tabelle, die alle Translations speichert (dies ist eine Option des Moduls nf_conntrack), erhöht werden:

options nf_conntrack hashsize=1572864

Nach diesen einfachen Anpassungen entsteht eine funktionierende Struktur, die eine große Anzahl an Client-Adressen in einen Pool von externen Adressen umwandeln kann. Allerdings lĂ€sst die Leistung dieser Lösung zu wĂŒnschen ĂŒbrig. Bei meinen ersten Versuchen, GNU/Linux fĂŒr NAT zu verwenden (ca. 2013) konnte ich eine Leistung von etwa 7Gbit/s bei 0,8Mpps auf einem Server (Xeon E5-1650v2) erreichen. Seitdem wurden viele verschiedene Optimierungen im Netzwerk-Stack des GNU/Linux-Kernels vorgenommen, und die Leistung eines Servers bei der gleichen Hardware stieg praktisch auf 18-19 Gbit/s bei 1,8-1,9 Mpps (das waren die Grenzwerte). Doch der Bedarf an dem Volumen des Datenverkehrs, das von einem Server verarbeitet wird, nahm viel schneller zu. letztlich wurden Load-Balancing-Schemata auf verschiedene Server entwickelt, wodurch die KomplexitĂ€t der Konfiguration, des Betriebs und der Aufrechterhaltung der QualitĂ€t der Dienstleistungen zunahm.

NFTables

Derzeit ist der Trend im programmatischen «Umsetzen von Paketen» die Nutzung von DPDK und XDP. Zu diesem Thema wurden zahlreiche Artikel veröffentlicht, viele verschiedene PrĂ€sentationen gehalten, und es erscheinen kommerzielle Produkte (zum Beispiel SKAT von VasExperts). Doch unter den Bedingungen begrenzter Ressourcen der Programmierer bei den Telekommunikationsanbietern ist es ziemlich problematisch, eigenstĂ€ndig ein «Werk» auf Basis dieser Frameworks zu entwickeln. Ein solches Lösung spĂ€ter zu nutzen, wird wesentlich schwieriger sein, da insbesondere Werkzeuge zur Diagnose entwickelt werden mĂŒssen. Beispielsweise wird der Standard tcpdump mit DPDK nicht einfach so funktionieren, und die Pakete, die mit XDP zurĂŒck in die Leitungen gesendet werden, wird er nicht «sehen». Vor dem Hintergrund aller GesprĂ€che ĂŒber neue Technologien zum Ausgeben von Paketweiterleitungen im User-Space sind unbemerkt geblieben Berichte und des Artikels Pablo Neira Ayuso, den Maintainer von iptables, ĂŒber die Entwicklung des Flow Offloadings in nftables. Lassen Sie uns diesen Mechanismus genauer betrachten.

Die Hauptidee besteht darin, dass, wenn der Router Pakete einer Sitzung in beide Richtungen des Flusses (eine TCP-Sitzung hat den Status ESTABLISHED erreicht) durchlĂ€sst, es nicht notwendig ist, nachfolgende Pakete dieser Sitzung durch alle Firewall-Regeln zu leiten, da alle diese PrĂŒfungen ohnehin mit der Übertragung des Pakets zur weiteren Routing fortgesetzt werden. Zudem muss die Routenwahl nicht getroffen werden — wir wissen bereits, auf welches Interface und an welchen Host die Pakete innerhalb dieser Sitzung gesendet werden sollen. Es bleibt nur, diese Informationen zu speichern und sie fĂŒr das Routing in der frĂŒhen Phase der Paketverarbeitung zu verwenden. Bei der DurchfĂŒhrung von NAT mĂŒssen zusĂ€tzlich die Informationen ĂŒber die Adress- und PortĂ€nderungen, die vom Modul nf_conntrack umgewandelt wurden, gespeichert werden. Ja, natĂŒrlich funktionieren dabei verschiedene Policer und andere informationsstatistische Regeln in iptables nicht mehr, aber im Rahmen der Aufgabe eines einzelnen stehenden NAT oder zum Beispiel eines Borders ist das nicht so wichtig, da die Dienste auf verschiedene GerĂ€te verteilt sind.

Konfiguration

Um diese Funktion zu nutzen, mĂŒssen wir:

  • Ein aktuelles Kerneldatum verwenden. Obwohl die FunktionalitĂ€t bereits in Kernel 4.16 eingefĂŒhrt wurde, war sie lange Zeit sehr «instabil» und fĂŒhrte regelmĂ€ĂŸig zu Kernel-Panics. Stabilisiert hat sich alles etwa im Dezember 2019, als die LTS-Kernel 4.19.90 und 5.4.5 erschienen.
  • Die iptables-Regeln im nftables-Format umschreiben, wobei eine ausreichend aktuelle Version von nftables verwendet wird. Funktioniert genau in Version 0.9.0.

Wenn der erste Punkt grundsĂ€tzlich klar ist, das Wichtigste ist, das Modul in die Konfiguration beim Kompilieren aufzunehmen (CONFIG_NFT_FLOW_OFFLOAD=m), erfordert der zweite Punkt ErklĂ€rungen. Die nftables-Regeln werden ganz anders beschrieben als die von iptables. Dokumentation deckt praktisch alle Aspekte ab, es gibt auch spezielle Konverter von Regeln aus iptables in nftables. Daher werde ich nur ein Beispiel fĂŒr die Einrichtung von NAT und Flow Offload geben. Eine kurze Legende fĂŒr das Beispiel: , — das sind die Netzwerk-Interfaces, ĂŒber die der Verkehr lĂ€uft; tatsĂ€chlich kann es mehr als zwei geben. , — die Start- und Endadresse des Bereichs der „weißen“ Adressen.

Die NAT-Konfiguration ist sehr einfach:

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

Mit Flow Offload ist es etwas komplizierter, aber durchaus nachvollziehbar:

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

Das ist eigentlich die gesamte Konfiguration. Jetzt wird der gesamte TCP/UDP-Verkehr in die Tabelle fastnat gelangen und viel schneller verarbeitet.

Ergebnisse

Um klarzumachen, wie viel schneller dies wirklich ist, werde ich einen Screenshot der Last auf zwei realen Servern beifĂŒgen, die die gleiche AusrĂŒstung (Xeon E5-1650v2), eine identische Konfiguration und denselben Linux-Kernel verwenden, aber NAT in iptables (NAT4) und in nftables (NAT5) ausfĂŒhren.

Schnelles Routing und NAT in Linux

Im Screenshot gibt es kein Diagramm der Pakete pro Sekunde, aber im Lastprofil dieser Server liegt die durchschnittliche PaketgrĂ¶ĂŸe bei etwa 800 Byte, weshalb die Werte bis zu 1,5Mpps erreichen. Wie zu sehen ist, hat der Server mit nftables eine enorme Leistungsreserven. Derzeit verarbeitet dieser Server bis zu 30Gbit/s bei 3Mpps und kann offenbar das physische Limit des Netzwerks von 40Gbps erreichen, wĂ€hrend er freie CPU-Ressourcen hat.

Ich hoffe, dieses Material wird Netzwerkingenieuren nĂŒtzlich sein, die versuchen, die Leistung ihrer Server zu verbessern.

Quelle: habr.com

ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server đŸ”„ ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster