はじめに
今年、わたしはTLS証明書をおもらししました。
Vault認証用のTLSクライアント証明書を、うっかりGitHubのPrivate RepositoryにPushしてしまったのです。
本来、GitHubでは管理しない用途のSecretだったので、さて、困ったぞ。どうやって失効すればよいのやら、ということで、作成方法・検証方法含め整理しました。
今後、おもらしした時の参考になれば幸いです。
TLSクライアント証明書によるVault認証
公式ドキュメントはこちらになります。https://www.vaultproject.io/docs/auth/cert
VaultでTLSクライアント証明書認証を有効化し、クライアント証明書を登録することで、TLSクライアント証明書による認証ができるようになります。
失効に関しては、Vault 0.4からRevocation Checkingの機能(CRL)がサポートされています。
CRLのSerial NumberとTLS証明書のSerial Numberが一致する場合、認証を拒否するという仕組みです。
CRLは、Certificate Revocation List(証明書失効リスト)の略です。
検索しても、ふわっとした情報しかヒットしないので、詳しく知りたい方は、1次ソースであるRFC5280を参照してください。
TLSクライアント証明書の失効手順
Vault PKIにCRLを登録することで、TLSクライアント証明書認証に使っているTLS証明書を失効することができます。
失効手順は以下となります。
- 失効する証明書のSerial Numberを確認し、ファイルに出力する
- Serial Numberを含むCRLファイルを作成する
- Vault PKIにCRLを登録する
具体的な手順を紹介していきます。
実行環境
今回の実行環境は以下となります。
- MacOS Big Sur
- cfssl 1.6.1
- vault cli v1.8.3
- openssl LibreSSL 2.8.3
- python 2.7
1. 失効する証明書のSerial Numberを確認し、ファイルに出力する
まず、CRLに登録する対象の証明書(以下の例ではclient.pemファイルを対象)のSerial Numberを確認します。
$ cat client.pem | openssl x509 -noout -text -in /dev/stdin
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
XX:XX:.......:XX <---- この値です
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN=FOO Root CA
Validity
Not Before: Mar 8 07:51:00 2021 GMT
Not After : Mar 8 07:51:00 2022 GMT
CRLファイル作成時にcfssl
を利用しています。cfssl
はhex
形式のSerial Number
をサポートしていないため、decimal
に変換します。 以下では、hex
からdecimal
の変換の際、bash
で変換しようとすると桁があふれ失敗したため、python
を利用しました。
$ python -c "print(int(\"`openssl x509 -in client.pem -noout -serial | awk -F '=' '{print $2}'`\", 16))" > serial.txt
Serial Numberをdecimal
に変換し、serial.txt
として保存しました。
2. Serial Numberを含むCRLファイルを作成する
CRLファイルは、証明書を発行したCAによって署名されています。 そのため、TLSクライアント証明書認証のためにPKIのルートCAのCertとKeyが必要です。
ここでは、それぞれca.pem
とca-key.pem
とします。
cfssl
を利用し、Serial Number
を持ったCRLファイルcrl.pem
を作成します。
$ cfssl gencrl serial.txt ca.pem ca-key.pem | base64 -D | openssl crl -inform DER -out crl.pem
Vaultに登録する前に、作成したCRLファイルを確認し、openssl x509 -in client.pem -noout -serial
と同じSerial Number
が登録されているか確認します。
$ cat crl.pem | openssl crl -text
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: /CN=FOO Root CA
Last Update: Oct 1 11:38:59 2021 GMT
Next Update: Oct 8 11:38:59 2021 GMT
CRL extensions:
X509v3 Authority Key Identifier:
keyid:00:1F:D4:28:97:1F:E7:6B:2E:5D:44:FE:35:68:03:84:B0:C9:22:9E
Revoked Certificates:
Serial Number: XXXXXXXXXXXXXXXXX <------ ここを確認
Revocation Date: Oct 1 11:38:59 2021 GMT
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:5f:6f:f3:fa:c5:dc:4e:23:04:9e:36:6e:32:f9:
3. VaultにCRLを登録する
VaultにCRLを登録します。 CRLは任意の名前で登録することができます。
以下の例では、日時にしました。
また、今回は/auth/cert/
をPKIのパスとしています。
このパスはご利用のVaultの設定、Policyに依存するので、このパスは必要に応じて変更してください。
cf. https://www.vaultproject.io/api-docs/auth/cert
# 環境に合わせた設定で、ログインしてください
$ VAULT_ADDR=[Vault Server] vault login ...
$ CRL_NAME=`date "+%Y%m%d%H%M%S"`; vault write /auth/cert/crls/$CRL_NAME crl=@crl.pem
登録したCRLを確認し、serial.txt
のSerial Numberと一致しているか確認します。
$ vault read --field=serials auth/cert/crls/$CRL_NAME
map[XXXXXXXXXX....:map[]]
認証エラーになるか動作確認
最後に、TLSクライアント認証でVaultにログインができなくなったことを確認します。
$ vault login \
-method=cert \
[この他,ca-certなど必要あれば指定してください...] \
-client-cert=client.pem \
-client-key=client-key.pem \
-path=auth/cert/ \
name=[role名]
Error authenticating: Error making API request.
URL: PUT https://[Vault Server]/v1/auth/cert/login
Code: 400. Errors:
* no chain matching all constraints could be found for this login certificate
ああ、よかった。
これでHappy Holidayが過ごせそうです