OpenVPN はプロファイルが読み込まれても ca.crt を見つけられない
プロファイルのパスは中のファイルの基準ではありません。絶対指定の --config でも ca.crt で失敗する理由と、起動がどう答えを決めるかを解説します。
サービスは起動し、プロファイルを何の不満もなく読み、それから無関係に見える行で停止します。ca.crt を開けないのです。証明書には何も変わっておらず、unit ファイルのプロファイルのパスは絶対指定です。この組み合わせが手がかりです。渡したパスが指すのは一つのファイルであり、そのファイルの中の名前はまったく別の場所で解決されます。だから完全修飾に見える起動でも、誰も意図しなかったディレクトリから鍵を読んでいることがあります。
この失敗の原因は数少なく、順に切り分ける価値があります。プロセスが実際に持っていた基準ディレクトリ、サービスの起動コンテキスト、そしてパスが正しくなった後のファイル周辺の権限やサンドボックスです。それぞれが unit に、プロセスに、ファイルシステムに別の痕跡を残します。
プロファイルのパスは基準ディレクトリではない
/tmp で起動し、/etc/vpn/prod/tenant-a.ovpn を渡されたプロセスを想像してください。そのプロファイルの中で、ca ca.crt という行は相対パスを指定しています。プロファイルを見つけた引数はその名前を書き換えないので、プロセスは /tmp/ca.crt を探し、ファイルが無いと報告します。
紛らわしいのはエラーの順序です。OpenVPN はまず構成を解析し、参照されたファイルに到達するたびに開くので、プロファイルの誤字は鍵に触れる前に報告され、欠けた証明書は解析がそこまで進んで初めて現れます。したがって読み込まれたプロファイルは、構文が正しい証拠であって、そこに書かれたファイルが見つかった証拠ではありません。
マニュアルが分けるもの: --config と --cd
OpenVPN 2.6 のマニュアルは二つの別個のオプションを説明しています。一方は構成ファイルを読み込みます。もう一方は構成、鍵、スクリプトその他のファイルを読む前にプロセスのディレクトリを変え、現在のディレクトリを参照しない絶対ディレクトリを要求します。
openvpn --cd /etc/vpn/prod --config tenant-a.ovpn
この呼び出しは形であり、他人のプロファイルを起動する指示ではありません。得られるのは決定性です。連鎖の中のあらゆる相対名の基準が、プロセスを起動したシェルや管理機構から継承されるのではなく、コマンド内で明示されます。代替案も同じくらい有効で、サービスにはしばしば適しています。作業ディレクトリはそのままにし、プロファイル内の参照ファイルをすべて絶対指定にします。
どちらを選んでも、最初の失敗ではなく連鎖全体を監査してください。プロファイルは別の構成ファイルを引き込むことがあり、取り込まれたファイルの相対名は、それを取り込んだファイルのディレクトリではなく、同じプロセスのディレクトリを基準に解決されます。ログのパス、認証ファイル、補助スクリプトも同じ規則に従います。
サービスは別の場所で起動する
プロファイルのディレクトリで対話シェルを動かしても、パッケージ化された unit については何も証明しません。管理機構は独自の作業ディレクトリを設定し、ラッパースクリプトがバイナリ実行前にさらに変えることもあります。失敗している unit こそが、推論する価値のある唯一の起動です。
systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd
二つ目のコマンドは、稼働中のプロセスが実際に保持しているディレクトリを示し、ラッパーが関与する場合は unit ファイルより信頼できます。両者が食い違うなら、答えはラッパーであり、unit は誤った手がかりです。
探索のあと: 権限、chroot、サンドボックス
正しい基準ディレクトリでも同じメッセージは出ます。解決とアクセスは別の段階だからです。プロセスには各親ディレクトリの実行権限とファイルの読み取り権限が必要で、ファイルシステムの一部を隠すサービス unit は、プロセスがそもそも見えるものを変えてしまいます。
よくある三つの型が同じエラーを生みます。ファイルが root だけ読める一方で、サービスが開く前に権限を落としている。ユニットがプロファイルのディレクトリを含まない保護的なファイルシステムの見え方を設定している。デーモンが chroot で動くため、ホスト上にあるパスがその見え方の中には存在しない。
権限を緩めるのではなく、ファイルの所有者とプロセスの身元で診断してください。このエラーを黙らせるために秘密鍵を誰でも読めるようにするのは、大きな失敗を静かな失敗に取り替えることであり、鍵こそディレクトリの中で最も晒したくない部分です。
自分の起動で修正を証明する
プロファイルと無関係なディレクトリから実際の unit を再起動し、同じ起動行を観察します。次に、プロセスが稼働中に意図したディレクトリを保持していること、読み込んだ証明書が期待どおりであることを確認します。
systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager
パスの読み込みが成功しても、認証と経路制御は依然として別の段階で、それぞれの失敗があります。接続が確立しても通信が通らない場合は別の調査です。ここでの修正は、ファイルがどのディレクトリから来たかだけに関わり、最後に手で実行した人の記憶ではなく、呼び出しの中に見えるべきです。
プロファイルを構成管理ツールで配布するなら、基準ディレクトリか絶対ファイル名もそこに書いてください。一台のホストでの手作業の修正は、次の再構築のあとに戻ってくる版のこの問題です。