現代のインフラに「NATインスタンス」を再定義する:iptablesで操るパケットの深淵
クラウドネイティブな時代において、マネージドな NAT Gateway は確かに便利だ。しかし、帯域コストの増大や、特定のフローに対するきめ細やかなパケット制御、あるいは特定のセキュリティコンプライアンス要件に直面したとき、我々エンジニアは再び Linux カーネルの深淵、すなわち Netfilter と iptables の世界へ回帰することになる。
今回は、単なるルーティングの解説ではない。パケットがカーネル内でどのように「変身」し、そこにあるボトルネックをどう削ぎ落とすか。真のインフラアーキテクトが知るべき、SNAT/MASQUERADE の深層心理を紐解こう。
—
1. パケットの書き換え:SNATとMASQUERADEの境界線
プライベートサブネットのインスタンスが外部へと通信する際、パケットの送信元IPアドレス(Source IP)をNATインスタンスのパブリックIPへと書き換える必要がある。ここで活躍するのが iptables の nat テーブルだ。
よく混同されるが、SNAT と MASQUERADE は本質的に異なる。
- SNAT: 出力先IPが固定されている場合に使用。パフォーマンス面でわずかに有利。
- MASQUERADE: インターフェースのIPが変動する場合(DHCPなど)に最適。接続が切断されるとコネクション追跡テーブル(
conntrack)の関連付けがリセットされる性質がある。
実装の勘所
以下は、eth0 を経由して外へ出るパケットを MASQUERADE するための基本的な設定だ。
# 1. カーネルのIP転送を有効化(これがなければパケットはそこで死ぬ)
sysctl -w net.ipv4.ip_forward=1
# 2. POSTROUTINGチェーンでMASQUERADEを適用
# -o eth0: 出力インターフェースを指定
# MASQUERADE: 送信元IPをeth0のIPに書き換え、ポート番号を自動調整
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 3. 戻りのパケットに対する許可(conntrackの恩恵を受ける)
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
—
2. 性能の極限を追求する:TCPバッファとconntrackのチューニング
NATインスタンスが「詰まる」最大の原因は、実はCPU負荷よりも conntrack のハッシュテーブル制限や、TCPスタックのメモリ不足にあることが多い。高負荷な環境では、以下のカーネルパラメータ調整が必須だ。
# conntrackテーブルのサイズを拡大(デフォルトでは数万程度でパンクする)
sysctl -w net.netfilter.nf_conntrack_max=1048576
# TCPバッファの最適化(RTTが大きく帯域が広い環境でのスループット向上)
# 最小値、デフォルト値、最大値を設定
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
# TIME_WAIT状態のソケットを再利用可能に
sysctl -w net.ipv4.tcp_tw_reuse=1
特に nf_conntrack_max が枯渇すると、カーネルは新規のコネクションを受け付けなくなり、パケットロスが連鎖的に発生する。dmesg で nf_conntrack: table full の文字を見たなら、それは設計の敗北を意味する。
—
3. セキュリティとパフォーマンスのトレードオフ:TLSとヘッダー
NATを通過するトラフィックが TLS であれば、NATインスタンスはパケットの中身を解読できない。しかし、MSS Clamping という技術を知っているか?
パス(MTU)の途中でパケットがフラグメンテーションを起こすと、再送処理でレイテンシが跳ね上がる。これを防ぐために、TCPの SYN パケット内の MSS(Maximum Segment Size)オプションを強制的に書き換えるのだ。
# MTU 1500からIP/TCPヘッダー分を引いた1460にMSSを固定
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
これは特に VPN トンネルや複雑なオーバーレイネットワークを経由する際、ハンドシェイクのタイムアウトを防ぐ強力な武器となる。
—
4. 現場の教訓:可視化なき最適化は無意味である
最後に、SREとしての直言を贈ろう。iptables は強力だが、ブラックボックス化しやすい。トラブルシューティングの際、パケットがどこでドロップされたかを特定するために、以下のコマンドを常に手元に置いておくべきだ。
# 特定のポートに対するトラフィックを追跡する
iptables -t nat -L POSTROUTING -v -n
# conntrackの現在数を確認する
cat /proc/sys/net/netfilter/nf_conntrack_count
NATインスタンスは、単なる「通り道」ではない。そこはパケットの交通整理が行われ、セキュリティの防壁が築かれ、そしてTCP/IPの不完全さを補完する最後の聖域だ。教科書的な設定に満足せず、カーネルの挙動を理解し、自身の環境に最適化した「魂の入った」ネットワークを構築してほしい。
それができるエンジニアこそが、真の意味でクラウドの恩恵をコントロールできると言えるだろう。
コメント