OpenVPN GUI のプロファイルをひとつだけ切断する — 全トンネルではない
GUI 管理のトンネルには GUI コマンドを、サービス管理のトンネルにはサービス制御を使う。スクリプトを書く前に、どのプログラムがプロファイルを所有しているかを特定する。
切断のスクリプトが失敗する理由はたいてい一つである。相手が違う所有者だからだ。コミュニティ版 OpenVPN GUI が管理するトンネルはその GUI のセッションに属し、Windows サービスが起動したトンネルはそのサービスに属し、OpenVPN Connect はどちらにも属さない。以下の確認を順に行い、所有者が不明なら止める。所有者が曖昧なまま kill コマンドを送るのが、ひとつのプロファイルの切断を拠点全体の停止に変える手順である。
GUI 管理の接続では、有効なのは GUI へのメッセージであり、openvpn.exe へのシグナルではない。
まず所有者を特定する
何かを書く前に、どのプログラムが実際に接続状態を表示しているかを見る。通知領域のアイコンは GUI セッションが所有していることを意味する。サービス項目はサービスが所有していることを意味する。独自のプロファイル一覧を持つ別アプリのウィンドウはどちらでもなく、そのバージョン固有のインターフェースが適用される。
アカウントとデスクトップセッションも確認する。別のユーザーとして、または非対話セッションで動くスケジュールタスクが、ログイン中の人が見ている GUI を制御していると決めつけてはならない。この不一致は、正常終了するのに何も変えないコマンドを生む。ログから追うには最も高くつく種類の失敗である。
次に所有者自身の切断を送る
GUI が例のパスにインストールされ、office という名前のプロファイルがある場合、コマンド全体は一行である。
"C:\Program Files\OpenVPN\bin\openvpn-gui.exe" --command disconnect office実際のインストールパスと、GUI が表示するとおりの大文字小文字を含む正確な構成名に置き換える。プロジェクトのコマンドドキュメントにサポートされる GUI 制御が並んでおり、この例は OpenVPN GUI だけのものである — 名前に OpenVPN を含むすべてのアプリのコマンドではない。
サービス所有のトンネルでは、正しい制御は GUI のバイナリではなくサービスである。何かを停止する前に、インストールされたサービスとそれが管理するプロファイルを調べる。停止は複数のトンネルを一度に落とすことがあり、プロファイルごとの結果は返ってこない。
他に何も落ちないことを確認する
GUI は disconnect_all というコマンドも文書化している。その範囲こそが、office だけを止めるスクリプトにとって誤った道具である理由だ。単純さのために使いたくなったら、そのマシンで他に何が接続されているか、利用者がどう気づくかを問う。
taskkill /F /IM openvpn.exe は二つの点でより悪い。実行ファイル名でプロセスを選び、強制終了するので、プロファイル名も所有者の通常の切断手順も表していない。これを穏当なシャットダウンと呼ぶのは、二つの問題をひとつの終了状態の背後に隠すことだ。
どの道を選んでも、変更前に影響範囲を確認する。接続中のプロファイルを一覧し、残すべきものを記録し、後で再度確認する。
終了コードではなく状態を確認する
切断を要求したら、コマンドの戻り値を信じるのではなく、所有者を通じて対象接続の状態を読む。次の手順が解体後のネットワークを必要とするなら、プロセスが戻った時点で後片付けが終わったと決めつけず、明示的なタイムアウトでその状態変化を待つ。解体と競争するスクリプトは時々失敗し、VPN のせいにされる。
状態が決して変わらないなら、所有者はおそらく宛先と違う。より強いコマンドに進む前に、セッションとアカウントを再確認する。
ログに残すもの
プロファイル名、宛先とした所有者、起動コンテキスト、そして結果の状態を記録する。完全な構成や資格情報をタスクログに流し込まず、秘密を含むファイルへのパスがあるならコマンドラインを記録しない。
プロファイルとコンテキストを名指ししたエラーメッセージがあれば、次の人が問題を再現できる。一般的な終了コードだけを記録するログは、彼らを最初に戻す。推測が再び始まるのはそこである。