eth0:0 はラベルでありデバイスではない: SNAT の一致を直す
カウンタがゼロなら、ルールが存在しえないインターフェースを名指ししている。実際のデバイスを読み、-o の一致を直し、そのうえで変換先アドレスを意図的に選ぶ。
VPN クライアントプールに専用のパブリックアドレスを与えるはずの NAT ルールが、ゼロパケットのまま止まっている。同じプールは相変わらず誤った送信元で外に出ており、ルールはたいていアドレスを間違えておらず、インターフェースを間違えている。 -o eth0:0 は、 eth0:0 が eth0上のアドレスに付いたラベルだから、存在しないデバイスを指している。カウンタを見るのがそれを確かめる最速の方法で、修正は調査が思わせるより小さい。
カーネルがそのデバイスを何と呼ぶかを確認する
何かを変える前に、二つの見え方を別々に読む:
ip link show
ip address show dev eth0
ip route get 203.0.113.20
リンク一覧はインターフェースを示す。アドレス一覧は、次のラベルを持つ二つ目の IPv4 アドレスを示すことがある eth0:0、そのアドレスに対応するデバイスはやはり eth0だ。iproute2 のアドレス解説書は、このラベルをアドレスの名前として扱い、二つ目のリンクとしては扱わないが、問題全体はまさにこの区別に懸かっている。
歴史が混乱を説明する。古い ifconfig eth0:0 構文は本当に新しいインターフェースに見えたし、当時のスクリプトは今もそれを参照している。現在のシステムでは、エイリアスはアドレスに付いたラベルであり、ルーティングや netfilter の経路でそれを独立した出口点として扱うものはない。
ルールが実際に何に一致したかを確認する
カウンタは記憶ではなく、ルール一覧と一緒に読む:
iptables -t nat -L POSTROUTING -v -n --line-numbers
一致するトラフィックが流れているのにパケットカウンタがゼロのままのルールは評価されていない。出力インターフェース条件が eth0:0 を名指しするのはよくある原因で、ルートが選んだ出力デバイスは eth0だから、別の名前を探す条件は、カーネルがどの送信元アドレスを選んでも決して真にならない。
条件を実際のデバイスに変え、ラベルはそこから外す。そのデバイスを共有する二つのクライアントプールを区別する必要があるなら、送信元プレフィックスで区別し、存在しえないインターフェース名では区別しない。重ならない -s の一致を持つ二つのルールは読めて試せるが、架空のデバイスを持つ一つのルールはそのどちらでもない。半年後にはプレフィックスだけでは理由が分からないので、各ルールにはプール名を書いたコメントを付ける。
デバイスを選んだルートを確認する
ポストルーティング NAT は、ルートがすでに出力インターフェースを選んだ後に実行されるので ルール内のインターフェースは、ルートが選んだものと同じでなければならない。カーネルに直接尋ねるには ip route get を使い、代表的なクライアントアドレスについて、報告されるデバイスと送信元の両方を読む。
もし答えが eth0を名指すなら、ルールのインターフェース部分は決着している。トンネルデバイスを名指すなら、パケットは編集しているルールに決して届かず、探索はルーティングテーブルとその優先度へ移る。パケットが別の場所から出たために決して一致しないルールは、デバイス名を打ち間違えたルールとカウンタ出力では同じに見える。二つ目はテキストではなくルーティングの変更を必要とするから、何かを編集する前にどちらの状況かを確認する。
変換先の送信元を意図的に選ぶ
デバイスが正しければ、送信元アドレスは別の判断だ。ここに挙げるのは説明用の IPv4 プールと例示アドレスにすぎない:
iptables -t nat -A POSTROUTING -s 10.8.1.0/24 -o eth0 \
-j SNAT --to-source 203.0.113.20
アドレスを --to-source に書き込んでも、誰かがそれをあなた宛てにルーティングしてくれるわけではない。上流プロバイダーかアドレスの所有者が、そのアドレス宛ての応答をこのホストに届ける必要があり、そのアドレスはあなたが使用を許可されているものでなければならない。そうでなければ、ルールは一致して変換し、応答はやはり別の場所へ行く。
送信元アドレスを変えることは、上流リンクを変えることと同じではない。本当の要件が別の物理経路なら、まずルーティングポリシーがその経路を選び、そのうえで SNAT がポリシーが選んだデバイス上で送信元を書き換える。ラベルを増やしても eth0 経路も許可も与えてくれない。
開いたばかりの接続で確認する
既存の接続を使い回さず、新しいクライアント接続を開く。コネクショントラッキングはフロー開始時に記録した変換を保持するので、古いセッションは以前の送信元アドレスを使い続け、正しい新しいルールが壊れて見えることがある。カウンタが増えるのを確かめ、そのうえで変換後の送信元を回線上または遠端で観察する。
一つのインターフェースを共有する複数のプールには、それぞれに明示的な送信元一致と独自の変換アドレスを与え、ファイアウォールの管理設定に置き、評価される順序を記録する。そのうえで確認したことを書き留める: デバイスは ip route getから、動いたカウンタ、相手側が見た送信元だ。その記録は、ラベルの混乱を繰り返さずに次の報告に答える。