VPN ゲートウェイの両側でキャプチャを取ると、一本のフローが四つのアドレスを示すことがあります。送信元 NAT はパケットがどこから来たと主張するかを書き換え、宛先 NAT はどこへ向かうかを書き換えます。Masquerade は第三の方向ではなく、固定値ではなく出力インターフェースのアドレスを使う送信元 NAT のルールです。三つのうち本当に必要なものを名指しできれば、「VPN が壊れた」というチケットの多くは戻り経路の話に縮みます。

各ルールが書き換えるもの

送信元 NAT は通常 SNAT と書かれ、フローがルーターやゲートウェイを出るときに送信元アドレスを変えます。受け取る側のサービスは翻訳後のアドレスへ応答し、翻訳する箱はその接続のために保持した状態を使って変更を戻します。Linux ではその状態が conntrack にあり、conntrack -L が元の組と応答の組を並べて表示するのはそのためです。

宛先 NAT、つまり DNAT は代わりに宛先を変えます。UDP 51820 の公開アドレス宛てのパケットは、10.8.0.2:51820 の内部 WireGuard サーバーへ書き換えられます。家庭用ルーターやクラウドのロードバランサーが VPN リスナーを公開するのはこの仕組みで、トンネルがその後何を運べるかについては何も語りません。

Masquerade は SNAT の一族です。ルールはアドレスを指定せず、パケットが出るときに出力インターフェースが持つアドレスを使います。Linux はこれに独自のターゲットを与えており、DHCP や PPPoE でアドレスを得る WAN インターフェースでは通常の選択です。

マッピングがどこにあるかで障害の形が決まる

境界ごとに組を記録します。対象はトンネルの前、トンネルの内側、公開インターフェース上で、トンネル内のキャプチャが外側と違うのは正当なことであり、翻訳がどこで起きるかを知らずに両者を比べる人は間違ったホストを追いかけます。

戻りトラフィックはマッピングを保持する機器を通る必要があります。応答が別の経路、二本目のアップリンク、ポリシールート、あるいはあなたのプライベート範囲を知らないプロバイダーを通れば、状態を持つ逆翻訳は起きず、クライアントには片方向のトラフィックが見えます。送信元 NAT を増やしても欠けた戻り経路はほとんど直らず、一本のフローで症状を隠しながら、他のあらゆる場所でアドレスベースのポリシーを壊すことがあります。

もう一つのよくある誤りは、トンネルが経路到達性を作るという期待です。パケットがインターネットへ出るプライベートなクライアントには、有効な出口の取り決めが必要です。デフォルトルート、転送するゲートウェイ、そして通常は公開アドレスへの送信元翻訳であり、暗号化だけではプライベートアドレスは到達可能になりません。

Masquerade か明示的な SNAT か

約束するもので両者を比べます。Masquerade は出口アドレスを選び、明示的な SNAT はそれを固定します。公開アドレスが安定したゲートウェイでは、固定によってログとパートナーの許可リストに一つの予測可能な値が与えられます。動的な WAN リンクでは、固定した SNAT アドレスはリースが変わった瞬間に誤りになり、Masquerade はまさにその場合のために作られました。

範囲は選択と同じくらい重要です。ゲートウェイを出るすべてのパケットに一致し、送信元も宛先も制限しない Masquerade ルールは、そのまま残したかったトラフィックまで翻訳します。他のプライベートネットワークへのトラフィックも含まれるため、ルールはクライアント範囲、意図した宛先、インターフェースに限定してください。

ポリシーベースの IPsec でこれが最も痛く効きます。strongSwan の転送ガイドは IP 転送の有効化とクライアント向けの送信元 NAT ルールの追加を順に説明し、同じ文書が元のアドレスを保つべきトラフィックの除外も扱っています。セキュリティポリシーが一致する前に送信元を翻訳すると、パケットが交渉済みのセレクターに見えなくなるため、トンネルは上がるのにトラフィックは落ち続けます。

遠端が何を見るべきかも決めます。翻訳後、サービスが見るのはゲートウェイであり、個々のクライアントではありません。これにより戻り経路は単純になり、同時にログは平坦化され、クライアントごとの許可リストは無効になります。クライアントのアドレスを保つことが重要なら、テストを通すために隠すのではなく、ルーティングされた戻り経路を設計してください。

Linux ゲートウェイでルールを読む

10.8.0.0/24 にクライアントを持ち、eth0 という名前の WAN インターフェースを持つリモートアクセスゲートウェイでは、転送を有効にしフローを許可するフィルターポリシーを用意してはじめて NAT ルールが役に立ち、iptables 版は両方向を nat テーブルに置きます。

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth0 -p udp --dport 51820 \
  -j DNAT --to-destination 10.8.0.2:51820

nftables の形は同じ二つのフックを、名前付きインターフェースと明示的なチェーンで使います:

nft add rule ip nat postrouting ip saddr 10.8.0.0/24 oifname "eth0" masquerade
nft add rule ip nat prerouting iifname "eth0" udp dport 51820 dnat to 10.8.0.2:51820

どちらの抜粋も、フィルターチェーンが転送されるフローをすでに受け入れていることを前提にしています。NAT は許可のルールではありません。正しく翻訳されたパケットでも一つ先のテーブルで破棄され得るため、conntrack -L で実際のマッピングを確かめ、nft list ruleset か iptables-save -t nat で何が読み込まれているかを確かめ、そのうえで両方のインターフェースでキャプチャし、アドレスが本当に変わるのを見てください。

悪いルールに見える障害の形

ヘアピン通信が古典です。サーバーの公開アドレス経由で内部サーバーに届く内部クライアントには、入りで DNAT、戻りで送信元翻訳が必要であり、なければサーバーはクライアントへ直接応答し、その応答は拒否されます。修正は、その内部から公開への場合に向けたより狭い二本目のルールであり、すべてに対する広い Masquerade ルールではありません。

二重翻訳は静かなほうです。すでにキャリアグレード NAT の背後にいるクライアントは、戻し経路を持てないアドレスでゲートウェイに来るので、もう一度翻訳します。動きはしますが、ログにはプライベートアドレスの二ホップが載り、調査には両方のマッピングが必要です。ポリシーベースの IPsec はさらに三つ目のねじれを加え、ポリシー一致の前に翻訳するとトラフィックが通らないまま SA だけが上がるため、これは NAT ではなくファイアウォールの不具合のように読めます。

さらに、通るテストと失敗する配備があります。NAT コマンドを手で実行して確かめられるのは仕組みであり、設定ではありません。実行時に足したルールは再起動や次のインターフェースイベントで消え、番号が変わるインターフェースに結び付いた Masquerade ルールは遠端が見るアドレスを静かに変え得ます。ルールは所有するファイアウォールの設定に置き、再接続のあとに再試験してください。

ルールを保存する前のチェックリスト

まず方向を名指しし、送信元か、宛先か、両方かを決めます。次に状態を誰が持つべきか、ゲートウェイか、上位のルーターか、IPsec のピアかを決め、応答経路がそこを通って戻ることを確かめます。ルールは本当に意図したクライアント範囲、宛先、インターフェースに限定し、遠端がゲートウェイを見るべきか元のクライアントアドレスを見るべきかを前もって決めます。

ゲートウェイからではなくクライアントから試します。ゲートウェイ上のブラウザーはクライアント翻訳ルールを完全に迂回し得るので、そこで動くページはトンネルについて何も証明しません。クライアント発のリクエストを一つ送り、カウンターと conntrack テーブルを見て、勤務先でどちらかが可能ならトンネルの再接続と WAN アドレスの変更のあとに繰り返します。

関連記事