小さな Linux サーバーがホストするアプリケーションのために外向き VPN を動かしており、管理者は依然として隣の机から SSH でそこへ到達したいと考えている。それは妥当な要件であり、通常はポート転送も、プロバイダーのアドレスも、トンネルに穴を開けることも必要としない。必要なのは、VPN クライアントがルーティングテーブルにしたことから受け継ぐのではなく、意図して設計された管理経路だ。

以下の手順は、管理者が同じ LAN にいることを前提とする。リモート管理は別の答えを持つ別の問題だ。

SSH を管理者が使うアドレスに束縛する

リスナーから始める。ss -ltnp | grep :22は sshd が何に束縛されているかを示し、0.0.0.0 のリスナーはトンネルを含むすべてのインターフェースからの接続を受け付ける。LAN アドレスに束縛するほうが狭く、意図が可視化される:ListenAddress 192.168.10.20内のsshd_configに置き、続いて設定テストと再読み込みを行う。そのアドレスの打ち間違いは、アドレスが存在しないと sshd が起動を拒否するため、ワイルドカードより見えやすい。

ホスト鍵の確認とユーザーごとの認証はそのままにしておく。「ローカルネットワークだから」は認証方式ではなく、経路が短いからと鍵の検証を飛ばす管理チャネルは悪用を待つ管理チャネルだ。DHCP 予約や静的アドレスは、目標をサーバーの公開 ID に変えることなく予測可能にする。

LAN ルートをトンネルの外に保つ

192.168.10.0/24 のアドレスを持つホストにはそのプレフィックスの接続ルートがあり、同じテーブル内ではより具体的なルートが VPN のデフォルトに勝つ。だからトンネルが上がってもローカル SSH はしばしばそのまま動き続ける。思い込まずに確認する:ip route get 192.168.10.50はカーネルが使うインターフェースと送信元アドレスを示し、答えはトンネルではなく LAN デバイスであるべきだ。パケットがそもそも届くかどうかはそちらのテーブルが決めるため、管理者のマシンからも確認を繰り返すこと。同じケーブル上の二台のホストが、どちらの方向が到達可能かで食い違うことがある。

前提は二か所で崩れる。ポリシーベースのルーティングルールは、メインテーブルを見る前に、デフォルトがトンネルを指すテーブルへトラフィックを送りうる。ロックダウンや kill switch を備えた VPN クライアントは、ルーティングテーブルが何と言おうと、トンネルに入らないトラフィックを遮断することもある。

ルーティングされた管理 VLAN がもう一つのケースだ。管理者がローカルルーターの背後で 192.168.50.0/24 に座っているなら、サーバーはそのプレフィックスに対して 192.168.10.1 経由の明示的なルートを必要とし、そのルートは再接続を生き延びなければならない。例外は管理プレフィックスに限定すべきで、プライベート範囲への広い例外はトンネルの目的を台無しにする。

ファイアウォールの例外をルールと同じくらい狭くする

ホストがファイアウォールを動かしているなら、SSH は管理送信元からのみ、LAN インターフェース上でのみ許可する。22 番ポートをどこからでも許可するルールは要件より広く、レビューで正当化しにくい。nftables のホストではルールはインターフェースと送信元を一致させた入力チェーンに入り、iptables のホストでは同等物は-iと-sに対する二つの一致の組だ。ルールにはそれが仕える管理者グループをコメントしておき、次の監査がなぜ 22 番ポートが開いているのかを推測せずに済むようにする。

VPN クライアント自身のフィルターも確認する。クライアントによっては設計上ローカルトラフィックを落とすルールをインストールし、クライアント側のドロップの上に正しいファイアウォールルールを置いても何も変わらない。直列の二つのフィルターがどちらにも似ていない障害を生むため、ホストのファイアウォールを編集する前にクライアントの設定を読むこと。

両方の状態をテストする

テストを二回、トンネル接続時と切断時に一回ずつ行う。各状態で、リスナー、ルート、そして管理者のマシンからの実際の SSH ログインを確認する。トンネルが上がっている間だけ機能する経路はローカル管理経路ではなく、それは偶然だ。

次に、SSH セッションを開いたままトンネルを再起動する。生き残ったセッションはルーティングが安定していることを証明し、落ちたセッションはクライアントが再接続時にルートやフィルターを書き換えていることを教えてくれるので、それはインシデントの最中より前に知っておく価値がある。

192.168.10.50 用に書かれたルールは管理者のノート PC が別のサブネットに移ると静かに失敗するため、テストに使った送信元アドレスを記録すること。

復旧経路を runbook に書く

外向き VPN がローカル経路を壊したらどうなるかを今決めておく。コンソールアクセス、二番目の管理アドレス、クライアントを停止する手順の文書化はどれも正当な答えであり、どれもログインが必要なその瞬間に問題を発見するよりましだ。サーバーが遠隔にあるならローカル経路は存在せず、正しい設計は公開ポートを晒すことではなく、別途承認されたリモートアクセス経路か踏み台だ。

文書では、近くにいる管理者のためのローカル SSH と、アプリケーションのトラフィックのための外向きトンネルという二つの役割を分けておく。それらの役割が書き留められていれば、将来どちらかを変更するときに確認すべき場所が明白になり、次の人が VPN のあるサーバーがなぜ今も LAN アドレスで応答するのかを再発見せずに済む。

関連記事