チュートリアルで似て見える二つのディレクトリは、まったく別の仕事をします。一方は認証局を保持し、その秘密鍵、シリアル番号のカウンター、そして署名したすべての記録を持ちます。もう一方はデーモンが起動してクライアントに応答するために必要なものを保持します。両方を同じホストの同じアカウントに置くのは一午後の作業としては楽ですが、デーモンが望むどんな身元でも発行できる唯一の鍵の隣で動くことになり、配備の残りの寿命にとっては高くつきます。

CA の作業領域にあるもの

PKI ディレクトリは発行者の状態であり、設定ではありません。CA の秘密鍵と証明書、シリアルファイル、発行済み証明書の索引、そしてそれらから作られた各身元の素材を含みます。

要求に署名するとこの状態が変わるので、作業領域は VPN サービスが動かないホスト上の管理者管理アカウントに属します。CA の秘密鍵を読める者はサーバーが信頼する証明書を発行できるため、鍵の保護が一つのファイルに入った信頼モデルのすべてです。手順を一つ省くために別の場所へ複製すると、守るべき二つ目と忘れるべき二つ目が生まれます。署名のたびにシリアルが増え索引に項目が加わるので、作業領域はファイルの束ではなく状態の一つの複製なのです。

公開 CA 証明書は別です。配布されるためのものであり、クライアントとサーバーが互いを検証するのに使うものです。

起動時にデーモンが読むもの

動作中のサーバーが消費するのは、自分の証明書、自分の秘密鍵、ピア検証用の CA 証明書、そして選んだモードが要求する鍵素材というわずかな組です。これらのパスを起動時と再読み込み時に読みます。

所有権は、実際に起動するユニットに対して評価すべきで、対話的な root シェルに対してではありません。宣言されたサンドボックスは、root での手動テストが成功しても、ファイルシステムの一部を読み取り専用や不可視にできます。

systemctl show -p User -p Group -p ReadOnlyPaths [email protected]
stat -c '%a %U:%G' /etc/openvpn/server/server.key
runuser -u openvpn -- test -r /etc/openvpn/server/server.key; echo $?

三行目こそが飛ばされる行です。デーモン自身のアカウントに鍵を読めるかを尋ねるもので、特権を落とした後に意味を持つ唯一の問い方です。root での終了コードゼロは、落とした後に何が起きるかを何も教えてくれません。

権限を変える前に、二つの障害経路を分けておく価値があります。署名の失敗は PKI ディレクトリ、その親ディレクトリの検索権限、発行者を動かすアカウントを指します。起動の失敗はユニット、その作業ディレクトリ、サーバー設定に記されたパスを指します。ツリー全体を誰でも読めるようにしてもどちらも直らず、両方が依存する境界を消してしまいます。

CA 鍵をサーバーに複製すると後で失敗する理由

複製はたいていデバッグの一手として始まり、VPN ホストでクライアントを更新したいので CA 鍵が /etc/openvpn に置かれ、更新は成功します。目の前の作業は片付き、境界は消えます。

やがてサーバーがバックアップされ、署名権限がバックアップに加わります。スナップショット、サポートバンドル、設定ディレクトリの複製が、CA が有効な限り信頼される身元を発行する力を持つことになります。その複製を持つ者は、サーバーが受け入れるどんな名前の証明書も、一度も発行されなかった名前も含めて作れます。その発行の唯一の記録は、彼らが残すと決めたものだけです。

その状態からの復旧は、ファイルを消す話ではありません。鍵が露出したかを決め、露出していれば CA を回し、すべてのピアに信頼を配り直す必要があります。作業領域を分けておけば、その会話自体が起きません。

アカウント、ディレクトリ、バックアップ

発行者には専用のアカウントとホームディレクトリを与え、実務上可能なら VPN ホストの外に置きます。デーモンには別のアカウントを与え、配備済み素材への読み取り権限だけを持たせ、証明書を発行する何かへの書き込み権限は与えません。配備は公開証明書を外へ複製して行い、発行者の非公開状態を内へ引き込むことは決してしません。二つの役割は、機密性と復元の物語が違うので別々にバックアップします。

失効の後は、サーバー設定が名指す CRL ファイルを更新し、それからサービスを再読み込みして新しい接続がそれを読むようにします。Easy-RSA のドキュメントは作業領域の構成と署名の流れを扱っており、その周りの所有権のルールは、あなたのホストについての判断のままです。サービスが何を読み込んだかは、再読み込みが拾ったと決めつけずに openssl crl -in /etc/openvpn/crl.pem -noout -lastupdate -nextupdate で確認してください。

分離を証明するテスト

動く場合だけでなく、否定的な場合を確かめます。設計どおりに発行者アカウントで証明書に署名し、その同じアカウントがサービスを起動できず、サーバーの秘密鍵を読めないことを確認します。次に、デーモンのアカウントが CA の秘密鍵を読めないことを確認します。

この三つの確認は数分で終わり、習慣ではなく権限についての言明なので担当者が変わっても残ります。結果は、対象にしたパスとアカウント、実行した日付とともに書き残します。さもなければ、この配備を引き継ぐ次の人は、境界が一度もなかったチュートリアルから境界を導き直すことになります。日付のある記録は、次のレビューを一午後ではなく数分にするものでもあります。

関連記事