二つのLAN、一つのWireGuardハブ、そして、どのプレフィックスを使うか、各ルーターにどのアドレスを割り当てるか、どのピアがどのサブネットを所有するかという三つの別々の問いに答える必要があるIPv6アドレス計画です。このどれかを間違えると、ハンドシェイクはするが何もルーティングしないトンネルになります。以下の計画は、その順序でプライベートな二拠点設計をたどります。IPv6によるインターネット接続は意図的に提供しません。

プレフィックスの用途を決める

拠点間のプライベートな到達性が目的なら、fd00::/8からのユニークローカルプレフィックスが自然な選択です。各拠点をどのISPが担当しても安定しており、グローバルルーティングテーブルに広告されないため、内部の採番がインターネットへ漏れることはありません。

同じ性質が制約でもあります。ULAには公開の戻り経路がなく、上流はそれをあなたのゲートウェイへルーティングすべきだと知りません。要件にIPv6のインターネット出口が含まれるなら、必要になるのは それをあなたへルーティングしてくれるプロバイダからの割り当てであり、これは独自のプレフィックスサイズを持つ別の設計判断です。

すべての導入に/48が必要だと決めつけないでください。 RFC 6177はエンドサイトの単一の必須サイズから離れ、適切なサイズは運用するネットワーク数に従います。他の組織も使うかもしれないプレフィックスを考案するのではなく、RFC 4193の手順でULAを生成してください。誰も記録しなかったプレフィックスは誰かが再利用するため、どの機器も設定する前に結果をアドレス計画へ書き留めてください。

プレフィックスを役割に分割する

以下の例ではfd7c:2e91:4a00::/48を使い、表は拠点別ではなく各ブロックをどこに書くかで整理しています。値はあくまで例として扱い、何かを導入する前に自分用に生成してください。

Where it is writtenWhat appears thereBlock usedWhat it establishes
Hub wg0.conf, interface addressA single host address on the tunnelfd7c:2e91:4a00:ff00::1/128The hub's own tunnel identity
Hub wg0.conf, Site A peerTwo ranges in one AllowedIPs line::2/128 and :10::/64That A owns its tunnel address and its LAN
Hub wg0.conf, Site B peerTwo ranges in one AllowedIPs line::3/128 and :20::/64That B owns its tunnel address and its LAN
Site A wg0.conf, interface addressA single host address on the tunnelfd7c:2e91:4a00:ff00::2/128A's identity as the hub sees it
Site B wg0.conf, interface addressA single host address on the tunnelfd7c:2e91:4a00:ff00::3/128B's identity as the hub sees it

LANブロックが/64なのは、通常のSLAACが64ビットのインターフェース識別子を前提とするためです。LANをより小さなブロックに分割すると多くのホストでその前提が崩れ、プライベート計画ではアドレス節約に対して運用コストが見合いません。両方のLANブロックは/48の中央から取り、低い範囲は後続の拠点のために空けておきます。

トンネルアドレスは管理上の枠であり、リンク上のネットワークではありません。各インターフェースはそこから/128を一つだけ受け取るので、トンネル上で共有サブネットを前提とするホストはなく、不要な場所で近隣探索も動きません。役割は重複させず、組織のアドレス計画に記録して、後の拠点がブロックを再利用しないようにしてください。

各ルーターに一つのトンネルアドレスを与える

ルーターごとに/128を一つ割り当て、稼働中のハブの既存の鍵とエンドポイントはそのまま維持します。以下の三つの値はホスト部分だけが異なります。

Hub:    Address = fd7c:2e91:4a00:ff00::1/128
Site A: Address = fd7c:2e91:4a00:ff00::2/128
Site B: Address = fd7c:2e91:4a00:ff00::3/128

この/128はそのインターフェースに割り当てられた単一のアドレスを表します。ピアがいくつの宛先をルーティングできるかは、到達性がインターフェースのプレフィックスではなくAllowedIPsで表現されるため、示しません。

各拠点ルーターには、自分のLANブロック内のアドレスと、それを配布する手段(通常はSLAAC向けのルーター広告)も必要です。WireGuardはその広告を代わりに送ることも、二つのLANをブリッジすることもしません。拠点ルーターは両方向のルーターです。

サブネットの所有権をAllowedIPsに置く

サイトAに対するハブのピアエントリは、AのトンネルアドレスとAのLANを所有しており、この組み合わせが所有権の表明のすべてです。そのピアセクションで拠点を説明する必要は他にありません。

AllowedIPs = fd7c:2e91:4a00:ff00::2/128, fd7c:2e91:4a00:10::/64

サイトBのピアエントリは対応する組み合わせを所有しており、ここでは簡潔さより対称性が重要です。二行を並べて読めば、所有の分担が一目で見えてきます。

AllowedIPs = fd7c:2e91:4a00:ff00::3/128, fd7c:2e91:4a00:20::/64

これは一つのピアを奪い合う二つのリストではなく、別々の二つのピアセクションです。WireGuardはAllowedIPsを両方向に使い、送信先に対してピアを選び、復号したピアに割り当てた範囲と送信元が一致しない受信パケットを拒否します。両方のピアに/48全体を与えると、この二つ目の検査が無効になり、どの拠点がどのブロックを所有するかがぼやけます。この区別があるからこそ、誤った送信元アドレスは黙って受け入れられず、見える形で現れます。

各拠点に必要なのは、ハブのピア経由で到達できる宛先だけで、サイトAはハブのアドレス、サイトBのトンネルアドレスとBのLANを列挙し、サイトBはその逆の集合を列挙します。リストが非対称なのは意図的で、各ルーターはトポロジーの異なる側を見ているからです。他の拠点の設定ではなくアドレス計画から書くことで、古い範囲が再採番を生き延びるのを防げます。

wg-quickでは、これらの範囲がルートも作成します。systemd-networkdや手動設定では、そうしないとカーネルが決して送らないパケットをトンネルが運ぶことになるため、同等のルートを自分で追加してください。

転送を完了し、両方向をテストする

ハブと両方の拠点ルーターでIPv6転送を有効にし、転送ポリシーで必要な拠点間サービスを許可します。ICMPv6 Packet Too Bigメッセージは、捨てるとパスMTU探索が壊れてアプリケーション障害のように見える大容量転送の停止が起きるため、使える状態に保ってください。ファイアウォールの許可なしに転送するハブは、ルーティングとトンネルの間でパケットを落とします。トンネルは上がったまま一部のフローだけが死ぬため、この障害モードは知っておく価値があります。

sysctl net.ipv6.conf.all.forwarding
ip -6 route
ping -6 -c 3 fd7c:2e91:4a00:20::1

サイトAのホストからサイトBのホストへ、そして逆方向へテストします。ハブのトンネルアドレスへのpingは最初のホップだけを試すので、LANのルートが誤っていても成功します。計画を証明するのはホスト間のフローです。

外側のWireGuard接続はIPv4上で動かしつつ内側のトラフィックをIPv6にでき、この独立性は移行時に役立ちます。後でグローバルなIPv6出口を追加する場合は、プロバイダの割り当て、送信元アドレスの選択、戻りルーティングを新しい設計ステップとして見直す一方、上記のプライベート計画は拠点間トラフィックには引き続き有効です。

関連記事