TT Lab
はじめる
学ぶ 学習パス コース

証明書は更新されたのに、ブラウザは古いものを表示した

証明書一枚を四つに分けて読む

TT Labで続きを見る

目標

自前のCAでサーバー証明書を発行し、チェーン・有効期間・SAN・鍵の一致を、それぞれopensslで検証します。中間CAを立ててfullchainを組み立て、名前の検査結果を表にして残します。

なぜ重要なのか

証明書障害は、次の4つのうち1つです。チェーンが切れている、期限が切れている、名前が違う、鍵が組になっていない。直し方がすべて違うので、どれなのかをまず読み取る必要があります。このラボは、その4つをわざと作り、検証ツールが何と言うかを見ます。特に、OpenSSL 3.0のx509 -reqがCSRの拡張を既定で捨てるという事実は、発行が成功したように見える落とし穴なので、自分で体験しておくほうがよいです。

ステップ

  1. CAの秘密鍵(/root/pki/ca.key)と自己署名証明書(/root/pki/ca.crt)を作成してください。サブジェクトはCN=Lab Root CAで、有効期間は30日です。
  2. サーバーの鍵(/root/pki/server.key)とCSR(/root/pki/server.csr)を作成してください。サブジェクトはCN=www.lab.internal、SANはDNS:www.lab.internalとDNS:api.lab.internalの2つです。
  3. CAで署名して、サーバー証明書(/root/pki/server.crt)を作成してください。有効期間は3日で、SANが証明書に残っている必要があります。
  4. server.crtのシリアル番号・有効期限・SHA-256フィンガープリント・SANを保存してください(保存先: /root/pki/04-fields.txt)。
  5. 比較用の鍵(/root/pki/other.key)をもう1つ作成し、cert=・key=・other=の3行(それぞれ公開鍵PEMのsha256、64桁)とverdict=matchを書いてください(保存先: /root/pki/05-keymatch.txt)。
  6. openssl x509 -enddateの出力行とrenew_within_7d=yes|noを書いてください(保存先: /root/pki/06-expiry.txt)。判定は、-checkend 604800の終了コードで行います。
  7. 中間CA(/root/pki/inter.key、/root/pki/inter.crt、CN=Lab Intermediate CA、CA:TRUE)をルートで署名して作成し、その中間CAでリーフ(/root/pki/api.crt、鍵は/root/pki/api.key、SANはDNS:api.lab.internal)を発行してください。リーフと中間CAをこの順に連結して、fullchainを作成してください(出力先: /root/pki/fullchain.pem)。
  8. server.crtに対するwww.lab.internal・api.lab.internal・other.lab.internalの3つの名前の検証結果を、이름=OK|FAILの形式(プレースホルダーは名前です)で書いてください(保存先: /root/pki/08-hostname.txt)。

参考

ルートCAを作る

/root/pki/ca.keyと自己署名の/root/pki/ca.crt(CN=Lab Root CA、30日)を作成してください。

reqに-x509を指定すると、CSRの代わりに自己署名証明書が出ます。発行者とサブジェクトが同じで、basicConstraintsがCA:TRUEになっているかを、openssl x509 -textで確認してください。

SANを含むCSR

/root/pki/server.keyと/root/pki/server.csr(CN=www.lab.internal、SAN 2つ)を作成してください。

-newkey rsa:2048 -nodes -keyoutで、鍵とCSRを一度に作れます。SANは-addextで入れ、openssl req -in server.csr -noout -textでSubject Alternative Nameを確認してください。

3日間のサーバー証明書の発行

CAで署名して、/root/pki/server.crt(3日、SAN維持)を作成してください。

x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3が骨組みです。発行後にopenssl x509 -in server.crt -noout -ext subjectAltNameが空なら、CSRの拡張が捨てられたということです。それを移すオプションがあります。

識別値を読む

server.crtのシリアル番号・有効期限・SHA-256フィンガープリント・SANを/root/pki/04-fields.txtに保存してください。

x509に-serial -enddate -fingerprint -sha256 -ext subjectAltNameを一度にまとめて指定できます。採点ツールは、同じ証明書から値を再計算して照合します。

鍵が組かどうかを判定する

/root/pki/other.keyを作成し、/root/pki/05-keymatch.txtにcert=・key=・other=(公開鍵PEMのsha256)とverdict=matchを書いてください。

証明書の公開鍵はx509 -pubkeyで、秘密鍵の公開鍵はpkey -puboutで、同じPEM形式になります。| sha256sum | cut -d' ' -f1で64桁だけを残してください。certとkeyが同じで、otherだけが異なる必要があります。

7日のウィンドウで期限を判定する

/root/pki/06-expiry.txtに-enddateの出力行とrenew_within_7d=yes|noを書いてください。

-checkend 604800は、7日(604800秒)以内に期限が切れると、0以外のコードで終了します。if文で受けて、yes/noを決めてください。3日間の証明書なら、答えは決まっています。

中間CAとfullchain

ルートが署名した中間CA(inter.key/inter.crt、CN=Lab Intermediate CA、CA:TRUE)を作成し、それでリーフのapi.crt(SAN api.lab.internal)を発行したあと、リーフ+中間の順で/root/pki/fullchain.pemを作成してください。

中間CAのCSRをルートで署名するときは、-extfileにbasicConstraints=critical,CA:TRUE,pathlen:0とkeyUsage=critical,keyCertSign,cRLSignを指定してください。リーフは-CA inter.crt -CAkey inter.keyで署名します。openssl verify -CAfile ca.crt api.crtは失敗し、-untrusted inter.crtを指定すると通るなら、本物のチェーンです。

名前検査の表

server.crtに対するwww・api・otherの3つの名前の-verify_hostnameの結果を、이름=OK|FAILの形式(プレースホルダーは名前です)で/root/pki/08-hostname.txtに書いてください。

名前の検査は、SANのdNSNameと照合します。CNにあっても、SANになければ失敗します。3つの名前をforで回しながら、終了コードでOK/FAILを決めてください。