リモートゲートウェイが再起動し、一分以内に戻ってくるのに、ローカルのstrongSwanデーモンは動き続けたままでトンネルは停止しています。ESTABLISHEDをgrepしてデーモンを再起動するcronジョブは、いずれそれを覆い隠し、そのうえマシン上の無関係なトンネルまで中断します。しかも失敗したトンネルだけを見逃すかもしれません。復旧は戻るべき接続に属するもので、リロードを生き延びる設定として表現します。このランブックはそれを一本の接続に対して設定し、結果を名前で証明します。

グローバルな再起動をやめ、その証拠は残す

デーモンの再起動には二つの明確な欠陥があります。すべての接続の状態を破壊すること、そして実際にどのイベントが失敗したのかを何も教えてくれないことです。grepしたステータステキストは別の接続のものかもしれませんし、必要なchildは何もトリガーしないまま待機していました。

何かを変える前に、読み込まれている接続とアクティブなアソシエーションを読み、peerが戻った後で比較できる変更前の像を持っておきます。

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

開始と再試行は戻ってくる接続に置く

swanctl.confの構成では、これらの設定はグローバルポリシーではなく接続とchildのレベルにあります。以下の断片はイニシエーター側の例で、提案・認証・セレクターがすでに正しいことを前提にしています。

connections {
    branch {
        keyingtries = 0
        dpd_delay = 30s
        children {
            private-lan {
                start_action = trap|start
                dpd_action = restart
            }
        }
    }
}

start_actionはchildが読み込まれたときに何が起きるかを決めます。startは即座に開始し、trapは一致するトラフィックが現れたときに開始をトリガーするポリシーをインストールします。trap|startと書くにはstrongSwan 5.9.6以降が必要なので、行をコピーする前にバージョンを確認してください。dpd_action=restartはpeerが死亡と判定された時点で新しいネゴシエーションを要求し、接続レベルのkeyingtries=0は成功か恒久的なエラーまで追加の試行を許可します。IKEv2ではdpd_timeoutはまったく効果がありません。peerが応答しないかどうかは通常の再送が決めるからです。

この例の遅延は出発点であり、普遍的な期限ではありません。peerの再起動にかかる時間と、どれだけの再送に耐えるか。

どのイベントから復旧しているのかを知る

三つの障害はダッシュボード上では同じに見え、それぞれ別の設定を必要とします。一度も上がらなかった初期接続は設定または到達性の問題です。応答をやめたpeerはDPDのケースです。peerが明示的に閉じたchildは、DPDが決して観測しない、独自のclose_actionを持つポリシーイベントです。障害前後のログを読めば三つのどれなのかが分かり、答えによって修正方法が変わります。

運用者が保守のために意図的に閉じる接続には攻撃的な再開始を加えないでください。加えるとメンテナンス時間の真ん中でトンネルが再び現れますし、オンデマンド設計なら保持したtrapで十分で、一致するトラフィックがタイマーなしでchildを再確立します。

デーモンのステータスではなく、名前で検証する

peerがまだ停止している間に接続とそのchildを名前で読み、戻ってからもう一度読んだとき、その二つの出力の差が証拠です。

swanctl --initiate --child private-lan
swanctl --terminate --ike branch

次にアソシエーションではなくサービスを確認します。新しいchildのセキュリティアソシエーションと、その先のプライベートな宛先への成功したリクエスト、この二つの事実が重要であり、無関係なトンネルが健全な状態でデーモンが動いていることはどちらも証明しません。

childがまったく開始しない場合は、テストトラフィックが設定されたセレクターと正確に一致しているか、プロトコルとポートも含めて確認します。開始して失敗する場合は、無限ループの陰に隠さず、認証または提案のエラーを読みます。keyingtries=0は恒久的な拒否を喜んで永遠に繰り返すからです。

メンテナンス時間に変更を読み込み、再テストする

リロードはデーモンの再起動より安全ですが、それでも無料ではなく、childの置き換えやアンロードは、開始済みのアソシエーションを閉じたり、そのtrapを落としたりすることがあります。

メンテナンス時間に読み込み、以前のファイルを保存し、接続が既定値ではなく意図した設定で現れることを確認します。

swanctl --load-conns
swanctl --list-conns

以前のファイルを戻して再度読み込むことでロールバックし、同じ二つのコマンドを繰り返します。デーモンの再起動後にしか戻らないトンネルは修復されたのではなく、リセットされたのです。

関連記事