HSM と Vault を連携して PKI シークレットエンジンで利用する秘密鍵の管理をする
VaultのPKIシークレットエンジンやTransitシークレットエンジンで扱う秘密鍵をVaultのバックエンドストレージではなく、外部のキー管理システムで管理したいという要件があるケースがあるかと思います。
Vault Enterpriseで利用できるマネージドキーの機能を利用する事で、この要件を実現する事ができます。
以下は、マネージドキーを利用し、PKIシークレットエンジンを設定し、その環境においてルートCAのローテーションを行った際の手順です。手順はReferencesに記載したチュートリアルを参考にしていますので、必要に応じてそちらのチュートリアルもご参照ください。
Prerequisites
- Ubuntu 22.04 LTS
- Vault Enterprise HSM v1.11以降のバージョン
-
softhsm2
パッケージ -
opensc
パッケージ (pkcs11-tool
CLI実行用にインストール)
Configure SoftHSM2
vault-enterprise-hsm
パッケージをUbuntu上にインストールし、systemd
でVaultが起動する様に設定しています。
[Unit]
Description="HashiCorp Vault - A tool for managing secrets"
Documentation=https://developer.hashicorp.com/vault/docs
Requires=network-online.target
After=network-online.target
ConditionFileNotEmpty=/etc/vault.d/config.hcl
StartLimitIntervalSec=60
StartLimitBurst=3
[Service]
Type=notify
EnvironmentFile=/etc/vault.d/vault.env
User=vault
Group=vault
ProtectSystem=full
ProtectHome=read-only
PrivateTmp=yes
PrivateDevices=yes
SecureBits=keep-caps
AmbientCapabilities=CAP_IPC_LOCK
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
NoNewPrivileges=yes
ExecStart=/usr/bin/vault server -config=/etc/vault.d/config.hcl
ExecReload=/bin/kill --signal HUP $MAINPID
KillMode=process
KillSignal=SIGINT
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
LimitNOFILE=65536
LimitMEMLOCK=infinity
LimitCORE=0
[Install]
WantedBy=multi-user.target
Vaultの実行ユーザーであるvault
がPKCS#11のライブラリにアクセスする必要があるため、以下のパーミッション設定を入れています。
sudo chown root:vault /etc/softhsm
sudo chmod 750 /etc/softhsm
sudo chown root:vault /etc/softhsm/softhsm2.conf
sudo chmod 640 /etc/softhsm/softhsm2.conf
sudo chown -R vault:vault /var/lib/softhsm
sudo chmod -R 750 /var/lib/softhsm
また、Vaultサービスが読み込む環境変数ファイル/etc/vault.d/vault.env
に環境変数SOFTHSM2_CONF
を設定し、SoftHSM2の設定ファイルにVaultサービスがアクセスできる様にしています。
echo "SOFTHSM2_CONF=/etc/softhsm/softhsm2.conf" >> /etc/vault.d/vault.env
次のステップに進む前に、vault
ユーザーがPKCS#11ライブラリにアクセス出来るかどうか確認しておきます。
sudo -u vault pkcs11-tool --module /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so -I
Cryptoki version 2.40
Manufacturer SoftHSM
Library Implementation of PKCS11 (ver 2.6)
Using slot 0 with a present token (0x0)
PKCS#11トークンの初期化をroot
ユーザーで実行します。
softhsm2-util --init-token --free --so-pin=supersecret --pin=prettysecret --label="test-pki-managed-key" | tee /home/ubuntu/softhsm2-init.out
以下の様なレスポンスが返ると思います。ここで出力されたslot
番号(以下の例では、1065878452
)が後ほど必要になるため、確認しておきます。
Slot 0 has a free/uninitialized token.
The token has been initialized and is reassigned to slot 1065878452
Configure Vault
VaultクラスタはVaultサーバ1台で構成しています。Vaultの構成ファイルは以下の様に設定しています。
api_addr = "http://xx.xxx.x.xx:8200"
cluster_addr = "http://xx.xxx.x.xx:8201"
ui = true
license_path = "/etc/vault.d/vault.hclic"
listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_disable = true
}
storage "raft" {
path = "/var/lib/vault"
node_id = "vault1"
}
telemetry {
disable_hostname = true
prometheus_retention_time = "12h"
}
kms_library "pkcs11" {
name = "myhsm"
library = "/usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so"
}
マネージドキーの機能を利用するために、kms_library
スタンザを用いて設定しています。
この環境で利用しているVaultのバイナリは、Vault Enterprise HSMバイナリになります。
$ vault version
Vault v1.17.2+ent.hsm (023471f83b7698e89424be66ed2ac8e5dad5fecc), built 2024-07-05T15:19:27Z (cgo)
Vaultサービスを起動します。
sudo systemctl start vault
問題なくVaultが起動したら、Vaultの初期化を行います。
export VAULT_ADDR=http://127.0.0.1:8200
vault operator init -key-shares=1 -key-threshold=1 | tee init.out
初期化の際に出力される初期ルートトークンや、Unsealキーを環境変数に設定し、VaultのバックエンドストレージをUnsealします。
export ROOT_TOKEN=
export UNSEAL_KEY=
export VAULT_TOKEN=$ROOT_TOKEN
vault operator unseal $UNSEAL_KEY
Unseal処理が完了したら、Vaultのステータスを確認します。Initialized
がtrue
、Sealed
がfalse
になっている事を確認し、次に進みます。
vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.17.2+ent.hsm
Build Date 2024-07-05T15:19:27Z
Storage Type raft
Cluster Name vault-cluster-01cfe84c
Cluster ID 2c8a32cb-fd26-bf4d-6342-6f99d7e4877b
HA Enabled true
HA Cluster https://xx.xxx.x.xx:8201
HA Mode active
Active Since 2024-07-10T03:04:07.068751551Z
Raft Committed Index 87
Raft Applied Index 87
Last WAL 30
Configure a Managed Key
次に、マネージドキーの設定をしていきます。APIドキュメントのCreate/Update managed keyに設定時に指定出来るパラメーターが記載されています。今回はマネージドキーとして利用するのは、PKCS#11のSoftHSMなので、PKCS#11 backend parametersを参照して設定してきます。
vault write sys/managed-keys/pkcs11/pki-managed-key \
library=myhsm slot=1065878452 pin=prettysecret \
key_label=test-pki-managed-key \
allow_store_key=false \
allow_generate_key=true \
mechanism=0x0001 key_bits=4096 \
any_mount=false
Success! Data written to: sys/managed-keys/pkcs11/pki-managed-key
Vaultの設定ファイルで構成したkms_library
スタンザを参照するlibrary
、PKCS#11トークンの初期化で出力されたslot
、初期化時に指定したpin
を指定しています。
allow_generate_key
は、VaultがバックエンドのHSMに鍵の生成を要求してもよいことを指定しています。
設定したマネージドキーの設定を確認します。
vault read sys/managed-keys/pkcs11/pki-managed-key
Key Value
--- -----
UUID b367b22a-3d7e-2f55-2fec-6b08979afea4
allow_generate_key true
allow_replace_key false
allow_store_key false
any_mount false
key_bits 4096
key_label test-pki-managed-key
library myhsm
mechanism 1
name pki-managed-key
pin redacted
slot 1065878452
type pkcs11
usages [3 4]
APIドキュメントTest sign with a managed keyに記載がある様に、このエンドポイントを利用することで、ランダムに生成されたデータに署名して検証を行い、マネージドキーが正しく機能することを検証できます。
vault write -force /sys/managed-keys/pkcs11/pki-managed-key/test/sign
Success! Data written to: sys/managed-keys/pkcs11/pki-managed-key/test/sign
上記の様に出力されれば、マネージドキーの設定が上手く行われています。続いて、PKIシークレットエンジンをマネージドキーを利用する形で構成していきます。
Configure root CA
マネージドキーを用いたPKIシークレットエンジンの構成をVaultプロバイダを利用して、Terraformで設定していきます。
terraform {
required_providers {
vault = {
source = "hashicorp/vault"
version = "~> 4.3.0"
}
}
required_version = "~> 1.9"
}
provider "vault" {}
resource "vault_mount" "pki" {
path = "pki"
type = "pki"
description = "root ca pki mount with managed-keys"
default_lease_ttl_seconds = 2592000 #30days
max_lease_ttl_seconds = 315360000 #10years
allowed_managed_keys = ["pki-managed-key"]
}
resource "vault_pki_secret_backend_root_cert" "root_2023" {
backend = vault_mount.pki.path
type = "kms"
managed_key_name = "pki-managed-key"
common_name = "example.com"
ttl = 315360000 #10years
issuer_name = "root-2023"
}
resource "local_file" "root_2023_cert" {
content = vault_pki_secret_backend_root_cert.root_2023.certificate
filename = "root_2023_ca.crt"
}
resource "vault_pki_secret_backend_issuer" "root_2023" {
backend = vault_mount.pki.path
issuer_ref = vault_pki_secret_backend_root_cert.root_2023.issuer_id
issuer_name = vault_pki_secret_backend_root_cert.root_2023.issuer_name
revocation_signature_algorithm = "SHA256WithRSA"
}
resource "vault_pki_secret_backend_config_urls" "config-urls" {
backend = vault_mount.pki.path
issuing_certificates = ["http://127.0.0.1:8200/v1/pki/ca"]
crl_distribution_points = ["http://127.0.0.1:8200/v1/pki/crl"]
}
output "vault_pki_secret_backend_root_cert_root_2023" {
value = vault_pki_secret_backend_root_cert.root_2023.certificate
}
vault_mout.pki
リソースブロックの中で、allowed_managed_keys
パラメーターで設定したマネージドキーpki-managed-key
を指定しています。
vault_pki_secret_backend_root_cert.root_2023
リソースブロックで、ルート証明書を生成していますが、ここではtype
としてkms
、managed_key_name
としてpki-managed-key
を指定し、設定したマネージドキーを利用して、ルート証明書を生成する様にしています。
他は一般的なPKIシークレットエンジンと同様の設定をしています。Terraformの処理を実行して、コードをVaultクラスタに反映させます。
terraform init
terraform plan
terraform apply -auto-approve
PKIシークレットエンジンのマウントポイントpki/
が作成されている事が確認できます。
$ vault secrets list
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_4b6d8ae7 per-token private secret storage
identity/ identity identity_618d63fa identity store
pki/ pki pki_55750f24 root ca pki mount with managed-keys
sys/ system system_66a6f569 system endpoints used for control, policy and debugging
続いて、中間CAも同じVaultクラスタ内に設定していきます。
Configure intermediate CA
上記ではPKIシークレットエンジンを利用して、ルートCAのみをVault内に作成しました。このルートCAを利用した中間CAもVault内に作成します。
main.tf
に以下の内容を追加し、Terraformの処理を実行し、中間CAから証明書を発行出来る様にします。
##################################
## intermediate CA
##################################
resource "vault_mount" "pki_int" {
path = "pki_int"
type = "pki"
description = "intermediate ca pki mount with managed-keys"
default_lease_ttl_seconds = 2592000 #30days
max_lease_ttl_seconds = 157680000 #5years
allowed_managed_keys = ["pki-managed-key"]
}
resource "vault_pki_secret_backend_intermediate_cert_request" "csr_request" {
backend = vault_mount.pki_int.path
type = "kms"
managed_key_name = "pki-managed-key"
common_name = "example.com Intermediate Authority"
}
resource "local_file" "csr_request_cert" {
content = vault_pki_secret_backend_intermediate_cert_request.csr_request.csr
filename = "pki_intermediate.csr"
}
resource "vault_pki_secret_backend_root_sign_intermediate" "intermediate" {
backend = vault_mount.pki.path
common_name = "new_intermediate"
csr = vault_pki_secret_backend_intermediate_cert_request.csr_request.csr
format = "pem_bundle"
ttl = 15552000 #180days
issuer_ref = vault_pki_secret_backend_root_cert.root_2023.issuer_id
}
resource "local_file" "intermediate_ca_cert" {
content = vault_pki_secret_backend_root_sign_intermediate.intermediate.certificate
filename = "intermediate.cert.pem"
}
resource "vault_pki_secret_backend_intermediate_set_signed" "intermediate" {
backend = vault_mount.pki_int.path
certificate = vault_pki_secret_backend_root_sign_intermediate.intermediate.certificate
}
resource "vault_pki_secret_backend_issuer" "intermediate" {
backend = vault_mount.pki_int.path
issuer_ref = vault_pki_secret_backend_intermediate_set_signed.intermediate.imported_issuers[0]
issuer_name = "example-dot-com-intermediate"
}
resource "vault_pki_secret_backend_role" "intermediate_role" {
backend = vault_mount.pki_int.path
issuer_ref = vault_pki_secret_backend_issuer.intermediate.issuer_ref
name = "example-dot-com"
ttl = 86400
max_ttl = 2592000
allow_ip_sans = true
key_type = "rsa"
key_bits = 4096
allowed_domains = ["example.com"]
allow_subdomains = true
}
以下のAPIドキュメントに記載があるように、中間CAの生成でもマネージドキーが利用出来るので、その様な構成にしています。
The Generate Root and Generate Intermediate API calls can leverage the Managed Keys feature, delegating operations that require private key material to an external system.
ルートCAの時と同様に、vault_mout.pki_int
リソースブロックの中で、allowed_managed_keys
パラメーターで設定したマネージドキーpki-managed-key
を指定しています。
vault_pki_secret_backend_intermediate_cert_request.csr_request
リソースブロックで、秘密鍵と署名用のCSRを作成していますが、ここでもtype
としてkms
、managed_key_name
としてpki-managed-key
を指定し、設定したマネージドキーを利用して、秘密鍵を生成する様にしています。
ルートCAを設定した時と同様に、Terraformの処理を実行し、変更を反映させます。
terraform init
terraform plan
terraform apply -auto-approve
PKIシークレットエンジンのマウントポイントが追加されている事が確認できると思います。pki_int/
のマウントポイントはPKIシークレットエンジンを用いて中間CAとして定義しています、また、pki_int/
のルートCAとしてはpki/
マウントポイントを利用するという構成になっています。
$ vault secrets list
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_4b6d8ae7 per-token private secret storage
identity/ identity identity_618d63fa identity store
pki/ pki pki_55750f24 root ca pki mount with managed-keys
pki_int/ pki pki_4226fbf5 intermediate ca pki mount with managed-keys
sys/ system system_66a6f569 system endpoints used for control, policy and debugging
中間CAに対して作成したPKIロールexample-dot-com
を利用して、証明書を発行してみます。
vault write pki_int/issue/example-dot-com common_name="test.example.com" ttl="24h"
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIFlDCCA3ygAwIBAgIUOTUtY9WdD1jeJVOOBGccEtaXZnkwDQYJKoZIhvcNAQEL
...
EyflgKCWxvsF/KH0geCFV4BA+hSMb/QbZ9MC2YLPnK2HgwkssuWf7w==
-----END CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIFpzCCA4+gAwIBAgIUE6d6pVm4GjO60td+6Q/xdpCO3qUwDQYJKoZIhvcNAQEL
...
XE8VA2lZUGFykdLi7hhPhmHjJdOmmeAqgLyHLuEMmnX6OMvDVapGeLfBg+Rfc8mZ
HeykB0AJlG35c4k=
-----END CERTIFICATE-----]
certificate -----BEGIN CERTIFICATE-----
MIIFVDCCAzygAwIBAgIUIb+Cva1H9g9qYHqmX2BVnF9qN5kwDQYJKoZIhvcNAQEL
...
zBHXPqiK/a+Zykflk7U6uTaIC3AKzeUS
-----END CERTIFICATE-----
expiration 1720589055
issuing_ca -----BEGIN CERTIFICATE-----
MIIFlDCCA3ygAwIBAgIUOTUtY9WdD1jeJVOOBGccEtaXZnkwDQYJKoZIhvcNAQEL
...
EyflgKCWxvsF/KH0geCFV4BA+hSMb/QbZ9MC2YLPnK2HgwkssuWf7w==
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEAwf4u4oRigPLSgnjRRKhNVUMe+XdmQTe8v13DO4HAb+6g6Fw8
...
F4H2z2Reia7RIsh7s1ay0soq5lZz3TrZ7ER5TTZz9Ca4uKGCUUbYb7NpiHg=
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number serial_number 2b:ca:ca:60:09:f7:c4:67:d2:4e:35:9a:65:f8:8e:88:8d:3d:54:2e
ルートCA、中間CAをVault内に設定する事が出来ました。続いて、ルートCAのローテーションを行っていきたいと思います。
Rotate root CA
v1.11以前では、同じPKIシークレットエンジンのマウントポイントで複数のルートCAを有効にすることができませんでした。
v1.11から、PKIシークレットエンジンに、同じシークレットエンジンのマウントポイントに複数のルートCAを含めるマルチ発行者機能を含む新機能が導入されました。これにより、以前より簡単にルートCAのローテーションが可能になりました。
マネージドキーを利用している環境でも問題なく利用出来るかを確認してみます。
ここからはTerraformではなく、vault
CLIを利用して設定していきます。ローテーション用のエンドポイントを利用して、既存のPKIシークレットエンジンのマウントポイントpki/
に新しいルートCAの発行者を作成します。
利用するAPIエンドポイントは以下のドキュメントに記載がある/pki/root/rotate/:type
になります。type
としてkms
を指定する事が出来るので、マネージドキーを指定して作成します。
vault write pki/root/rotate/kms managed_key_name="pki-managed-key" common_name="example.com" issuer_name="root-2024"
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----
MIIFpzCCA4+gAwIBAgIUOpcrMom4nt1vnwVVBnMDxuSgrkkwDQYJKoZIhvcNAQEL
...
P9yO9lK5artZUsg=
-----END CERTIFICATE-----
expiration 1723177470
issuer_id 4c9d2d43-7392-0ce7-f55e-00c852941a75
issuer_name root-2024
issuing_ca -----BEGIN CERTIFICATE-----
MIIFpzCCA4+gAwIBAgIUOpcrMom4nt1vnwVVBnMDxuSgrkkwDQYJKoZIhvcNAQEL
...
P9yO9lK5artZUsg=
-----END CERTIFICATE-----
key_id 25d3c4b0-7bd9-9701-9a25-17466d2abc41
key_name n/a
serial_number 3a:97:2b:32:89:b8:9e:dd:6f:9f:05:55:06:73:03:c6:e4:a0:ae:49
ルートCAのマウントポイントとして定義しているpki/
で、複数のルートCA発行者が作成されている事を確認します。
$ vault list pki/issuers
Keys
----
4c9d2d43-7392-0ce7-f55e-00c852941a75
76254618-5997-53fa-ab69-17e772957c39
それぞれのissuer_name
が違うことから、別のルートCA発行者が同一のルートCAのマウントポイントpki/
で定義されている事が分かると思います。現実点では、デフォルト設定されているroot-2023
のルートCA発行者を介した証明書が発行されます。
$ vault read pki/issuer/76254618-5997-53fa-ab69-17e772957c39 | tail -11
crl_distribution_points []
issuer_id 76254618-5997-53fa-ab69-17e772957c39
issuer_name root-2023
issuing_certificates []
key_id 25d3c4b0-7bd9-9701-9a25-17466d2abc41
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm SHA256WithRSA
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
$ vault read pki/issuer/4c9d2d43-7392-0ce7-f55e-00c852941a75 | tail -11
crl_distribution_points []
issuer_id 4c9d2d43-7392-0ce7-f55e-00c852941a75
issuer_name root-2024
issuing_certificates []
key_id 25d3c4b0-7bd9-9701-9a25-17466d2abc41
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm SHA256WithRSA
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
PKIロールを設定する際に、issuer
を明示的に指定する事が可能です。ルートCAをローテーションした後のテスト用に、pki/
マウントポイントに対してissuer
をroot-2023
に指定して、PKIロール2023-server
を作成しておきます。
vault write pki/roles/2023-server max_ttl=2592000 allow_any_name=true issuer_ref=root-2023
Key Value
--- -----
allow_any_name true
allow_bare_domains false
allow_glob_domains false
allow_ip_sans true
allow_localhost true
allow_subdomains false
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains []
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
allowed_user_ids []
basic_constraints_valid_for_non_ca false
client_flag true
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames true
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref root-2023
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 720h
no_store false
no_store_metadata false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
server_flag true
signature_bits 256
street_address []
ttl 0s
use_csr_common_name true
use_csr_sans true
use_pss false
issuer_ref
がroot-2023
となっている事が確認出来ると思います。
証明書を発行する際は以下の様なコマンドを実行します。
vault write pki/issue/2023-server common_name="test.example.com" ttl="24h"
Create a cross-signed intermediate
ルートCAのローテーションに対しては、create a root bridge CAとcreate a cross-signed intermediate、どちらかを選択して対応する形になりますが、ここでは後者のcreate a cross-signed intermediateの方法を試していきます。
まずは、相互署名用のCSRを作成します。中間CAに対して作業を行いますので、PKIシークレットエンジンのマウントポイントはpki_int/
を使用します。
vault write -format=json pki_int/intermediate/cross-sign \
common_name="example.com Intermediate Authority" \
key_ref="$(vault read pki_int/issuer/$(vault read -field=default pki_int/config/issuers) \
| grep -i key_id | awk '{print $2}')" \
| jq -r '.data.csr' \
| tee cross-signed-intermediate.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIEcjCCAloCAQAwLTErMCkGA1UEAxMiZXhhbXBsZS5jb20gSW50ZXJtZWRpYXRl
...
Uj0vN7DdOu2glNkpAAWLL2tAHyVYN/cHcgoGAnf5SIJH0QnWNks=
-----END CERTIFICATE REQUEST-----
次に、新しいルートCA発行者root-2024
を利用して、先ほど生成したCSRcross-signed-intermediate.csr
に署名します。ルートCAで署名を行いますので、PKIシークレットエンジンのマウントポイントは、pki/
になります。
vault write -format=json pki/issuer/root-2024/sign-intermediate \
common_name="example.com Intermediate Authority" \
csr=@cross-signed-intermediate.csr \
| jq -r '.data.certificate' | tee cross-signed-intermediate.crt
-----BEGIN CERTIFICATE-----
MIIFpjCCA46gAwIBAgIUA5kLiqOI8QfwTFP6tt4K3h6GV+0wDQYJKoZIhvcNAQEL
...
AXyKudEGKZFzbQ==
-----END CERTIFICATE-----
相互署名された証明書cross-signed-intermediate.crt
を、中間CAのマウントポイントpki_int/
に対してインポートします。
vault write pki_int/intermediate/set-signed certificate=@cross-signed-intermediate.crt
Key Value
--- -----
existing_issuers <nil>
existing_keys <nil>
imported_issuers [c38781de-162b-cfad-6da2-ebebe97d9604]
imported_keys <nil>
mapping map[c38781de-162b-cfad-6da2-ebebe97d9604:77cef66b-8ee0-358e-ec91-5c7ce289cf68]
中間CAにインポートした相互署名された証明書の発行者(imported_issuers
= c38781de-162b-cfad-6da2-ebebe97d9604
)の発行者名を、xc-example-dot-com-intermediate
と設定しておきます。
vault write pki_int/issuer/c38781de-162b-cfad-6da2-ebebe97d9604 issuer_name=xc-example-dot-com-intermediate
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIFpjCCA46gAwIBAgIUA5kLiqOI8QfwTFP6tt4K3h6GV+0wDQYJKoZIhvcNAQEL
...
AXyKudEGKZFzbQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFpzCCA4+gAwIBAgIUI0S0LGnYhhQH6gJ9WO7c46L3GIYwDQYJKoZIhvcNAQEL
...
s57ytXUtfUn/0GY=
-----END CERTIFICATE-----
]
certificate -----BEGIN CERTIFICATE-----
MIIFpjCCA46gAwIBAgIUA5kLiqOI8QfwTFP6tt4K3h6GV+0wDQYJKoZIhvcNAQEL
...
AXyKudEGKZFzbQ==
-----END CERTIFICATE-----
crl_distribution_points []
issuer_id c38781de-162b-cfad-6da2-ebebe97d9604
issuer_name xc-example-dot-com-intermediate
issuing_certificates []
key_id 77cef66b-8ee0-358e-ec91-5c7ce289cf68
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm n/a
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
Set default issuer in root CA
中間CA側の作業が全て完了した上で、ルートCAでデフォルトの発行者を変更していきます。
ルートCAの現在のデフォルト発行者を確認します。
vault read pki/issuer/default | tail -11
crl_distribution_points []
issuer_id 76254618-5997-53fa-ab69-17e772957c39
issuer_name root-2023
issuing_certificates []
key_id 25d3c4b0-7bd9-9701-9a25-17466d2abc41
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm SHA256WithRSA
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
/pki/root/replace
エンドポイントを利用して、デフォルトの発行者を更新する事が出来ます。
vault write pki/root/replace default=root-2024
Key Value
--- -----
default 4c9d2d43-7392-0ce7-f55e-00c852941a75
default_follows_latest_issuer false
変更されたか確認してみます。ルートCAのデフォルトのissuer_name
がroot-2024
に変更されている事が分かります。
vault read pki/issuer/default | tail -11
crl_distribution_points []
issuer_id 4c9d2d43-7392-0ce7-f55e-00c852941a75
issuer_name root-2024
issuing_certificates []
key_id 25d3c4b0-7bd9-9701-9a25-17466d2abc41
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm SHA256WithRSA
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
Sunset old root CA
続いて、古いルートCAの発行者であるroot-2023
を、CRLに署名したり、証明書を失効させたりする機能は保持したまま、証明書を発行する機能を削除していきます。
vault write pki/issuer/root-2023 issuer_name="root-2023" usage=read-only,crl-signing | tail -n 11
crl_distribution_points []
issuer_id 76254618-5997-53fa-ab69-17e772957c39
issuer_name root-2023
issuing_certificates []
key_id 25d3c4b0-7bd9-9701-9a25-17466d2abc41
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm n/a
revoked false
usage crl-signing,read-only
usage
からissuing-certificates
が削除され、crl-signing
とread-only
だけが古いルートCAの発行者root-2023
で使用可能な様に変更しました。これは、今後古いルートCAの発行者であるroot-2023
を介して、証明書が発行できないことを意味します。
作成しておいたルートCAの発行者root-2023
を用いたPKIロール2023-server
を利用して、証明書を発行しようとしてみます。以下の様にルートCAの発行者にissuing-certificates
の機能がないため、証明書を発行出来なくなっているのが分かります。
vault write pki/issue/2023-server common_name="test.example.com" ttl="24h"
Error writing data to pki/issue/2023-server: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/pki/issue/2023-server
Code: 500. Errors:
* 1 error occurred:
* error fetching CA certificate: error while attempting to use issuer 76254618-5997-53fa-ab69-17e772957c39: requested usage issuing-certificates for issuer [id:76254618-5997-53fa-ab69-17e772957c39 / name:root-2023] but only had usage crl-signing,read-only
Set default issuer in intermediate CA
中間CA側の証明書の発行者を確認してみます。デフォルトの発行者は、example-dot-com-intermediate
となっている事が分かります。
$ vault read pki_int/issuer/default |tail -11
crl_distribution_points []
issuer_id 2cc72790-a41f-1652-9bdf-72737eaf4cb0
issuer_name example-dot-com-intermediate
issuing_certificates []
key_id 77cef66b-8ee0-358e-ec91-5c7ce289cf68
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm n/a
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
Create a cross-signed intermediateで中間CAにインポートした相互署名された証明書の発行者(xc-example-dot-com-intermediate
)の情報を改めて確認しておきます。
$ vault read pki_int/issuer/c38781de-162b-cfad-6da2-ebebe97d9604 |tail -11
crl_distribution_points []
issuer_id c38781de-162b-cfad-6da2-ebebe97d9604
issuer_name xc-example-dot-com-intermediate
issuing_certificates []
key_id 77cef66b-8ee0-358e-ec91-5c7ce289cf68
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm n/a
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
ルートCAで行った時と同様に、デフォルトの発行者を相互署名されているxc-example-dot-com-intermediate
に変更します。
vault write pki_int/root/replace default=xc-example-dot-com-intermediate
Key Value
--- -----
default c38781de-162b-cfad-6da2-ebebe97d9604
default_follows_latest_issuer false
中間CAのデフォルト発行者が変更された事を確認します。
$ vault read pki_int/issuer/default |tail -11
crl_distribution_points []
issuer_id c38781de-162b-cfad-6da2-ebebe97d9604
issuer_name xc-example-dot-com-intermediate
issuing_certificates []
key_id 77cef66b-8ee0-358e-ec91-5c7ce289cf68
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm n/a
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only
中間CAに設定したPKIロールexample-dot-com
の設定を確認してみます。issuer_ref
が2cc72790-a41f-1652-9bdf-72737eaf4cb0
となっており、発行者はexample-dot-com-intermediate
となっている事が分かります。
vault read pki_int/roles/example-dot-com
Key Value
--- -----
allow_any_name false
allow_bare_domains false
allow_glob_domains false
allow_ip_sans true
allow_localhost true
allow_subdomains true
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains [example.com]
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
allowed_user_ids []
basic_constraints_valid_for_non_ca false
client_flag true
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames true
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref 2cc72790-a41f-1652-9bdf-72737eaf4cb0
key_bits 4096
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 720h
no_store false
no_store_metadata false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
server_flag true
signature_bits 256
street_address []
ttl 24h
use_csr_common_name true
use_csr_sans true
use_pss false
問題なく証明書を発行出来る事を確認します。
vault write pki_int/issue/example-dot-com common_name="test.example.com" ttl="24h"
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIFlDCCA3ygAwIBAgIUW+aRTRuWs21kn13FS44Q+eF7wHMwDQYJKoZIhvcNAQEL
...
K0V0Tfh8Ipmw6SQCnxA3xFLAa3RQcHoiaOAP3+q1boEyWtBto+CxOA==
-----END CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIFpzCCA4+gAwIBAgIUI0S0LGnYhhQH6gJ9WO7c46L3GIYwDQYJKoZIhvcNAQEL
...
s57ytXUtfUn/0GY=
-----END CERTIFICATE-----]
certificate -----BEGIN CERTIFICATE-----
MIIFVDCCAzygAwIBAgIUMu8JF4p/1zsUXALmgpSy4FhujvowDQYJKoZIhvcNAQEL
...
Fo/cHeXHG523zr7AWH3Sb0nbmzt7Aj3p
-----END CERTIFICATE-----
expiration 1720773506
issuing_ca -----BEGIN CERTIFICATE-----
MIIFlDCCA3ygAwIBAgIUW+aRTRuWs21kn13FS44Q+eF7wHMwDQYJKoZIhvcNAQEL
...
K0V0Tfh8Ipmw6SQCnxA3xFLAa3RQcHoiaOAP3+q1boEyWtBto+CxOA==
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIJKAIBAAKCAgEAvYqT5tlnChIsQVz8zdmPgQ+PvtzVIJUsZOqWgqpkQuxu0EU3
...
3XFdAu8h+GjHMtex6SDc8KGvHOs6Bxp3pJs6t3GDnmepXybjTIbF3Mn7DXA=
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number 32:ef:09:17:8a:7f:d7:3b:14:5c:02:e6:82:94:b2:e0:58:6e:8e:fa
Sunset old root CAで実施したのと同様に、中間CAの発行者example-dot-com-intermediate
から証明書が発行できない様に設定を変更します。
vault write pki_int/issuer/2cc72790-a41f-1652-9bdf-72737eaf4cb0 issuer_name="example-dot-com-intermediate" usage=read-only,crl-signing | tail -n 11
crl_distribution_points []
issuer_id 2cc72790-a41f-1652-9bdf-72737eaf4cb0
issuer_name example-dot-com-intermediate
issuing_certificates []
key_id 77cef66b-8ee0-358e-ec91-5c7ce289cf68
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm n/a
revoked false
usage crl-signing,read-only
先ほどと同様に証明書の発行をPKIロールexample-dot-com
で試みてみますが、以下の様に発行者example-dot-com-intermediate
を介して、新たな証明書は発行出来ないため、エラーが返ります。
vault write pki_int/issue/example-dot-com common_name="test.example.com" ttl="24h"
Error writing data to pki_int/issue/example-dot-com: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/pki_int/issue/example-dot-com
Code: 500. Errors:
* 1 error occurred:
* error fetching CA certificate: error while attempting to use issuer 2cc72790-a41f-1652-9bdf-72737eaf4cb0: requested usage issuing-certificates for issuer [id:2cc72790-a41f-1652-9bdf-72737eaf4cb0 / name:example-dot-com-intermediate] but only had usage crl-signing,read-only
PKIロールexample-dot-com
を更新し、デフォルト発行者になっているxc-example-dot-com-intermediate
を発行者に変更します。
vault write pki_int/roles/example-dot-com ttl=86400 max_ttl=2592000 allow_ip_sans=true key_type=rsa key_bits=4096 allowed_domains="example.com" allow_subdomains=true
Key Value
--- -----
allow_any_name false
allow_bare_domains false
allow_glob_domains false
allow_ip_sans true
allow_localhost true
allow_subdomains true
allow_token_displayname false
allow_wildcard_certificates true
allowed_domains [example.com]
allowed_domains_template false
allowed_other_sans []
allowed_serial_numbers []
allowed_uri_sans []
allowed_uri_sans_template false
allowed_user_ids []
basic_constraints_valid_for_non_ca false
client_flag true
cn_validations [email hostname]
code_signing_flag false
country []
email_protection_flag false
enforce_hostnames true
ext_key_usage []
ext_key_usage_oids []
generate_lease false
issuer_ref default
key_bits 4096
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 720h
no_store false
no_store_metadata false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
server_flag true
signature_bits 256
street_address []
ttl 24h
use_csr_common_name true
use_csr_sans true
use_pss false
issuer_ref
が変更され、default
(発行者名xc-example-dot-com-intermediate
)に更新されている事が分かります。
この状態で再度PKIロールexample-dot-com
を用いて、証明書を発行してみます。今回は問題なく証明書を発行する事が出来ています。
vault write pki_int/issue/example-dot-com common_name="test.example.com" ttl="24h"
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIFpjCCA46gAwIBAgIUA5kLiqOI8QfwTFP6tt4K3h6GV+0wDQYJKoZIhvcNAQEL
...
AXyKudEGKZFzbQ==
-----END CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIFpzCCA4+gAwIBAgIUI0S0LGnYhhQH6gJ9WO7c46L3GIYwDQYJKoZIhvcNAQEL
...
s57ytXUtfUn/0GY=
-----END CERTIFICATE-----]
certificate -----BEGIN CERTIFICATE-----
MIIFZjCCA06gAwIBAgIUIOKWoLpJTI5vgmpXRj+xBm6IxXowDQYJKoZIhvcNAQEL
...
BdOKOqKfx85HxeyYkTPiSSofA1LCIXq7hImXFAyW3n0xQqKebnWhbXj8
-----END CERTIFICATE-----
expiration 1720774352
issuing_ca -----BEGIN CERTIFICATE-----
MIIFpjCCA46gAwIBAgIUA5kLiqOI8QfwTFP6tt4K3h6GV+0wDQYJKoZIhvcNAQEL
...
AXyKudEGKZFzbQ==
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIJJwIBAAKCAgEA6l3BhWBvQHZE+TwpSioPa0OMzoLVskb89Xot8ddQu4wn86yp
...
vUcXi7hNGvP3PhZ7ypjyKIlWz07GHIl/4dm0OvVO+gU6zHsSJpzZnVgHAA==
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number 20:e2:96:a0:ba:49:4c:8e:6f:82:6a:57:46:3f:b1:06:6e:88:c5:7a
PKIロールを作成する際、issuer_ref
をdefault
と指定しておけば、デフォルトの発行者を変更した際に、PKIロール側を変更する必要は無いと思いますので、実際に運用される際はその様に設定しておいた方が良いかと思います。
マネージドキーの機能を利用して、PKIシークレットエンジンを設定し、その環境下でのルートCAのローテーション等を行ってみました。参考になりそうな部分があれば、ご活用下さい!
Discussion