OpenVPNのローカルbindが起動時に失敗する — 待つか再試行するか
ローカルアドレスがまだ上がっていないとき、OpenVPNはbindできません。制限付きの待機と再起動ポリシーを比較し、network-online.target が保証にならない理由を説明します。
起動時に立ち上がらないOpenVPNサーバーには、二つの修正案が提示されます。アドレスを待つか、bindが成功するまでサービスに再試行させるかです。どちらも同じ症状を異なる失敗時の挙動で扱います。待機は特定の前提条件を明示し、それが欠けていれば大きな音を立てて失敗します。再試行は前提条件を隠したまま、試し続けます。どちらをunitに入れるべきかは、そのアドレスが設計上の依存関係なのか、タイミングの偶然なのかで決まります。
どちらも固定のsleepより優れています。sleepは何も待たず、何を待っていたのかも報告しません。
local オプションが実際に要求するもの
localはデーモンがソケットをbindするアドレスを指定します。まだ存在しないアドレスへのbindは、「要求されたアドレス」に関するエラーで即座に失敗します。オプションがない場合、デーモンはすべてのアドレスで待ち受けます。だから同じプロファイルが、インターフェースがまだ上がっていないマシンでも動いてしまうのです。指定した一つのアドレスではなく、どこでも待ち受けているからです。この違いが失敗のすべてであり、再起動するまで見えません。
要件は、インターフェースが一般的な意味で上がっていることではありません。bindの瞬間に、アドレスが正しいインターフェースに割り当てられていなければならず、しかも同じデーモンが後で作るトンネルではなく、アンダーレイのインターフェースでなければなりません。ログインの数分後に実行した確認は、起動シーケンスについて何も証明しません。
アドレスを待つか、bindを再試行するか
待機とは、アドレスが現れるまでポーリングするExecStartPreのことで、試行回数に上限があり、時間切れになれば非ゼロで終了します。再試行とは、メインプロセスを失敗させ、サービスマネージャーに再起動を依頼することです。たとえばRestart=on-failureとRestartSec=5の組み合わせです。前者は欠けた前提条件を失敗したunitとして報告し、後者は最終的に止まる再起動の連続として報告します。ジャーナルでは騒がしくなりますが、予測できない理由でアドレスが遅れて現れる場合にも耐えます。
アドレスが設計上の依存関係なら待機を、アドレスが通常は現れるがタイミングが変わるなら再試行を選びます。両者を組み合わせるのも合理的です。制限付きの待機が通常のケースを、再起動ポリシーが外れ値をカバーします。どちらも永遠に走らせてはいけません。無限に再試行するunitは、設定ミスを報告するのではなく隠してしまうからです。
network-online.target では足りない理由
network-online.targetが約束するのは、稼働中のネットワーク実装がonlineとみなすものだけで、それ以上ではありません。systemd-networkdでは、systemd-networkd-wait-onlineがそのターゲットに到達した時点を決めますが、その既定のonlineの捉え方は、あなたの特定のアドレスが存在する前に満たされることがあります。NetworkManagerでは、wait-onlineサービスが独自のルールを適用します。ターゲットの後に並べることは健全な基準線であって、一つのアドレスやDNS応答、リモートの相手が準備できている保証ではありません。
同じ論理で、よくある代替案も排除されます。デスクトップの自動起動エントリは、サーバーでは決して開かないかもしれないユーザーセッションを待ちます。遅延したcronコマンドは、現れることを期待したリソースを名指しせずに経過時間を足すだけです。どちらも何か月も成功しているように見え、肝心の一度の起動で失敗します。
コールドブート後にbindを確認する
サービスの再起動ではなく、実際のコールドブートで検証してください。再起動は、起動シーケンスが作るはずだったアドレスを引き継ぐからです。起動後、ss -lntpまたはss -lunpで、各リスナーが実際にbindしたローカルアドレスがわかり、journalctl -b -u openvpn-server@serverで最初の試行が失敗したかどうかがわかります。bindされたアドレスをプロファイルのものと比較し、ネットワーク再接続後にもう一度比較してください。
プロファイルが固定アドレスを必要としたことがないなら、localを外すのは正当な簡素化です。ただし、トラブルシューティングの習慣ではなくセキュリティ上の判断として行ってください。
リスナーを広げると、誰が到達できるかが変わります。その変更は、本来それを制限すべきだったファイアウォールポリシーとセットにしてください。すべてのインターフェースで確実に起動するサービスは、元の問題を解決したのではなく、問題をネットワークの縁へ移しただけです。