あるサービスが 127.0.0.1:1080 で待ち受けている。DNAT ルールは受信トラフィックをそのアドレスへ向けるが、接続は失敗する。サービスが正常で NAT ルールが一致していても起こり得る。IPv4 のループバックアドレスはルーティング上で特別な扱いを受けるからだ。

Linux の route_localnet は、ルーティング時に 127/8 のアドレスを火星アドレスとして扱うかどうかを制御する。既定値は通常のループバック境界を保つ。特定インターフェース向けの例外は、意図的なローカル転送の設計に関係することがある。

これが、別のマシンで動いたルールが、コピーしていない sysctl に依存し得る理由である。ただし、その設定をどこでも有効にしてよい理由にはならない。

セキュリティ上の前提は経路とともに変わる

ループバックへの束縛は、補助プログラムに独立したクライアント認証がないために使われることが多い。別のインターフェースから届くトラフィックをそこへルーティングできるなら、束縛アドレスだけでは到達可能な相手を表さなくなる。実際のルールセットで入力元、宛先、ポートを制限し、該当する場合はループバックの送信元や宛先を名乗るトラフィックも含めて考える。

サービスを含むネットワーク名前空間を確認する。コンテナのループバックはホストのループバックではなく、ホスト側インターフェースの設定を変えてもコンテナ内に待ち受けが自動で生まれるわけではない。

rp_filter は送信元経路の検証という別の問いに答えるものだ。これを全体で無効にすることは、ループバックのルーティングを理解する代わりにはならない。同様に ip_nonlocal_bind はソケットを非ローカルアドレスに束縛する話であり、この DNAT 経路を正しくする話ではない。

最後に、転送先のプロトコルが待ち受け側に合っていなければならない。生の HTTP や TLS を SOCKS ポートへ送るには依然として変換役が必要であり、ルーティングの例外は欠けたネゴシエーションを補えない。

関連記事