トンネルは使い捨てだが、ポリシーはそうであるべきではない。Linuxゲートウェイでは、名前でトンネルのインターフェースに一致するnftablesルールを一度ロードすれば、そのインターフェースが現れるたびに適用され続ける。インターフェースは依然としてライフサイクルを持ち、作成され、消え、その周囲のルートと変換は独自のスケジュールに従う。これらの所有者を分けることが、再接続中にアクセスを安定させる。

名前の一致はインターフェースより長く生きる

nftablesは数値のインターフェースインデックス一致と、動的な名前一致 iifname と oifname を提供する。これらの名前を使うルールは、トンネルデバイスがまだ作成されていなくても問題なくロードでき、起動時のルールセットにまさに必要な性質だ。インターフェースの名前が変わると一致は止まり、新しいインターフェースがその名前を引き継ぐと再開する。数値インデックスにはこの性質がないため、トンネルには名前の形式が通常の選択となる。

名前は一致のキーであり、反対側に誰がいるかの証拠ではない。ピアの認証はVPNの仕事のままである。

ルールを追加する前にチェーンを読む

順序が結果を決めるため、ルールセットが現在何を含み、新しいルールがどこに入るのかを確認する。

nft list ruleset
nft -c -f /etc/nftables.conf

一覧はチェーン、ルール、ハンドルを示し、チェックモードは候補ファイルをロードせずに検証する。同じフローの以前の許可の後に置かれたトンネル専用の許可は、最初に一致したルールが勝つため、何も変えない。だから遅れて置いたルールは正しく見えても効果がないことがある。チェーンを順に読み、クライアントからアップリンクへの通信の拒否が今もより広いものより前にあることを確認する。

ルート、変換、フローには別の所有者がいる

インターフェースの存在はルートを作らず、ピアを認証もしない。それらはVPNマネージャーのもので、変換には第三のライフサイクルがある。

conntrack -L -s 10.20.0.0/24 | head
ip route show dev vpn0

conntrackの一覧は既存のフローを元の値と変換後の値とともに示し、ルートの一覧はマネージャーがインターフェースのために何を設定したかを示す。NATルールは最初のパケットで接続追跡の状態を作るため、確立したフローはルールが変わった後も変換を保つ。だからルールが更新されることと、新しい経路を使うフローがあることは別の話だ。どのセッションを再接続させるかを決め、無関係なフローはそのままにしておく。

コールドスタート、喪失、復旧を受け入れる

起動時にトンネルがない状態、次に存在する状態、さらに切断と復帰の後でゲートウェイを試す。トンネルがない間は禁止された転送が拒否されたままであること、ピアが認証されれば新しく許可されたフローが動くこと、復旧に無関係な状態の消去が要らないことを確認する。他のサービスがそれらを共有しているため、一つのプロファイルの停止動作としてPOSTROUTINGチェーン全体やすべてのconntrackエントリを消してはいけない。起動フックがゼロで終わったことだけでなく、どのコンポーネントがインターフェース、ルート、ポリシーを変えたのかを記録する。

再接続を生き延びるポリシーとは、所有者が名指しされ、トンネルを下げた状態と上げた状態の両方でルールが試されたものだ。成功を報告するフックは、フックが動いたことしか証明しない。

関連記事