OpenVPN がログイン時には起動し、Windows の起動時には起動しないのはなぜ?
スタートアップのショートカットはデスクトップアプリを起動するのであって、自動サービスを起動するわけではありません。ファイルを移動する前に、サービスがどのプロファイル元を読むかを確認してください。
サインインした後にだけ現れるトンネルは、通常その人物のセッションが起動しているのであって、自動サービスが起動しているのではありません。よくある原因は openvpn-gui.exe を起動するスタートアップのショートカットで、壊れたインストールではありません。ショートカットはユーザーセッションの中でデスクトップアプリを起動し、そのユーザーのプロファイル、そのユーザーの証明書ストア、プロンプトに応答する権限を使います。これらはいずれも接続をサインイン済みの人間から独立させませんが、ログイン前のトンネルが要求するのはまさにその独立です。
症状には通常三つの原因がある
三つのパターンは外から見ると同じに見えますが、修正方法は異なります。一つ目は実行の所有者がサービスではなくユーザーセッションである場合で、これがスタートアップのショートカットのケースです。二つ目はサービスが見ない場所にプロファイルがある場合で、サービスは起動しても何も見つけられず、きれいに終了します。三つ目はサービスがプロファイルを見つけて起動するものの、その資格情報がどのサービスにも提供できない対話を必要とする場合です。
どれに当たるかを特定するには二つの読み取りが必要です。サービスが何を実行するよう構成されているか、そしてどのファイルを見られるかであり、どちらもコマンド一つで済み、実行中の接続を妨げることもありません。
自動サービスが実際に読むもの
Community の自動サービスはラッパーで、構成された自動起動ディレクトリ(通常はインストール先の config-auto)を走査し、見つかった一致するプロファイルごとに OpenVPN プロセスを起動します。ユーザーの GUI メニューに表示されるプロファイルは、代わりにそのユーザーのローミングプロファイル配下にあり、サービスアカウントが読まないディレクトリに置かれています。Windows サービスのガイドはこの検出について説明しており、何かをコピーする前に読む価値があります。対象ディレクトリはインストールの性質であり固定の慣習ではないから、GUI のフォルダにファイルをコピーしてもサービスには何の変化もなく、config という名前のすべてのフォルダにコピーすると修正ではなく重複が生まれます。
Get-Service OpenVPNService | Select-Object Status, StartType
Get-CimInstance Win32_Service | Where-Object Name -eq 'OpenVPNService' | Select-Object PathName, StartName
gci 'C:\Program Files\OpenVPN\config-auto'
最後のコマンドはラッパーが実際に何を見るかを一覧にするもので、プロファイルが間違った場所にあることを確認する最速の方法です。二行目はサービスが実行されるアカウントも示しており、そのアカウントがどのファイルパスと証明書ストアに到達できるかを決めます。
デスクトップのログインでは動き、起動時には動かない理由
デスクトップでの成功は、入力への依存を長く隠すことがあります。GUI は鍵のパスフレーズ、アカウントのパスワード、第二要素をダイアログで集められますが、表示可能なデスクトップを伴う対話型セッションで動いているからです。サービスはデスクトップのないセッションで動くため、入力要求を表示する場所がなく、資格情報の問題とはまったく似ていないタイムアウトの後に接続が失敗します。
ファイルアクセスも同じ規則に従います。ユーザーのプロファイル配下に保存された秘密鍵や、ユーザーの個人ストアにある証明書は、マシンとして動くサービスからは利用できません。同じプロファイルファイルが同じ環境を意味すると仮定するのではなく、絶対パス、アクセス許可、双方が行う証明書の選択を比較してください。
ユーザーがサインインしているかどうかに関係なく実行するよう設定されたスケジュールタスクも、同様の制約を引き継ぎます。GUI の実行ファイルを正常に起動しても、資格情報を決して取得しないプロセスを生み出すことがあるため、タスクマネージャーにプロセスがあることはトンネルが機能している証拠にはなりません。
所有者を一つに決めて、実際のライフサイクルを試す
サインイン済みの人物に属する接続には、GUI のサポートされる自動起動を使い、サービスは関与させないでください。誰かがサインインする前に存在しなければならないトンネルには、サービスを構成する、ラッパーが読む場所にプロファイルを置く、対話型パスフレーズのない鍵や文書化された資格情報ファイルなど、サポートされる無人資格情報の仕組みを使う、といった対応が必要です。
Get-Content 'C:\Program Files\OpenVPN\log\openvpn.log' -Tail 40
Get-WinEvent -LogName Application -MaxEvents 20 | Where-Object ProviderName -like '*OpenVPN*'
重要なのは、誰もサインインしないまま再起動し、その後にネットワーク変更のあと再接続する、というライフサイクルを試すことです。接続の所有者は一つに保ってください、なぜなら競合する二つの起動の仕組みは通常、同じルートと同じサーバーセッションを奪い合う二つのインスタンスを生み出し、どちらか一方の仕組みだけよりも診断が難しくなるからです。