tcpdump で IPsec の平文が片方向にしか見えない理由
この非対称性はキャプチャポイントの産物であり、応答経路の故障ではありません。Linux の IPsec ゲートウェイで内側と外側の通信をどこで見るかを示します。
Linux の IPsec ゲートウェイの外側インターフェースで tcpdump を実行すると、同時に二つのものが見えます。受信した ESP フレームと、その直後に続く復号済みの内側パケットです。送信側では ESP しか現れません。そこで「応答が送られていない」あるいは「IPsec が片方向だけ暗号化して他方を忘れている」と結論しがちですが、どちらも正しくありません。
あなたが見ているのはキャプチャポイントです。カーネルは送信パケットをデバイスの送信経路がパケットソケットへ渡す前に変換するため、ソケットは外へ出る内側の形を決して見ません。受信側では、パケットはまず ESP として捕捉され、スタックに再び入るときに非カプセル化されたコピーが見えます。同じ通信を、二つの異なる観測窓から見ているのです。
見えるものはキャプチャポイントが決める
通常のインターフェースでは、AF_PACKET ソケットはデバイス層の近くに位置します。ホストを離れるパケットはまず IPsec の出力処理を通り、そこで内側の TCP セグメントが ESP または UDP-4500 のデータグラムに変わり、その後でようやくこの層に届きます。到着するパケットは、ケーブルから入ってきた時点でまだ暗号化されたままソケットへコピーされ、復号された結果は、スタックがそれをローカルに配送するか転送するときに後から見えるようになります。
この順序が非対称性を完全に説明します。これは方向やポリシー、アプリケーションの挙動についての証拠ではなく、そう扱うと、ずっと正しく送られていた応答を追いかけることになります。これは、異常を作り出しているのがネットワークではなく計測器である、数少ないネットワークの謎の一つです。
フィルタを意図した層に合わせる
tcp port 443 のような式は内側の TCP 接続を選びます。送信側では、ソケットに問い合わせる時点でその接続はすでに ESP になっているため、フィルタは何にも一致しません。保護された通信を数えたいなら、代わりに外側の形でフィルタしてください。生の ESP ならプロトコル 50、NAT トラバーサルがあるなら UDP ポート 4500 です。どちらのフィルタも二つのピア間で比較できるパケット数を返し、それがそもそも数える理由であることがほとんどですが、どちらも内側の要求に応答があったかどうかは教えてくれません。
UDP 4500 のカウントを ESP パケット数として扱わないでください。IKE もそのポートを NAT-T のキープアライブとカプセル化された交換に使うため、この数には測定したかったデータではない通信が含まれます。UDP 500 での最初の IKE 交換には、それが問いなら専用のフィルタが必要です。制御通信とデータを混ぜた数は、帯域の見積もりも未知の幅で狂わせます。別々のカウントは別々の問いに答えます。
フィルタは、それが答える問いの隣に書き留めてください。「ESP がいくつ箱を出たか」と「Web 要求が箱を出たか」は別のフィルタを使う別の測定であり、一つのキャプチャで両方を決めることはできません。その注記がなければ、二人は同じものを数えていなかった数字を比べることになります。
変換の前を見る、後ではない
送信側の平文を見る必要があるなら、観測点を IPsec の出力処理より前へ移してください。NFLOG は Netfilter のフックを与え、そこでルールが選んだパケットをユーザー空間のソケットへコピーでき、tcpdump がそれを読めます。strongSwan のトラフィックダンプのガイドがこの方法を記録しているのは、まさにこの理由からです。
ポリシー一致はルールを、トンネルに入ろうとしている通信だけに限定します。-m policy --pol ipsec --dir out が、箱が送るすべてのパケットを記録する代わりにルールを具体的にします。次に、ロググループを制限付きのキャプチャで読み、小さなスナップショット数とサイズ上限で、診断が通信のアーカイブになることを防いでください。制限付きのキャプチャは、無関係なペイロードを引きずらずにレビュー担当者へ渡しやすいという利点もあります。開始する前に、どれだけ届いたかを見た後ではなく、数を決めてください。
iptables -I OUTPUT 1 -d 10.83.0.44/32 -p tcp --dport 8443 -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5
tcpdump -ni nflog:5 -s 128 -c 20 'host 10.83.0.44 and tcp port 8443'フックはフローに合わせて選んでください。OUTPUT はゲートウェイ自身が生成する通信を対象にし、LAN クライアントからの通過は代わりに FORWARD チェーンを通るため、OUTPUT のルールは決してそれを見ません。上のアドレスとポートは、承認済みのテスト先のためのプレースホルダーです。
観測が証明すること
NFLOG はログの対象であって、受け入れの判断ではありません。そこにパケットが現れるのは、フックに届いてルールに一致したことを示します。後段のフィルタが許可したこと、デバイスが送信したこと、ピアが何かを受け取ったことを示すものではありません。
空のログも同じくらい曖昧です。ルールのパケットカウンタを確認し、方向を確かめ、フローが実際に IPsec ポリシーに一致したことを確かめ、宛先を確かめてください。両方のピアで一致するカウンタだけが、観測を結論に変えます。次に、同じ制御された試行について両方のピアのセキュリティアソシエーションのカウンタを、何が保護され送られたかの権威ある記録として比べてください。
もう一つの罠があります。ここでの「平文」は IPsec の暗号化層の外側という意味です。内側の HTTPS セッションには依然として独自の TLS があり、非カプセル化されたパケットを捕捉してもアプリケーションの TLS は復号されず、そこで読める HTTP が見えるなら、そのアプリケーションは最初から HTTPS を使っていません。
後始末をして両端を比べる
観測が終わったら、挿入したルールをその所有者ごと正確に削除してください。ログ用のルールを残すと、一致するパケットごとに CPU を消費し、気づかないうちにデータ保持の問題を作ります。自分が所有していないチェーンをフラッシュするのではなく、-D を付けてルールを繰り返して削除します。
iptables -D OUTPUT -d 10.83.0.44/32 -p tcp --dport 8443 -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5配備がユーザー空間の IPsec、XFRM インターフェース、ハードウェアオフロードを使っている場合、観測点は移動し、この手順はまったく当てはまらないかもしれません。libipsec の場合、内側の通信を観測する文書化された場所は TUN デバイスです。まず経路を特定し、次に問いに答える点を選び、二つの方向が違って見えるのは変換の反対側を見ているときだけだと想定してください。