Linux の高速ルーティングと NAT

IPv4 アドレスが枯渇するにつれて、多くの通信事業者は、アドレス変換を使用してクライアントにネットワーク アクセスを提供する必要性に直面しています。 この記事では、汎用サーバーでキャリア グレードの NAT パフォーマンスを実現する方法について説明します。

歴史を少し

IPv4 アドレス空間の枯渇というトピックは、もはや新しいものではありません。 ある時点で、RIPE に待機リストが出現し、その後、アドレスのブロックが取引され、それらをリースする取引が締結される取引所が出現しました。 徐々に、通信事業者はアドレスとポート変換を使用してインターネット アクセス サービスを提供し始めました。 各加入者に「ホワイト」アドレスを発行するのに十分なアドレスを取得できなかった企業もあれば、二次市場でのアドレスの購入を拒否して資金を節約し始めた企業もいます。 ネットワーク機器のメーカーはこのアイデアを支持しました。 この機能には通常、追加の拡張モジュールまたはライセンスが必要です。 たとえば、ジュニパーの 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 については考慮しません。なぜなら... 私はかなり前にこの OS の使用をやめたので、GNU/Linux を使い続けるつもりです。

アドレス変換を有効にすることはまったく難しいことではありません。 まず、iptables の nat テーブルにルールを登録する必要があります。

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 年頃) では、サーバーあたり 7Mpps で約 0.8Gbit/s のパフォーマンスを得ることができました (Xeon E5-1650v2)。 それ以来、GNU/Linux カーネル ネットワーク スタックではさまざまな最適化が行われ、同じハードウェア上の 18 台のサーバーのパフォーマンスは 19 ~ 1.8 Mpps でほぼ 1.9 ~ XNUMX Gbit/s まで向上しました (これらは最大値でした)。しかし、XNUMX 台のサーバーで処理されるトラフィック量の需要は、はるかに速く増加しました。 その結果、さまざまなサーバーの負荷を分散するためのスキームが開発されましたが、これにより、提供されるサービスのセットアップ、維持、品質の維持が複雑になりました。

NFTable

現在、ソフトウェア「シフティング バッグ」のファッショナブルなトレンドは、DPDK と XDP の使用です。 このトピックに関して多くの記事が書かれ、さまざまな講演が行われ、商用製品も登場しています (たとえば、VasExperts の SKAT)。 しかし、通信事業者のプログラミング リソースが限られているため、これらのフレームワークに基づいた「製品」を独自に作成することは非常に困難です。 将来的にこのようなソリューションを運用することはさらに困難になるでしょう;特に診断ツールを開発する必要があるでしょう。 たとえば、DPDK を使用した標準の tcpdump はそのようには機能せず、XDP を使用してワイヤに送り返されたパケットを「認識」しません。 パケット転送をユーザー空間に出力するための新しいテクノロジーについての話題が多い中、それらは注目されませんでした。 レポート и 記事 iptables メンテナの Pablo Neira Ayuso が、nftables でのフロー オフロードの開発について語ります。 この仕組みを詳しく見てみましょう。

主な考え方は、ルーターが XNUMX つのセッションからのパケットをフローの両方向に通過させた場合 (TCP セッションが ESTABLISHED 状態になった場合)、このセッションの後続のパケットをすべてのファイアウォール ルールに通過させる必要がないということです。 これらすべてのチェックは、パケットがさらにルーティングに転送されることで終了します。 実際にルートを選択する必要はありません。このセッション内でどのインターフェイスとどのホストにパケットを送信する必要があるかはすでにわかっています。 残っているのは、この情報を保存し、パケット処理の初期段階でルーティングに使用することだけです。 NAT を実行する場合、nf_conntrack モジュールによって変換されたアドレスとポートの変更に関する情報を追加で保存する必要があります。 はい、もちろん、この場合、iptables のさまざまなポリサーやその他の情報、統計ルールは機能しなくなりますが、別の常駐 NAT や境界などのタスクの枠組みでは、これはそれほど重要ではありません。デバイス間で分散されます。

設定

この関数を使用するには、次のものが必要です。

  • 新しいカーネルを使用してください。 この機能自体はカーネル 4.16 で登場したという事実にもかかわらず、かなり長い間、非常に「未加工」であり、定期的にカーネル パニックを引き起こしていました。 LTS カーネル 2019 と 4.19.90 がリリースされた 5.4.5 年 XNUMX 月頃にすべてが安定しました。
  • かなり新しいバージョンの nftables を使用して、iptables ルールを nftables 形式で書き換えます。 バージョン 0.9.0 で正確に動作します

最初の点で原理的にすべてが明確であれば、主なことは組み立て中に構成にモジュールを含めることを忘れないことです (CONFIG_NFT_FLOW_OFFLOAD=m)。XNUMX 番目の点については説明が必要です。 nftables ルールは、iptables とはまったく異なる方法で記述されます。 Документация ほぼすべてのポイントを明らかにします、特別なポイントもあります コンバーター iptables から nftables へのルール。 したがって、NAT とフロー オフロードの設定例のみを示します。 小さな凡例の例: 、 - これらはトラフィックが通過するネットワーク インターフェイスであり、実際には XNUMX つ以上存在する可能性があります。 、 — 「白」アドレス範囲の開始アドレスと終了アドレス。

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 を実行している 4 台の実サーバーの負荷のスクリーンショットを添付します。 (NAT5) および nftables (NATXNUMX)。

Linux の高速ルーティングと NAT

スクリーンショットには 800 秒あたりのパケット数のグラフはありませんが、これらのサーバーの負荷プロファイルでは平均パケット サイズが約 1.5 バイトであるため、値は最大 30Mpps に達します。 ご覧のとおり、nftables を備えたサーバーには膨大なパフォーマンスの余裕があります。 現在、このサーバーは 3Mpps で最大 40Gbit/s を処理し、空き CPU リソースを持ちながら XNUMXGbps の物理ネットワーク制限を満たすことができることは明らかです。

この資料がサーバーのパフォーマンスを向上させようとしているネットワーク エンジニアに役立つことを願っています。

出所: habr.com

コメントを追加します