クラウドポリシーで VPN ポート を許可しても、ハンドシェイクがインスタンス上で死ぬことがある。ゲストは独自のフィルターと独自のリスナーバインディングを動かしており、どちらもクラウドが承認したものを捨ててしまえる。逆も起こる。ホスト側のルールがポートを許可していても、上位のポリシーが先に落とす場合だ。所有者が二つ、ルールセットが二つ、パケットの経路は一つ。最も怪しい層で推測するのではなく、順番にたどろう。

エッジから内側へたどる

順序は決まっている。公開エンドポイント、リソースのインターフェース、関連付けられたクラウドポリシー、ゲストのアドレス、プロセスのリスナー、ローカルの入力ルール。各段階はパケットを通すか調査を終わらせる。だからゲストから始めると最も時間を無駄にする。

転送されたクライアントのトラフィックは別の段階で、トンネルをデカプセル化した後に調べる。クラウド層が見るのは外側のトンネルだけなので、接続を承認しても内側のサービス要求とは何の関係もないことがある。接続はできるのに内部ホストに届かないトンネルは、通常は閉じたポートではなく転送を示している。

ゲストに触る前にクラウドポリシーを読む

VPN ポートの受信ルール、そのプロトコル、テストクライアントに合う送信元の範囲を確認する。サブネットのアクセス制御リストも見る。独自のルールと既定値を持つ二つ目のフィルターだ。パケットがインスタンスに届く前に、両方がそのフローを許可していなければならない。片方で許可し、もう片方で拒否しているのが、この不具合の典型的な形である。

範囲は意味を持つところまで狭める。VPN ポートをインターネット全体に開けるのは証明は簡単で防御は難しい。一方、一つのアドレスに固定したルールは、テストクライアントがネットワークを移ると破綻する。ルールの識別子とポリシーの所有者を記録しておけば、次の変更を人までたどれる。

リスナーを確認し、次に入力チェーンを見る

インスタンス上で、VPN プロセスが想定したアドレスとポートにバインドされているか確認する。たとえば ss -lntp 'sport = :1194' を使う。127.0.0.1 にだけバインドされたデーモンはローカルのクライアントを受け付けるが、トンネル経由では何も受け付けない。外から見ると、これはフィルターされたポートとまったく同じに見える。

次に、変更に使うのと同じ構文でローカルのルールを読む。たとえば iptables -S INPUT や nft list chain inet filter input だ。ファイルに書かれたまま一度も読み込まれていないルールや、対応する許可のない既定の破棄は、パケットを黙って捨てる。転送するゲートウェイなら、転送と逆経路の設定も確認する。インスタンス宛てではなくインスタンス経由でルーティングされるパケットの扱いを決めるのは、これらの設定である。

一方の層はステートフル、次の層はステートレス

セキュリティグループは許可したフローを記憶し、応答を戻す。サブネットのアクセス制御リストや多くのホストファイアウォールはその状態を持たないので、外向きの方向だけを覆うルールは要求を通し、応答を捨てる。第二層のルールを読まずに、層の間で戻りトラフィックの前提を持ち込んではならない(second layer's rule)。

アカウント内のすべてのルールを読むより、カウンターのほうが速く決着する。増えているカウンターはパケットがそこに届いて捨てられたことを意味し、ゼロで止まっているカウンターはそこまで届いていないことを意味する。ルールをカウンター付きで読み込んだ場合、iptables -vnL INPUT と nft list ruleset がその数値を示す。

生きたセッションではなく、新しいセッションで試す

表示を比べている間は接続元のネットワークとテスト用プロファイルを変えず、変更のたびに新しい接続を開く。443 のウェブコンソールに届いても、VPN デーモンが 1194 にバインドされているかは分からない。必要なポートを試すこと。既存のセッションはここでは最悪の証人である。新しいログインがすべて拒否される間も、それは動き続ける。

リモートのポリシーを編集する前に、変更する経路に依存しない戻り道を用意する。そのうえで VPN のテストと並行して二つ目の管理セッションを開く。先に確立したセッションは、新しい接続を遮断するルールより長く生き残ることがある。両方のポリシーの所有者を記録し、再構築で経路の半分が復元されないようにする。両方の層が一致しているのにトンネルが失敗するなら、ゲストのインターフェースで取得し、クライアントが実際に使うアドレスとポートを確認する。

関連記事