OpenVPNのscript-securityレベル0〜3と、それぞれが何を開くか
script-securityの各レベルは、プロファイルが実行できる範囲を広げます。まず管理者向けヘルパー、次にユーザースクリプト、最後に環境変数内のパスワードです。ディレクティブを読みましょう。
プロファイルをデスクトップクライアントに取り込むと、最初の失敗はクライアントが受け入れを拒む行であることが多い——実行しないスクリプトフック、あるいは寛容すぎると判断されるscript-security値だ。数値を上げればダイアログは消える。だがそれは、警告を消すためだけに、そのプロファイルがあなたのマシン上で実行できる範囲を広げることでもあり、奇妙な取引だ。取り込みからディレクティブまで辿れば、判断は具体的になる。
取り込みダイアログからディレクティブへ
プロファイルはディレクティブを含むテキストファイルで、クライアントはトンネルが存在する前にそれを読む。up、down、tls-verify のようなディレクティブは、OpenVPN が決められた時点で実行すべき外部プログラムを名指しする。OpenVPN がそれを実行するかどうかは script-security という別の設定で、プロファイルは通常そちらも指定する。
つまり警告は暗号や証明書の話ではない。設定ファイルがクライアントにホスト上で何かを実行するよう求め、クライアントが現在の許可レベルでその要求を通せるかを確認しているのだ。
この段階では二つの異なる失敗が同じに見える。クライアントが与えないレベルを求めるプロファイルは拒否を生む。クライアントが与えるレベルを求めるがスクリプトが欠けているプロファイルは、代わりに実行時の失敗を生み、サポートのスレッドでは両者が混同される。一方は許可の問題、もう一方はパッケージの問題だ。
各レベルが実際に開くもの
レベル0は外部プログラムの呼び出しを完全に禁じる——これは助けなしに自分のインターフェースを設定するクライアントには筋が通り、オペレーティングシステムに頼るクライアントには筋が通らない。レベル1(既定)は、インターフェースとルートの設定に必要な組み込み実行ファイルを許可する。どちらのレベルも、ユーザーが用意したものは何も実行しない。
| Level | What OpenVPN may execute | What it exposes |
|---|---|---|
| 0 | No external programs at all | Interface and route setup must not depend on helpers |
| 1 (default) | Built-in helpers such as ip, ifconfig, route or netsh | Privileged commands the platform already ships |
| 2 | Built-in helpers plus user-defined scripts | Whatever the named script does with the client's privileges |
| 3 | Everything above, plus passwords in environment variables | Credentials visible to child processes and their logs |
レベル2が興味深い境界で、ユーザー定義のスクリプトを認める——その時点から、クライアントの権限は、あなたが読んだことのないコードに及び、あなたが選ばなかった瞬間に呼び出され、接続の詳細を含む環境で動く。レベル3はさらに進み、環境変数を通じたパスワードの受け渡しを許す。だからマニュアルは潜在的に安全でないと記している。
これらの数値はいずれも強度の設定ではない。レベル3のプロファイルはレベル1より優れた暗号化を持つわけではなく、実行面が大きいだけで、トンネルは同一だ。
そのプロファイルに何がふさわしいかを決める
どのレベルが必要かを問う前に、そのスクリプトが何のためかを問う。DNS設定を押し込んだり、接続後にルートを修復したりするフックは、何かを実行する正当な理由だ。一時ディレクトリで見慣れないバイナリを呼ぶフックは、止める理由だ。
スクリプトのパスはスクリプト本体と同じくらい重要だ。相対パスはクライアントが使うディレクトリを基準に解決され、書き込み可能なディレクトリは一度きりの取り込みを恒久的な実行スロットに変える。ユーザーが変更できないディレクトリ内の絶対パスが、選ぶべき形だ。
スクリプトはクライアントの環境も継承し、そこに資格情報と接続メタデータがある。この継承こそが、環境を記録するスクリプトと組み合わさったときにレベル3を危険にする理由であり、スクリプトを有効にしたクライアントの診断ダンプをチケットに貼る前に一度見直すべき理由でもある。共有する前に環境を取り除こう。
grep -nE 'script-security|^up |^down |tls-verify' client.ovpn一つだけ変え、そして切断側も見る
プロファイルに本当にスクリプトが必要なら、レベルだけを、そのプロファイルに限って変える——クライアントを前面で詳細出力付きで実行し、スクリプト自身のエラーが見えるようにする。サービス管理に飲み込ませてはいけない。
openvpn --config client.ovpn --script-security 2 --verb 3
ip route show default
接続だけでなく、ライフサイクル全体を試す。切断フックが失敗するとルートは死んだトンネルを指したままになり、接続しているように見えて何にも届かないマシンができる。変更を完了とする前に一度再接続し一度切断し、それぞれの後にルーティングテーブルを確認する。
元のプロファイルの複製を残す。プラットフォームのクライアントが同じスクリプトモデルを実装していない場合、取り込みが通るまでディレクティブを削ると、トンネルが必要としていたDNSやルートの統合が失われかねず、結果の接続は認証だけは完璧に通って何も解決しない。
記録すべき判断は狭い——どのスクリプトを、どのパスで、どのレベルで許可し、どのプロファイルのためか。それ以外はプロファイル内で変わらず、これはレビュー担当者が確認できる一文だ。