起動時にクライアントを起動し、ユニットは active と報告しているのに、トンネルがない。当然の結論は「サービスが起動に失敗した」であり、当然の対処は「もう一度起動する」である。どちらも十分に頻繁に間違っているので、再試行中の稼働クライアントは外から見ると壊れたクライアントとまったく同じに見える、という原則にする価値がある。違いはプロセスが何をしているかにあり、ユニットの状態にはない。

神話: サービスが起動していればトンネルも機能している

active なユニットは、プロセスが起動され、終了していないことを証明する。プロファイルが読み込まれたこと、証明書が受け入れられたこと、相手側が応答したことは証明しない。パッケージ版クライアントは何分も再試行ループに留まることがあり、その間 systemd は成功しか報告しない。状態と挙動のあいだのこの隔たりが、この記事の主題そのものである。

逆のケースも同じくらいよくある。鍵を読めずにプロセスが終了し、ユニットが失敗状態を報告しても、理由は何も語らないことがある。どちらの状態も、ログを読まなければ区別できない。

ユニットの状態ではなく、そのインスタンスのジャーナルを読む。理由の行はログにあり、状態ラベルにはない。

神話: 再試行の設定はあらゆる失敗をカバーする

名前解決とトランスポートの再試行は、別々の既定値を持つ別々の制御である。resolv-retry はリモートホスト名の繰り返し検索を制御し、文書化された既定値は無限に試行し続ける。connect-retry は試行間隔を設定し、connect-retry-max は各リモートエントリを試行する回数を制限できる。どれかを変更する前に、ログがどの段階を示しているかを確認する。

いずれも、壊れたプロファイル、読めない秘密鍵、拒否されたアカウントには当てはまらない。これらは修正が必要であり、再試行し続けるクライアントは前進しない。

未承認の証明書を永遠に再試行することは、検証を外す理由ではない。エラーを読む理由である。

神話: ランチャーはひとつで足りるので、もうひとつ追加する

NetworkManager やパッケージ版ユニットがすでに管理している接続に、ふたつ目のランチャーは必要ない。同じルートを奪い合うふたつのプロセスは、重複したインターフェース、混乱したログ、そして誰にも見えない理由で揺れ続けるトンネルを生む。ふたつ目のコピーはたいてい、ひとつ目が遅いことへの回避策として現れる。

何かを追加する前に、どのコンポーネントがトンネルを所有するかを決める。その後、無効化して願うのではなく、もう一方のランチャーを削除する。

所有者は再試行と認証情報の出どころも決めるため、この判断はあらゆる調整より先に来る。所有権が最初に来るのはまさにそのためである。

実際に順序が必要なもの

順序は設定済みアドレスを待つことができ、保証するのはそれだけである。network-online.target はマネージャーがネットワークを稼働状態と見なすまでアクティベーションを遅らせるが、稼働の定義はマネージャー次第である。VPN のホスト名が解決するか、リスナーが応答するか、キャプティブポータルが端末を許可したかは何も語らない。

依存関係を追加する前に、インストール済みのユニットと drop-in を読む。すべてのネットワークサービスに広範な After= を置いても、実際に必要な接続は確立されず、起動が遅れるだけである。

テストできる依存関係を順序付けし、それ以外は準備完了プローブで確認する。トンネルを開くプローブは、推測するタイマーに勝る。

トンネルが最初に上がった後に何が起きるか

起動は数ある事象のひとつにすぎない。アクセスリンクは変わり、ポータルセッションは失効し、ピアは再起動する。内部の再接続と、サービス管理者が扱うプロセス終了を区別するのは、両者の所有者が異なり残す証拠も異なるからだ。

対話的な認証は無人での復旧を制約する。バックグラウンドのユニットはデスクトップのキーリングを解錠せず MFA の要求にも答えないため、サービスの文脈に対して承認された認証情報の取り決めに従う。

トンネルが落ちている間にアプリケーションが何をしてよいかを別に決める。再試行は接続を回復するが、ブロックポリシーはその間隙に直接通信を許すかどうかを決める。

関連記事