strongSwan の設定に接続を並べても、定義が読み込まれたことしか証明しない。ピアに接続したこと、IKE SA が存在すること、トラフィックが保護されていることを意味しない。デーモンは定義と生きた関連を別個のオブジェクトとして扱い、両者の距離は意図的な設計判断である。どちらのオブジェクトを見ているのかを分かっていれば、曖昧な障害が具体的な次のコマンドに変わる。

読み込みは接続ではない

読み込まれた接続は、ピアのアドレスや資格情報、提案、トラフィックセレクタといった、後で何を交渉できるかについての表明だ。その表明のどこにも、デーモンが誰かを呼び出しておく必要はない。ゲートウェイは相手側を待つことも、起動時に自分から開始することも、一致するトラフィックが来て目覚めるのを待つこともできる。三つとも有効で、開始ポリシーを読むまでは設定ファイル上で同じに見える。

運用者がはまるのは、定義の一覧を状態一覧として読むときだ。プロファイルがあるからトンネルは上がっていると見なし、次の一時間を、一度も構築されなかった関連のルートのデバッグに費やす。

逆の誤りも同じくらい多い。プロファイルが欠けていると、設定が一度も読み込まれていないのにネットワーク障害を探しに行く。オブジェクトに名前を付け、そのうえでそれを観測するコマンドを実行する。

三つのオブジェクト、三つの観測

strongSwan は、読み込まれた定義、IKE SA、CHILD SA を保持する。一つ目は設定、二つ目は認証された制御関係、三つ目は選択されたトラフィックに対する交渉済みの保護だ。それぞれ別の名前も持つので、hq というプロファイルが hq-lan という child を持つことができる。

表は各層を、それを表示するコマンドに対応づける。ログを読む前にその行を読む。

LayerWhat it containsCommand
DefinitionPeer addresses, credentials, proposals, and traffic selectorsswanctl --list-conns
IKE SAOne authenticated control channel to the peerswanctl --list-sas
CHILD SAKeys and selectors for the traffic being protectedChild rows under the IKE SA

child を要求すると、存在しない場合はまず親の IKE SA を構築する。IKE SA だけを要求するのは別の呼び出しだ。正しく認証される制御チャネルでも、要求した child が保証されるわけではない。

この違いは部分的な障害のときに効く。IKE SA は健全でも、child がセレクタの不一致やピアが受け入れない提案で失敗することがある。二つのオブジェクトは別の理由で失敗するので、別々に観測する価値がある。

開始アクションは意図して選ぶ

swanctl.conf では、child の start_action が読み込み後の挙動を決める。既定値 none は定義を手動の開始や responder としての利用に残す。start は発信し、trap は一致するトラフィックが現れ次第ネゴシエートするポリシーを残す。

つまり「読み込みがトンネルを開始することは決してない」も「読み込みが必ず開始する」も誤りだ。アクションはプロファイルの一部であり、ピアの役割に合っていなければならない。両方が相手を待つ二つのゲートウェイは沈黙を生むのであって、トンネルは生まない。

trap ではトラフィックがセレクタに一致する必要があるので、無関係な ping は何も目覚めさせない。start ではピアのアドレスが使える必要があり、両側が認証と提案で合意しなければならない。どちらのアクションも、これらの前提の確認の代わりにはならない。

復旧は別のポリシー

起動は keepalive ではない。死んだピアの検出、ピアによる明示的な切断、鍵の更新、プロセスの再起動は、それぞれ独自の設定を持つ別のライフサイクル事象だ。最初の開始がそのすべてを覆うと期待するのではなく、一つずつ意図して設定する。

起動時に上がり、一時間後に死ぬトンネルは復旧の問題だ。開始ポリシーは仕事を終え、その後に意味を失った。最初の交渉を責める前に DPD と鍵更新の設定を見る。

読み込まれた定義の置き換えは独立した操作だ。既定でない開始ポリシーには文書化された逆アクションがあり、再読み込みは運用上の変更であって、すべての関連がその場で更新されたという前提ではない。再読み込みは再接続が許容される段階で行う。新しい設定が証明されるまで古い設定を保つ。

ルーティングをデバッグする前に何が存在するかを確認する

三つの観測、すなわち読み込まれた定義、稼働中の IKE SA、child の項目を順に行う。答えのたびに次の問いが狭まる。一歩飛ばすと、最後には一度も構築されなかった層をデバッグすることになる。

読み込まれているものと、実際に確立されているものから始める:

swanctl --list-conns
swanctl --list-sas

プロファイルが正しいのに child がないなら、名前で開始し、何が起きるかを見る。通常、出力は親が先に上がったかどうかを示す。

swanctl --initiate --child hq-lan

稼働中の CHILD SA はゴールではない。転送規則、ルート、アプリケーション自身の認可がまだ揃っていなければならない。ライフサイクルが答えるのは何を交渉したかであり、誰がサービスを使えるかは決められない。

関連記事