OpenVPN はパスワードを端末から読み、stdin からは読まない
OpenVPN が実際にパスワードを読む場所、stdin 上のファイルが失敗する理由、Linux と macOS でのスクリプトによるサインインの三つの対応手段。
OpenVPN は制御端末でユーザー名とパスワードを求めますが、標準入力にリダイレクトされたファイルはその端末ではありません。この一点が、パスワードがパイプの中にあるのにスクリプトが止まる理由を説明します。プロンプトを描くのはクライアントで、読み取りは端末デバイスから行われるため、stdin をリダイレクトしても何も変わりません。クライアントを文書化された入力手段のどれかで供給すれば、同じスクリプトが一発で接続します。
三つの手段でほぼすべてのケースを網羅でき、それぞれが独自の形で失敗します。クライアントが実際に表示するプロンプトで選ぶべきで、スクリプトにしやすいオプションで選ぶべきではありません。
プロンプトは stdin から来ない
OpenVPN が資格情報を必要とすると、制御端末を開いてそこから読み取ります。だから対話的なテストは問題なく見える一方、cron や unit ファイルの下では同じコマンドが動かず、プロンプトは誰も見ていないログに書かれたままになります。端末が無いときに標準入力へフォールバックするビルドもあり、その不整合は導入まで問題を隠すため、明確な失敗より悪いものです。
コードを書く前に環境を確認し、スケジューラやサービスマネージャーが使うのと同じユーザー、同じ stdin でクライアントを実行してください。プロンプトがログに一度も現れず、プロセスが進まないなら、存在しない端末を何かが待っています。
第一の手段:二行の資格情報ファイル
認証オプションはパスを取り、ファイルにはちょうど二行、ユーザー名そしてパスワードだけが入ります。作業ディレクトリに資格情報ファイルが紛れているのが誤ったアカウントの使われる経路なので、既定のファイル名に頼らずパスを明示してください。モードを 0600 にし、クライアントを実行するアカウントに所有権を与えます。
クライアントは起動時にそのファイルを一度だけ読むので、パスワードの交換はプロセスの再起動を意味します。ふつうはそれが望ましい挙動で、交換手順の隣の runbook に書くべきものです。
第二の手段:鍵のパスフレーズ用の askpass
パスフレーズで保護された秘密鍵は二つ目の別のプロンプトを出し、それにはファイルによる答えがあります:askpass オプションがファイルの一行目からパスフレーズを読みます。SSH ベースのトンネルでは同等なのはクライアントが実行する askpass プログラムで、その標準出力が秘密になります。
どちらの形式も秘密を引数リストに入れず、ファイルとして、あるいはそれを出力する実行ファイルとして存在させます。守りはファイル権限とプロセスの所有権であって、不明瞭さではありません。コードに埋め込んだ文字列をそのまま返すヘルパーは、手間を増やしただけの秘密です。
第三の手段:ポータルクライアント自身の CLI
企業向けクライアントは通常、ウィンドウを一切介さずに名前付きポータルへ接続するコマンドラインの入口を備えており、それが対応する経路です。Linux では GlobalProtect クライアントが CLI 経由で接続と証明書のインポートを提供し、証明書認証を使うポータルでは自動接続の前にインポートの手順が要ります。実際の終了ステータスが得られ、ウィンドウのフォーカスに依存せず、画面ロックも越えられるので、合成したキー入力よりこちらを選んでください。
最初の接続でまだ人が証明書を承認する必要があるなら、自動化は未完成です。設定時にインポートを済ませ、前提条件として記録してください。
流れが擬似端末を必要とするとき
パスワードの次にワンタイムコードを求める手順には、読むべき一つのファイルがありません。Expect のような端末ドライバが適切な道具で、各パターンを順に待ち、何かを照合する前にプロセスが起動している必要があります。
失敗は二つが中心です。クライアントを起動せずにプロンプトを待つスクリプトは永久に待ち、Tcl はシェルではないので expect ブロックの中に書いたシェルの算術は読んだとおりには評価されません。パターンを組む間はデバッグフラグを立てたままにし、終わったら切ってください。
漏れる秘密と、その隠れ場所
引数として渡したものはプロセス一覧に見えるので、資格情報はファイルかヘルパーの後ろに置き、コマンドラインには決して置きません。ワンタイムコードは設計上消費され、試行ごとに生成する必要があります。失敗ログはユーザー名を、ときにはそれ以上持つためどこかへ送る前に伏せ字にし、パスワードを埋め込んだ設定ファイルはチケットやリポジトリに貼り付けられるので、秘密はプロファイル自体の外に保ってください。その状態でアカウントを交換すると、あらゆる複製を探すことになり、それがまさにこの配置が避ける費用です。
選んだ手段を監査し、実際にクライアントを動かす unit ファイルやスケジューラに配線してください。トンネルはそのプロセスが生きている間だけ生きます。