OpenVPN 経由のパブリックプレフィックス:戻り経路を直す
ルーティングされたパブリックプレフィックスは OpenVPN の TUN リンクを越えられるが、応答は同じ経路で戻らなければならない。プレフィックスを委任し、パブリックな送信元アドレスを保つ。
トンネルが上がり、クライアントが向こう側に ping を打つ様子を見たあと、VPN の背後にあるはずのパブリックアドレスが別の場所から応答する、あるいはまったく応答しません。この症状は通常、暗号や証明書とは関係ありません。プロバイダーがルーティングしたプレフィックスは IP ルートとして届けられ、それを OpenVPN 経由で運ぶとは、そのルートを二つの階層で再現し、戻り経路で送信元アドレスを保つことです。WAN をブリッジする必要はなく、アドレスをインターフェースに足しても上流ルートはできません。
プレフィックスはまず自分宛てにルーティングされる必要がある
ブロックがどう届けられるかをプロバイダーに確認してください。サーバーの主アドレスにルーティングされたプレフィックスは、プロバイダーが WAN セグメント上で直接届くことを想定するアドレスとは別物です。ここでの設計が機能するのは前者だけです。
プロバイダーが 198.51.100.64/28 を入口サーバーにルーティングしているなら、その範囲のパケットはサーバーに届き、転送しない限りそこで止まります。プロバイダーが代わりにその範囲を上流リンクにブリッジしているなら、サーバーはそのための ARP に応答する必要があり、これは別の問題です。
OpenVPN に触る前に配信モデルを試してください: 外からブロック内のアドレスに ping を打ち、どのインターフェースが受け取るかを見ます。何も届かなければ、どんなトンネル設定も役に立ちません。アドレスが WAN 上で直接応答するなら、プロバイダーはルーティングではなくブリッジしており、以下の設計は当てはまりません。
二つのルーティング階層:カーネルルートと iroute
OpenVPN はプレフィックスを二か所で必要とします。カーネルはプレフィックスがトンネルデバイスに属することを知る必要があり、そうして転送されたパケットはデフォルトルートではなく OpenVPN に入ります。OpenVPN はどの認証済みクライアントがプレフィックスを持つかも知る必要があり、それがクライアント固有ディレクトリの iroute エントリです。
サーバー側のルートは次のようになり、プレフィックスとマスクは割り当てに一致している必要があります:
ip route add 198.51.100.64/28 dev tun0
クライアント固有の設定が所有権を割り当てます。クライアント証明書のコモンネームにちなんだ CCD ファイルに置き、そのディレクトリが実際にサーバーが読むものであることを確認してください:
iroute 198.51.100.64 255.255.255.240
OpenVPN のルーティングされたネットワークに関するドキュメント は両方の階層とその分離の理由を説明しています。iroute のないカーネルルートは所有者のないパケットをトンネルに送り、OpenVPN はそれを破棄します。カーネルルートのない iroute はパケットをサーバーのデフォルト経路に残します。どちらの誤りもクライアント側からは壊れたトンネルに見えます。
サービスアドレスはどこにあるか
委任されたプレフィックスはトンネル自身のアドレスとは別物です。必要ならリンクをプライベート空間から採番し、パブリックなサービスアドレスはサービスが実際に動く場所に置いてください。
サービスをローカルで終端する Linux クライアントでは、ホストアドレスが一つあれば十分です:
ip address add 198.51.100.70/32 dev lo
プレフィックスがさらに VM ホストや別の LAN へルーティングされる場合は、代わりにその下流経路と戻りルートを設定してください。ブロック内の全アドレスを VPN クライアントに割り当てる必要はなく、後で競合を生みます。
戻り経路でパブリックな送信元を保つ
委任されたプレフィックスからの応答はトンネルを出てプロバイダーのルートに届かなければなりません。リモートホストが自分の ISP 経由で送ると、送信元アドレスが偽装に見え、プロバイダーや宛先がそれを捨てます。解決策は 送信元ベースのルールか専用のルーティングテーブル であり、より広い NAT ではありません。それがなければ、サービスはトンネルの相手からは動き、ほかのどこからも失敗します。
入口サーバーでは、広い masquerade ルールがよくある原因です。パブリックな送信元をサーバーの主アドレスに書き換えてしまい、クライアントは本物を決して見ません:
iptables -t nat -S POSTROUTING
NAT は必要とするプライベート VPN クライアントに限定し、委任されたプレフィックスは変換しないでください。そのうえで、デフォルト拒否の転送チェーンがそれを黙って捨てるため、サーバーがそもそもプレフィックスを転送するかを確認してください。
信頼する前に両方向を検証する
検証は一つではなく四つの観察です。プロバイダーのルートが届くこと、カーネルがプレフィックスをトンネルへ送ること、OpenVPN が正しいクライアントに割り当てること、応答がパブリックな送信元を保って戻ることを確認します。各観察には専用のコマンドがあるので、失敗は設計全体ではなく層を指します。設定変更のたびにこの順で実行してください。
カーネルに委任アドレスがどの経路を取るか尋ね、リクエストの実行中にトンネルを観察してください:
ip route get 198.51.100.70
sudo tcpdump -ni tun0 host 198.51.100.70
逆経路フィルタリングは正しいルートを打ち消すことがあります。トンネルと上流リンクの実効設定を確認し、厳格モードでは到着したインターフェースと送信元が一致しないトラフィックを拒否することを覚えておいてください:
sysctl net.ipv4.conf.tun0.rp_filter net.ipv4.conf.eth0.rp_filter
最後に失敗のケースを試します。トンネルを止め、パブリックプレフィックスが通常の上流リンクから漏れないことを確認してください。VPN を戻せば、ホストが公開するポートを広げずにサービスが戻るはずです。