なぜ家庭の NAT は VPN インターフェースを守らないのか
家庭のルーターはトンネルを転送しますが、復号されたパケットを判断するのはホストです。リスナー、内部経路、受信ポリシーを分けて読みます。
家庭のルーターの背後にありポート転送をしていないノート PC でも、VPN 経由で届く SSH 接続は依然として受け入れます。これは矛盾ではなく、別々の二台の機器が別々の二つのパケットを判断しているからです。ルーターは暗号化されたトランスポートを転送し、ホストは自分のトンネルインターフェースに届いた復号済みパケットをどう扱うかを決めます。この二つの判断を切り離して考えることが、この演習のすべてです。
ルーターはトンネルを転送し、ホストはパケットを判断する
一つのルールを見る前に、遠隔の送信元からサービスまでの経路を描きます。外側の区間は VPN トランスポートで、ルーターとゲートウェイが扱います。内側の区間は、端点がトンネル層を外し、ホストが自分の VPN アドレス宛てのパケットを受け取ったときに始まります。
この二つの区間を合わせると、ホストが下す判断の手柄はルーターに帰ります。ポート転送のページやルーターのログは外側の会話しか記述しておらず、どちらもホストがどの復号済みトラフィックを受け入れるかは言いません。ホストは内部パケットに自分の受信ポリシーを適用し、インターフェースに届くどのパケットに対しても同じです。露出の問題が実際に決まるのは、そのポリシーの中です。
ワイルドカードのリスナーは公開サービスではない
Linux で INADDR_ANY にバインドするというのは、すべてのローカルアドレスを意味し、したがってサービスは自分が一度も名指ししていないトンネルインターフェースで応答できます。IP ソケットのリファレンスはそのバインドを説明しており、リスナー一覧から結論を出す前に読む価値があります。ワイルドカードの項目はソケットについての事実であり、到達可能性についての主張ではありません。
下の二行は同じサービスの二つの異なるバインドで、その違いがインターフェースが重要かという問いへの答えのすべてです。まずソケットがどのアドレスに座っているかを読みます。
ss -lntp "sport = :22"
LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=812,fd=3))
LISTEN 0 4096 10.8.0.6:22 0.0.0.0:* users:(("sshd",pid=812,fd=4))
そのポートに届きうる配置を名指しする
三つの配置がそのインターフェースにパケットを載せ、それぞれ所有者が違います。正しいものを名指しすることが、誰がポリシーを変えるべきかを決めます。
| Arrangement | What reaches the port | Where the decision lives |
|---|---|---|
| Another permitted VPN peer | A packet from the same tunnel subnet | Gateway forwarding policy and host input rules |
| A deliberate public forward | Traffic the gateway publishes on purpose | Gateway service definition |
| A subnet routed behind the gateway | Client traffic from the far side | Gateway route and host input rules |
公開の出口アドレスを示すブラウザの結果は、三つのどれについても何も言いません——出ていくトラフィックがどう出るかを述べており、入ってくるトラフィックに何が許されるかではないからです。代わりに、リスナーとサービスのログにある送信元アドレスから逆にたどります。送信元が別のトンネルピアなら、興味深い文書はゲートウェイのポリシーです。変換されたアドレスなら、ルールを変える前に変換を見つけます。
サービスを意図した経路に限定する
SSH が管理経路からだけ必要なら、その経路を送信元範囲とインターフェースとして書き留めます。その後、ホストの受信ルールをネットワーク名ではなく、インターフェース、宛先、送信元で限定します——私的に見える名前が任意のアドレスを表しうるからです。次の問題を直す人のために経路を残します。
nft add rule inet filter input iifname "tun0" ip saddr 10.8.0.0/24 tcp dport 22 accept
nft list chain inet filter input
トンネルインターフェースと管理範囲を名指しするルールは、意図を一か所で述べます。Wi-Fi ネットワーク向けに書かれたルールと比べてください——後者は復号済みのトンネルトラフィックについて何も言いません。二つの層が食い違うとき、パケットが出会うのはホストのポリシーです。
ログインとパッチはそのままの場所に置き、ポートに届くことは、それを使う許可を得ることと同じではありませんでした。未知の送信元についてはアドレスファミリーと時刻を記録し、機能や脆弱性のせいにする前に調べます。トンネルピアをすべて通すルールは、管理サブネットを通すルールとは別の設計であり、どちらを意図したかをログの行が教えてくれることはありません。
成功一件と拒否一件で修正を受け入れる
両方の半分を証明します——承認された接続が一つ成功し、除外された経路が一つ拒否されることです。拒否こそが見落とされがちな半分で、ルールが許可の既定値の隣に座っているのではなく働いていることを示します。あれこれ考えるのではなく、除外された側から試します。
再接続のあとでこの組を繰り返します——別のインターフェース名で戻ってきたトンネルは、古い名前に限定されたルールを静かに迂回しうるからです。重要な境界は、ホストが実際に受け取るパケットに適用する境界です。