公開ゲートウェイがすでに UDP 51820 で WireGuard を、22 番で SSH を動かし、インターネットから到達できる必要のあるアプリケーションを一つ動かしているとします。魅力的に見える規則は全ポートをピアへ転送し、それで完了とします。WireGuard ゲートウェイでは、その規則がトンネル自身の通信を捕まえ、終端しているマシンからあなたを締め出しかねません。公開は制御プレーンの例外を伴うルーティングの判断であり、DNAT の一行ではありません。

公開入口かトンネル入口か、どちらかを選ぶ

サービスを公開することは、インターネットに新しい入口を作ることです。訪問者がトンネルに入らず、ゲートウェイがバックエンドの公開の顔になるため、ピアに VPN のメンバーシップを与えるのとは同じではありません。この違いが規則の対象と証明書を決めます。

管理用インターフェースがその位置に置かれることはほとんどありません。認可された VPN クライアントが到達する管理ページは、攻撃面をトンネルの内側に保ち、ログイン フォームを無差別なスキャンに晒すことを避けます。公開アプリケーションのエンドポイントには、独自の TLS 証明書、認証、レート制限が依然として必要です。暗号化された WireGuard の区間は、訪問者からゲートウェイまでの区間を保護しません。

サービスが本当に公開でなければならないなら、ホスト名、それを覆う証明書、到達を許す訪問者の範囲を書き留めます。この三つが後で規則の形とフィルター方針を決めます。それ以外は公開リスナーでの範囲の拡大です。

入口は一つのポート、出口は一つのバックエンド

公開ポートを一つ、バックエンド サービスを一つ使います。この例では eth0 が公開アドレス 198.51.100.20 を持ち、ゲートウェイのトンネル アドレスは 10.200.0.1、ピアは 10.200.0.7 でアプリケーションを動かします。公開 TCP 9443 はピアの TCP 8443 に写像されます。

iptables -t nat -A PREROUTING -i eth0 -d 198.51.100.20 -p tcp --dport 9443 -j DNAT --to-destination 10.200.0.7:8443
iptables -t nat -A POSTROUTING -o wg0 -d 10.200.0.7 -p tcp --dport 8443 -m conntrack --ctorigdst 198.51.100.20 --ctorigdstport 9443 -j SNAT --to-source 10.200.0.1

SNAT 規則は変換後のバックエンドと元の公開宛先に一致します。そのため同じバックエンド サービスへの別の接続はこの写像の外に残ります。また訪問者のアドレスをピアから隠し、これが送信元を保つルーティング帰路を別設計にするトレードオフです。 iptables 拡張のリファレンス は両方のターゲットとその一致オプションを記述しています。

転送は依然として有効にする必要があり、フィルター チェーンには変換後の宛先とポート、および確立済みの応答を許可する規則が必要です。FORWARD チェーンは DNAT 後の変換済み宛先を見るため、公開アドレスに対して書いた規則は転送パケットに一致しません。許可は公開側ではなく、バックエンドのタプルに対して書いてください。

ピアはゲートウェイのトンネル アドレスからのサービス接続を受け入れ、応答をトンネル経由で返す必要があります。AllowedIPs は実際に受け取る送信元を許可しなければならず、送信元変換のもとではそれがゲートウェイのトンネル アドレスです。この設計に全ピアの広い 0.0.0.0/0 エントリは必要ありません。帰りの通信を落とすのは、そのアドレスをリストから省いたピアか、代わりに訪問者自身のアドレスを転送する送信元保持の設計です。規則に書いた送信元ではなく、ピアが実際に見る送信元を確認してください。

ゲートウェイ自身のリスナーを規則の外に保つ

ポートの一致を、すべての TCP と UDP の宛先を覆う規則に置き換えると、ゲートウェイ自身の WireGuard ソケットがその中に入ります。 宛先変換は、マシンがパケットをローカルと判断する前に行われます。そのため UDP 51820 は、全ピア接続を保持するプロセスではなく、ピアに届くことがあります。規則は正常に読み込まれ、トンネルは死にます。これはピア側から読み解くのが難しい障害です。

SSH、監視エージェント、その他ゲートウェイで動くサービスも同じ露出を持ちます。すべてを転送する規則は制御プレーンと公開アプリケーションを区別せず、締め出しが明らかになるのは変更後の最初の再起動のときです。何でも飲み込む規則は、黙って引き継いだサービスについて警告しません。次回の接続が失敗して初めて気づきます。

広い転送が本当に必要な場合は、何でも飲み込む規則の前に制御ポートを予約するか、公開用に別の公開アドレスを使ってください。後者のほうが制御アドレスが独自の方針を保つためきれいですが、プロバイダーがそのアドレスを渡す必要があります。DNS レコードを足してもアドレスは割り当てられません。

広い TCP と UDP の転送はすべてのプロトコルではありません。ICMP、IPv6、path-MTU のフィードバック、外側の VPN 通信には独自の方針が必要で、TCP と UDP を覆う規則はそれらを既定のチェーンに残します。

規則を書く前にモデルを選ぶ

四つの形でゲートウェイの公開のほとんどを覆えます。選択は動かすサービスの数と、許容できる制御プレーンのリスクによります。次の表は狭いものから広いものへと並べています。

ModelWhat it protectsCostUse when
Narrow port forwardEvery other listener, including the VPNOne rule per serviceFew services, stable ports
Catch-all with reserved portsPorts named in the exception listRule order becomes criticalMany services and disciplined review
Separate public addressControl address fully isolatedProvider must supply the addressHigh-value publication
VPN-only accessNo public entry at allVisitors need the tunnelAdmin interfaces and internal tools

後でサービスが増えると予想しても、狭いモデルから始めてください。監査が最も容易で、狭い規則の集合をレビュー済みの何でも飲み込む規則に変えるほうが、広い規則がどのリスナーを捕まえたかを突き止めるより簡単です。どのモデルを選んでも、規則はファイアウォールの所有者のもとに置いてください。同じチェーンを管理する UFW や nftables の設定の隣に iptables の行を適用すると、起動順に依存して変わる方針が生まれます。

公開と制御経路の両方を証明する

認可された外部クライアントから、承認済みのホスト名とそれに有効な証明書を使って試験します。どのバックエンドが応答したかを確認し、そのうえで無関係な公開ポートが拒否されたままであることを確認します。証明書チェックを無効にしたものは合格した HTTPS 試験ではなく、誤ったバックエンドに届く接続は失敗より悪いものです。

その後、ゲートウェイ自体を検証します。WireGuard ピアを接続し、SSH セッションを開き、監視が依然として報告することを確認します。公開したサービスが動いていても制御プレーンが壊れていることがあるため、両方の確認は同じ変更作業に入れるべきです。一度再起動して規則が期待どおりの順で再適用されることを証明し、その後で公開を撤去し、撤去が追加と実際に対応することを確認します。起動時の大量の追加と不完全な撤去は、一時的な試験が恒久的な穴になる道です。

関連記事