VPN ユニットがネットワークより先に起動して死ぬ理由
リンクにアドレスが付く前に起動するユニットは、一見ランダムに見える形で失敗します。ジャーナルから順序を証明し、その後で待機と再試行を追加します。
マシンを起動してログインすると、トンネルが上がった数秒後に死んでいることがあります。プロファイルは正常で、証明書も正常で、残っている手がかりはその起動時のジャーナルだけです。たいてい起きているのは競合で、ユニットはマシンがアドレスを持つ前に起動しており、宣言した順序は見た目どおりの意味を持っていません。以下ではすべて、その競合を証拠から証明し、正しく閉じる方法を扱います。
ターゲットは待ち合わせ場所であり、管理者ではない
network-online.target はネットワークが何かを知りません。これは調整用のポイントで、リンクが使えるようになるまで起動を遅らせるはずのサービスを集め、その定義はマシンを所有するネットワークマネージャーに委ねます。ほとんどのデスクトップとサーバーでは、NetworkManager や systemd-networkd が提供する待機サービスを意味します。どちらも有効にしなければ、ターゲットには待つものが何もないので、何かが引き込んだ瞬間に完了します。しかもそれは DHCP が応答するよりかなり前かもしれません。あなたのユニットの順序行は正直でしたが、それでも役に立ちませんでした。
したがって最初の問いは、あなたのユニットが何を宣言するかではありません。このマシンで実際に待機を行っているものがあるかどうかです。
ユニットファイルではなく最後の起動を読む
ユニットファイルは意図を記述し、ジャーナルは起きたことを記述します。その起動だけを、単調なタイムスタンプ付きで問い合わせてください。そうすればすべてのメッセージが同じ時計に載ります。次に二つの行を探します。トンネルユニットが起動を始めた瞬間と、アドレスが現れた瞬間、または待機サービスが終わった瞬間です。その二つの数字を並べれば、競合は確認されるか除外されるかのどちらかです。
依存関係の表示がそれを裏づけます。トンネルユニットの重要なチェーンに待機サービスが含まれていなければ、その経路のどこも起動を遅らせておらず、ターゲットは想定した仕事をしていません。二つの表示、一つの結論です。
systemctl list-units --type=service --state=running | grep wait-online
journalctl -b -o short-monotonic -u openvpn-client@office
待機を足し、次に再試行を足す
パッケージ済みのユニットを編集するのではなく drop-in を使ってください。パッケージ更新が変更を黙って捨てないようにするためです。ユニットはターゲットの後に順序づけられ、ターゲットを同じトランザクションに引き込まなければなりません。順序だけではターゲットは呼び出されず、望むことがそれを呼び出します。
OpenVPN クライアントのパッケージ済みユニットはすでに両方を備えています。手書きのユニットはふつう片方かどちらも備えていないので、何かを足す前に確認する価値があります。
[Service]
Restart=on-failure
RestartSec=15
固定の sleep が罠である理由
ExecStartPre 内の sleep は順序の修正のように感じられ、余分な手順を伴う遅延のように振る舞います。健康だった起動も含めてすべての起動を遅くし、リンクが選んだ数より長くかかるとやはり負けます。
さらに悪いことに、待機サービスが機能しているかどうかを隠すので、次の失敗は同じ問題の別のタイミングではなく、まったく新しい問題として現れます。短い再起動の遅延のほうが良い道具です。健康な起動では何のコストもかからず、失った競合を別の試行に変えます。間隔は控えめにして、ユニットを成功させてください。永遠に再起動し続けるなら、プロファイルが壊れているのであって、何度試しても変わりません。だからこそ 間隔を上げるのではなくログを読んでください。
順序が正しくても名前解決が失敗するとき
トンネルのルートを持つアクティブなユニットは、順序が仕事をしたことを意味し、残る不具合は一つ上の層にあります。よくある形は、リンクやリゾルバがそれを保持できる状態になる前に、トンネルの up スクリプトが適用したリゾルバ設定です。失敗中のリゾルバの状態と、トンネルユニットを再起動した後の状態を比べてください。
再起動で名前解決が直るなら、間違った DNS サーバーではなく起動順序の不具合であり、この二つは別の修正を必要とします。そのうえで、サービス再起動ではなくコールドブートで全体を証明してください。再起動はすでに上がっているネットワークに対して行われるので、追っている不具合をちょうど隠してしまいます。リンクをわざと遅い状態にして繰り返し、ネットワークが速いときだけ動くユニットはまだ壊れているとみなしてください。