サイト間 VPN をまたぐ IPv6 プレフィックス委任:チェックリスト
委任された IPv6 プレフィックスをサイト間 VPN 越しにルーティングするための確認項目:プレフィックスマップ、トラフィックセレクタ、転送、MTU、戻り経路、再番号付け。
トンネルを立ち上げるのは簡単な半分にすぎない。サイト間リンクが何日も確立したままなのに、向こう側の LAN の全ホストが沈黙を返し続けるのを見たことがある。原因は、そのゲートウェイ背後の委任プレフィックスがインターフェースに設定されたものの、トンネルにルーティングされていなかったことだ。トンネルのアドレスはその間ずっと ping に応答していたからこそ誰もプレフィックスを見なかったのであり、委任 IPv6 プレフィックスをサイト VPN 越しに通すときに私が確認する順序は、プレフィックスマップ、トラフィックセレクタ、転送とファイアウォール、そして戻り経路だ。
トンネルに触れる前にプレフィックスマップを書く
プレフィックス委任は、要求したルーターにブロックを渡すだけだ。ピアにルートを設定せず、そのブロックを on-link に拡張せず、要求側ルーターの背後に何があるかを遠隔ゲートウェイに伝えない。この三つは自分で設定するものであり、設定ファイルを変える前にアドレス計画に入れておくべきものだ。
サイトごとに、委任プレフィックス、LAN で実際に使う /64、トンネルのアドレス、各ルートの所有者を記録する。プロバイダーはサイト A に 2001:db8:a1::/56 を委任して LAN で 2001:db8:a1:10::/64 を提供させ、サイト B は 2001:db8:b2::/64 を保つ。サイト A がその /64 だけを提供するなら、両端は /56 全体ではなく 2001:db8:a1:10::/64 を指定すべきだ。
ほぼ必ず二つの誤りが現れる。一つは遠隔プレフィックスを on-link として扱い、ブリッジしたりトンネルインターフェースに載せたりして、到達できないホストへの近隣要請にゲートウェイが応答してしまうことだ。もう一つは、/64 を一つしか設定していないのに /56 全体を広告することであり、経路表はそのブロックに到達可能と主張し、アドレスの大半はブラックホールに落ちる。
両端のトラフィックセレクタをルートに合わせる
IKEv2 も WireGuard も不一致のトラフィックを拒否し、その拒否は静かすぎてトンネルは健全に見えたままになる。
strongSwan ではセレクタを明示し、サイト A では次のとおり。
conn a-to-b
left=2001:db8:ff::1
leftsubnet=2001:db8:a1:10::/64
right=2001:db8:ff::2
rightsubnet=2001:db8:b2::/64
auto=startサイト B の conn は二つのサブネットを鏡写しにする。両者が食い違うと、応答側は TS_UNACCEPTABLE で CHILD_SA を拒否するので、IKE_SA が確立していても child SA は上がらない。両側で、設定したサブネットはローカルカーネルがトンネル方向にルーティングする内容と一致しなければならない。
WireGuard は同じ情報を AllowedIPs で運ぶが、一つ癖がある。AllowedIPs は送信時のルートであると同時に受信時の送信元フィルターでもある。サイト B のサイト A 向けピア項目が 2001:db8:a1:10::/64 を欠くと、サイト A からのパケットは有効なハンドシェイクで届いても許可されていないものとして破棄される。これがあの見慣れたパターン、つまりハンドシェイクだけが更新され続けて応答が一切出ていかない状態を生むので、両端を wg show wg0 allowed-ips で比較する。委任が変わるたびにその一覧を再確認し、古い /64 はセッションを生かしたまま新しいプレフィックスを到達不能にする。
まず転送、ファイアウォール、MTU を除外する
次のログ行を読む前に、ゲートウェイがそもそも転送することを確認する。sysctl net.ipv6.conf.all.forwarding は両方で 1 を返す必要があり、トンネルと LAN のインターフェースにも適用する。一つ罠が付いてくるが、転送を有効にすると accept_ra=1 のインターフェースはプロバイダーからのルーター広告を受け付けなくなる。そのためトンネル内では完全にルーティングできても上流のデフォルトルートを失うことがあるので、プロバイダーの RA がまだ必要な場所では accept_ra=2 を設定する。
次にファイアウォール規則がプレフィックスを両方向に許可する必要があり、ICMPv6 も生き残らなければならない。近隣探索、packet-too-big、destination-unreachable は任意でなく、これらを落とすと経路 MTU 探索が壊れて接続は開いたあと最初の大きな応答で止まり、最小限の規則の組は次のとおり。
nft add rule inet filter forward ip6 saddr 2001:db8:a1:10::/64 ip6 daddr 2001:db8:b2::/64 accept
nft add rule inet filter forward ip6 saddr 2001:db8:b2::/64 ip6 daddr 2001:db8:a1:10::/64 accept
nft add rule inet filter forward icmpv6 type { packet-too-big, nd-neighbor-solicit, nd-neighbor-advert } acceptMTU はその背後にある。トンネルは使える MTU を 1500 未満に縮め、IPv6 はすべてのリンクが少なくとも 1280 を運ぶことを要求する。小さな ping は通るのに、SSH セッションは大きなバーストで固まり、/proc/net/snmp6 には返ってこない packet-too-big メッセージが現れる。トンネルの MTU を明示的に設定するか、mangle テーブルで TCP MSS をクランプし、より小さな MTU を通知する ICMPv6 を戻してやる。
トンネルアドレスではなく戻り経路を試す
最も時間を奪う障害は片方向ルーティングだ。各ゲートウェイは遠隔プレフィックスをトンネルへルーティングするが、ホストは自分の /64 がある場所だからという理由で自分のデフォルトゲートウェイ経由で応答する。パケットを宛先まで届けるのは経路の半分にすぎない。
| What you see | Likely cause | First check |
|---|---|---|
| Tunnel up, every host silent | remote prefix not routed into the tunnel | ip -6 route get on both gateways |
| Handshake renews, no replies | source prefix missing from selectors or AllowedIPs | ipsec statusall, wg show allowed-ips |
| Small pings pass, transfers stall | MTU or ICMPv6 packet-too-big filtered | /proc/net/snmp6 counters |
| Old prefix still works | stale /64 left in routes or selectors | delegation lease and route table |
二つのコマンドで大半は片付く。サイト A で ip -6 route get 2001:db8:b2::53 from 2001:db8:a1:10::5 を実行すると、その送信元からの応答が使うインターフェースがわかるので、サイト B で鏡像の確認を行う。次にゲートウェイではなくホストからトラフィックを生成し、両端のカウンターを比較する。
遠隔プレフィックスへの近隣要請がトンネル上に現れるなら、そのプレフィックスは本来 on-link であるべきでない場所で on-link になっているので、ルートを調整する前にそれを直す。プロキシ NDP はブリッジが本当に必要な場合を扱うものであり、ルートの代わりではない。
プレフィックスが自分の下で変わる前提で計画する
プレフィックス委任は委任側と要求側ルーターの間のリースであり、更新で別のブロックが返ることがある。プロバイダー移行後の別の /56 や、トンネルが稼働してきた期間より短いリースであり、古いプレフィックスを名指す場所はルート、セレクタ、AllowedIPs、ファイアウォール規則、DNS レコード、そしてリテラルアドレスを埋め込む監視すべてと一斉に古くなる。メッセージフローは RFC 8415 にある。
プレフィックスが動くと予想される場合は、それに依存しない内部アドレス計画を保ち、境界で変換する。NPTv6 はステートレスな選択肢で、内部ポリシーを読めるまま保つが、これはプレフィックス変換であり魔法の層ではなく、/64 の境界を揃える必要があり、チェックサムは調整され、リテラルアドレスを埋め込むアプリケーションは依然として壊れる。プロバイダーアドレスを端から端まで保つなら、リースの挙動と変更手順をアドレス計画に記録する。
最後に時間に耐えるテストで締める。各 LAN の許可されたホストがもう一方の LAN のサービスに到達し、応答がトンネルを通って戻り、トンネル再起動と委任更新の後でも同じ組が動くことであり、最後の部分が失敗するなら、その設計は一週間もたない状態に依存している。