ひとつのOpenVPNポート、三つのサービス:内部ポートが重要な理由
ひとつのトンネル、三つのサービス、ひとつの公開ポート。外側のVPNリスナーと内側のアプリケーションポートを分け、それぞれの内側の許可を個別に試してください。
ひとつのSSHセッション、ひとつのWebアプリ、ひとつの名前解決は、ポートを奪い合うことなくひとつのVPN接続を共有できます。クライアントはゲートウェイへの暗号化されたフローをひとつだけ構築し、アプリケーションの会話はすべてその中を流れます。外側では、トンネル自身のトランスポートとポートだけが見えます。内側では、各サービスが自分のポートを保ち、なおかつ自分の許可を必要とします。
外側のフローが運ぶものと、隠すもの
クライアントは、パケットがマシンを離れる前に、トンネルのトランスポートで包みます。その外側のフローには宛先ポートがひとつだけあり、VPNの設定時に固定されます。包みの内側では、元の各パケットが対象サービスのアドレスとポートを保ちます。ゲートウェイは包みを外して内側のヘッダーでルーティングするため、宛先にはネットワークから到着する普通のクライアントが見えます。
したがって、WANインターフェースでのキャプチャには会話がひとつだけ映り、三つではありません。内側のポートはカプセル化を解除した後にだけ現れます。だからこそ、ファイアウォールの開口部がひとつあれば、SSH、HTTPS、DNSを同時に運べます。
# WAN side: one outer tuple, whatever the inner services are
tcpdump -ni wan0 'udp port 443'
# tunnel side: the inner tuples appear after decapsulation
tcpdump -ni tun0
TUN/TAPのドキュメント は、ルーティングされたTUNデバイスがカーネルとユーザー空間のプロセスの間でIPパケットを受け渡す仕組みを説明しています。この受け渡しがあるからこそ、内側のヘッダーがゲートウェイのルーティングとファイアウォールのコードから見えるのです。また、外側のポートがどのサービスを許可しているかを何も語らない理由も説明しています。
NATの転送はリスナーに属し、アプリケーションには属しません
IPv4のNATの背後にある自己ホスト型ゲートウェイには、内向きの変換がひとつ必要です。公開アドレスとポートをVPNリスナーにマッピングします。トンネルの利用者が到達するからという理由だけで、SSH、HTTPS、DNSにルールが必要になるわけではありません。それらのポートを公開すれば、トンネルがすでに保護しているサービスを露出させてしまいます。転送ルールが表すのはリスナーの到達性であり、内側の何かに対する許可ではありません。
逆も成り立ちます。トンネルのポートを開いても他の何も露出しないため、トンネル経由でしか届かないサービスは公開表面を閉じたままにできます。この分離こそが、そもそもサービスを非公開に保つ理由です。
アクセスを実際に決めるのは内側のポリシーです
暗号化は経路を守りますが、宛先を許可するものではありません。クライアントのルートはどのプレフィックスがトンネルに入るかを選び、ゲートウェイの転送ポリシーはパケットがトンネルを出られるかを決め、宛先のファイアウォールとログインがサービスが応答するかを決めます。DNSが最も分かりやすい例です。問い合わせを運んでも、リゾルバーがあなたのクライアントプールからの問い合わせを受け入れるようになるわけではありません。各層は独立に「いいえ」と言えます。
トンネル経由で各サービスを個別に試してください。解決に成功してもWebポートについては何も分からず、Webリクエストに成功してもSSHについては何も分かりません。
dig @10.40.0.53 app.corp.example
nc -vz 10.40.0.10 8443
ssh -p 2222 [email protected]
トンネルが上がっているのにすべて失敗するときは、まずクライアントのルートテーブルを読んでください。ひとつのサービスだけ失敗して他が動くときは、障害はその宛先にあります。この二つの観察は別々の担当者を指しており、混ぜると時間を浪費します。
WireGuardも同じ線を引いています
WireGuardは外側のリスナーを ListenPort という名前で呼び、内側のアプリケーションは必要などんなサービスポートでも使います。 AllowedIPs はルーティングされたプレフィックスの集合であり、許可されたサービスポートの一覧ではありません。これをポートの許可リストとして読むと、トンネルの実際の動作と合わないルールが生まれます。名前は違いますが、層の分け方は同じです。
サービスがエンドポイント自体で動く場合はローカル入力ポリシーで、そのエンドポイントの背後にある場合は転送ポリシーで許可してください。この区別が、どのルールセットがパケットを見るかを決めます。
一般的な形は、ひとつの外側トランスポートと多数の内側の会話です。複数の外側のやり取りや別のIPプロトコルを必要とする製品は、単一公開ポートというパターンがこの設計を表すのであって、すべてのVPNを表すのではないことを思い出させてくれます。