ある朝を費やしたのは、きれいに立ち上がり、支社が本社のファイルサーバーに到達できる一方で、本社から支社へ開く接続はすべて最初の SYN で死ぬトンネルでした。SA は上がっており、トンネルのカウンターは増え、ハンドシェイクが問題だったことはありません。応答はトンネルが覆わない場所へルーティングされていたのであり、その選択は遠端側に属します。サイト間 VPN は、ホストがゲートウェイに渡すパケットだけを運び、その選択はホストごとに、方向ごとに、それぞれのルーティングテーブルから行われます。

両方向は別々にルーティングされる

IP は会話の方向を記憶しません。パケットを送る各ホストは自分の最長プレフィックス検索を行い、次のホップを一つ選び、その判断を忘れます。要求と応答は、たまたま同じ接続に属する無関係な二つのパケットであり、トンネルはどちらが使っても使わなくてもよい一つのホップです。IKE の交換が教えるのは、どのプレフィックスを暗号化してよいかという合意だけで、あなたのサブネットへの到達方法ではありません。

その合意が第二の関門です。strongSwan ではトラフィックセレクターが leftsubnet と rightsubnet で、送信元または宛先が合意した組の外にあるパケットは、ルーティングテーブルが何と言おうと暗号化されません。トンネルにルーティングされていてもセレクターに無いプレフィックスは静かな片方向障害で、ルートは正しく見え、パケットは依然として平文で出るか捨てられ、charon のログだけが文句を言います。

遠端のホストはあなたのトンネルを何も知らない

遠端の LAN の内部では、応答はあなたのクライアント宛ての普通のパケットです。宛先ホストは IPsec ヘッダーを見ず、VPN ゲートウェイを選ぶ理由もなく、あなたのプレフィックスを引き、デフォルトルートより具体的なものが無いのでそれに従います。デフォルトが中核のファイアウォールを指すなら、そのファイアウォールはトンネルへ戻るルートを持つか持たないかです。持たない場合、静かな破棄、ICMP unreachable、あるいはインターネット側のインターフェースから出て消える応答が返ります。

二つ目のインターフェースがあれば、ルートが存在していてもこれは壊れます。別の VLAN に管理リンクを持つ NAS、バックアップ uplink を持つサーバー、ある送信元範囲を二つ目のテーブルへ送るポリシールール、これらのどれもが応答を横取りできます。Linux では、ip rule show と ip route show table all が、既定の一覧では見えないルールとテーブルを表示します。

応答を送る機械で判断を読みます

何かを変える前にカーネルに尋ね、送信元に依存するルールが答えを変えるので送信元アドレスを渡してください。

ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"

出力は送出インターフェースと次のホップを示します。そのインターフェースが VPN ゲートウェイ側でなければ、欠陥は見つかっており、残る作業はルートをどこに置くかの選択です。ゲートウェイからの ping は、遠端のホストが位置づけられるアドレスで答えているのであって、あなたのノート PC のアドレスではないため、ここではほとんど証明になりません。

Windows では、判断には Find-NetRoute -RemoteIPAddress 10.10.5.10、テーブルには Get-NetRoute が相当します。既定より高いメトリックを持つ New-NetRoute で追加したルートは静かに負けるので、エントリではなくメトリック列を読んでください。次にパケットで確かめるなら、遠端の LAN インターフェースで tcpdump -ni any "host 10.10.5.10 and tcp port 445" が要求を、トンネル側で同じフィルターが応答が戻ったかどうかを示します。要求が見えて応答が無ければ応答は別の場所へルーティングされたか捨てられており、誤ったインターフェースに応答が出れば、ルートに触る前に犯人が分かります。

サーバーのゲートウェイが VPN の終端でない場合

多くの拠点は、サーバーと集約装置の間にファイアウォールを置きます。そのファイアウォールは応答を転送するので、あなたのクライアントのプレフィックスに対する VPN ゲートウェイ向きのルートと、両方向の転送ポリシーが必要です。ステートフルな機器はさらに悪化させ、要求は許可された LAN ホストからファイアウォールを越え、応答は今や別方向から届き、コネクション追跡のエントリが一致しなくなるため、パケットは拒否ではなく不正として破棄されます。ポリシーログが空に見えるのにトラフィックが消えるのはそのためです。

ゲートウェイには独自の第二のフィルターがあります。Linux の逆経路フィルタリングは、届いたインターフェースから送信元に到達できないパケットを破棄しますが、これはまさに正当な非対称な戻り経路の形です。strongSwan の転送ガイド がまさにその理由で net.ipv4.ip_forward と緩めた net.ipv4.conf.all.rp_filter を求めています。どちらかのゲートウェイで厳格な値 1 にすると、正しいルートが静かに壊れ、どこを見るべきか分かっていれば nstat -az が破棄を示します。

SymptomWhere the reply is most likely lost
Gateway ping works, LAN host silentSource address the far host cannot place in its table
SYN arrives, no SYN-ACK, tunnel counters flatNo route to the client prefix on the far host or its gateway
Reply counted on the internet-facing interfaceDefault route or policy rule on the far host
Firewall reports invalid stateAsymmetric path through a stateful device
Worked until a link failed overNew path is asymmetric, or rp_filter now rejects it

ルーティングするか変換するかして、両方向で確認する

二つの修復は等価ではありません。ルートを足すとクライアントのアドレスはそのまま残るので、送信元ベースのルール、監査ログ、呼び出し元を記録するアプリは動き続けますが、代償は、判断を行う各ホップにルートが必要になることで、間違えられる場所が増えます。遠端ゲートウェイでのマスカレード は、応答がゲートウェイ自身宛てになったことで戻り経路を一つのホップに縮め、どのクライアントが何をしたかを隠します。

iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE

クライアントがゲートウェイのアドレスとして見え始めると送信元ベースの ACL はそれらを区別できなくなり、応答をトンネルへ書き戻すために conntrack が対応付けを保持しなければならないので、意図して選んでください。セレクターが今もクライアントのプレフィックスを除外しているなら、要求がトンネルに入っていないので NAT は何も変えません。

直ったと呼ぶ前に、応答を送るホストのルート、それを転送する各ホップのルート、両方のプレフィックスを覆うセレクター、そして応答が期待した送信元でトンネルに入ることを示すキャプチャの四つを順に確認してください。そのうえで、もう一方の拠点からテストを繰り返します。片方向が通るのは半開きの設計であり、二つ目の方向はたいてい、いま直したのとは別の理由で失敗します。

関連記事