
官方文档 https://developer.hashicorp.com/vault/tutorials/pki/pki-engine?variants=vault-deploy%3Aselfhosted
企业内部对安全要求比较高的话,会需要启用TLS加密(例如elasticsearch节点、和其它kibana、filebeat等组件之间)。目前外采的付费版的SSL证书基本上有效期都是1年的,每年更换证书既容易遗漏掉,工作量也是挺大的。
因此有时候,我们会考虑使用自建的CA体系。

> export VAULT_ADDR='http://192.168.31.181:8200'
$ vault login hvs.R6BvAMswb8gBJWbFnSTrxI5c
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token hvs.R6BvAMswb8gBJWbFnSTrxI5c
token_accessor vrf79v2YaUzEBmR0jsCqXLJy
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]1 在 pki 路径上启用 pki 密钥引擎。
$ vault secrets enable pki2 优化 pki 密钥引擎以颁发最长生存时间 (TTL) 为 10年的证书。
$ vault secrets tune -max-lease-ttl=3650d pki3 生成 example.com 的根 CA,为其指定颁发者名称,并将其证书保存在文件 root_2023_ca.crt 中。
这将生成新的自签名 CA 证书和私有密钥。库 在租约期 (TTL) 结束时自动撤销生成的根。CA 证书对其自己的证书吊销列表 (CRL) 进行签名。
$ vault write -field=certificate pki/root/generate/internal \
common_name="example.com" \
issuer_name="root-2023" \
ttl=3650d > root_2023_ca.crt查看下根证书文件的内容
> cat /root/root_2023_ca.crt
-----BEGIN CERTIFICATE-----
MIIDNTCCAh2gAwIBAgIUZgu7wTTdRf/ChofBK9AisqCDdSswDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMjUwNjI4MTAxMzU4WhcNMzUw
NjI2MTAxNDI3WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALZqsRMNpbc4FPbfqzP7yB/5B1bySPuMKPGC0J1s
3FDqgHU57tP7vK/wODUtCwC62N/PD5xXmu229/LH7I0+HdV1mVpl7lSRM5YifqJN
gjqOaItgGjAPn5V2sdSGWhVBMnybAclPYNDWlZgTMcgKSPPVwJ5vEt1w4sD05Mzg
T63HXQTmtl8ffSqWOp01yVkLIkz3Sr78csJc6YSUh+BycVH/RAX+aXBhg5yNDrJq
ipseLO52Qu2oi9dxqY8P2BwlODAGnxHnFn9TKwX1S6+9INVi0pK1YBP5+c/2XJ4h
sVJxny9/Z+U7/leEYnN7F7HUX0QS3yPVEWDNGH8gzD8tgWkCAwEAAaN7MHkwDgYD
VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMlrRPrcOrLM
BACMOdhV1GxZLUUFMB8GA1UdIwQYMBaAFMlrRPrcOrLMBACMOdhV1GxZLUUFMBYG
A1UdEQQPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBcgeh2NUpD
PMXWZg/04cwuef4mpUwqx31KGNflDoqQRVHtrI149Ma/My6aJka5FHtE68veOFUp
NTHMk8hvdf0NlFaDYKyARJCMdxeQbRvubRwYhJLXGA2fJln5TXONJyjU56GQb2zL
dkAukFJFzFBwDhYISWBWhU74P04CEpN+6jvVnoVxFWK9SlHkrFv+26b1sqn0GwlV
nr90PomwV/RIMowiDgJhYOltr/5Ewssea0ri2mkn3x7KzdbEu+jnw+z3muLzy+i7
NY8KbEMJPEFBkYfpvUenGW2bPT1RZPdM3x29VXWqZiGxaAn9ydeWOR7RBUeHxWo4
QjJ3geelWMr/
-----END CERTIFICATE-----#4 列出根 CA 的颁发者信息。
$ vault list pki/issuers/
Keys
----
10bee018-3e6e-ad07-b16e-42b93a8506735 您可以使用其 ID 读取颁发者,以获取有关颁发者的证书和其他元数据。使用如下的命令跳过证书内容的输出,但列出颁发者元数据和使用情况信息。
$ vault read pki/issuer/$(vault list -format=json pki/issuers/ | jq -r '.[]') | tail -n 13
输出结果如下:
crl_distribution_points []
delta_crl_distribution_points []
enable_aia_url_templating false
issuer_id 10bee018-3e6e-ad07-b16e-42b93a850673
issuer_name root-2023
issuing_certificates []
key_id 02cae863-9362-80b9-b250-bfca8046d512
leaf_not_after_behavior err
manual_chain <nil>
ocsp_servers []
revocation_signature_algorithm SHA256WithRSA
revoked false
usage crl-signing,issuing-certificates,ocsp-signing,read-only6 为根 CA 创建角色。创建此角色允许在必要时为此方案指定颁发者。这也提供了一种简单的方法,通过名称引用一个颁发者来从一个颁发者过渡到另一个颁发者。
$ vault write pki/roles/2023-servers allow_any_name=true
输出结果如下:
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 default
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 0s
no_store false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
serial_number_source json-csr
server_flag true
signature_bits 256
street_address []
ttl 0s
use_csr_common_name true
use_csr_sans true
use_pss false操作完成后,可以在web ui上看如下:

7 配置 CA 和 CRL URL
$ vault write pki/config/urls \
issuing_certificates="$VAULT_ADDR/v1/pki/ca" \
crl_distribution_points="$VAULT_ADDR/v1/pki/crl"
输出结果如下:
Key Value
--- -----
crl_distribution_points [http://192.168.31.181:8200/v1/pki/crl]
delta_crl_distribution_points []
enable_templating false
issuing_certificates [http://192.168.31.181:8200/v1/pki/ca]
ocsp_servers []注意:
当在同一挂载中使用多个颁发者时,建议使用每个颁发者 AIA 字段,而不是全局 (/config/urls) 变体。这是为了正确性:某些应用程序需要这些字段来构建链和自动 CRL 检测。如果它们指向错误的发行者信息,这些应用程序可能会中断。
1 首先,在 pki_int 路径启用 pki 密钥引擎。
$ vault secrets enable -path=pki_int pki2 优化 pki_int 密钥引擎以颁发最大生存时间 (TTL) 为 3650d 的证书。
$ vault secrets tune -max-lease-ttl=3650d pki_int3 执行以下命令生成一个中间文件,并将 CSR 另存为 pki_intermediate.csr。
$ vault write -format=json pki_int/intermediate/generate/internal \
common_name="example.com Intermediate Authority" \
issuer_name="example-dot-com-intermediate" \
| jq -r '.data.csr' > pki_intermediate.csr4 使用根 CA 私有密钥对中间证书进行签名,并将生成的证书另存为 intermediate.cert.pem,这个文件实际上也就是证书链文件
$ vault write -format=json pki/root/sign-intermediate \
issuer_ref="root-2023" \
csr=@pki_intermediate.csr \
format=pem_bundle ttl="3650d" \
| jq -r '.data.certificate' > intermediate.cert.pem5 签署 CSR 并且根 CA 返回证书后,可以将其导入回 Vault。
$ vault write pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
WARNING! The following warnings were returned from Vault:
* This mount hasn't configured any authority information access (AIA)
fields; this may make it harder for systems to find missing certificates
in the chain or to validate revocation status of certificates. Consider
updating /config/urls or the newly generated issuer with this information.
Key Value
--- -----
existing_issuers <nil>
existing_keys <nil>
imported_issuers [4deef04b-83a2-ceef-5d13-9527ba044c70 fc640e82-05f1-f95f-7e2e-86356de67c06]
imported_keys <nil>
mapping map[4deef04b-83a2-ceef-5d13-9527ba044c70:32f23f46-babc-601d-37a3-8c96c7f8f122 fc640e82-05f1-f95f-7e2e-86356de67c06:]角色是映射到用于生成这些凭证的策略的逻辑名称。它允许配置参数控制证书公用名、备用名称、它们有效的密钥用途等。
创建一个名为 example-dot-com 的角色,该角色允许子域,并将默认颁发者 ref ID 指定为 issuer_ref 的值。
$ vault write pki_int/roles/example-dot-com \
issuer_ref="$(vault read -field=default pki_int/config/issuers)" \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="3650d"
输出结果如下:
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 4deef04b-83a2-ceef-5d13-9527ba044c70
key_bits 2048
key_type rsa
key_usage [DigitalSignature KeyAgreement KeyEncipherment]
locality []
max_ttl 87600h
no_store false
not_after n/a
not_before_duration 30s
organization []
ou []
policy_identifiers []
postal_code []
province []
require_cn true
serial_number_source json-csr
server_flag true
signature_bits 256
street_address []
ttl 0s
use_csr_common_name true
use_csr_sans true
use_pss false操作完成后,在web ui看到的如下:

执行以下命令以请求 test.example.com 域 example-dot-com
$ vault write pki_int/issue/example-dot-com common_name="test.example.com" ttl="3600d" 注意这里的ttl值必须小于 步骤3中的max_ttl值。
输出结果比较长,具体如下:
Key Value
--- -----
ca_chain [-----BEGIN CERTIFICATE-----
MIIDsDCCApigAwIBAgIURjYkXHWoC3WreNdW26ozel0iqtYwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMjUwNjI4MTAyNTE1WhcNMzUw
NjI2MTAxNDI3WjAtMSswKQYDVQQDEyJleGFtcGxlLmNvbSBJbnRlcm1lZGlhdGUg
QXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyBRCuWtq
B3Gq0UsWp7A0hHZMJHu/iQv7O9ssw343M/erOhRzI1FtQIkUftvryRhBk+t9gYC3
zBp2zkYE7BPRKzZF8TtjlDvh8EaRfnIRrU4CWpWLMtLY8/vleKuqwXOiyJzgLa4G
ZkqmbuUn0nG62g5JwSVmvPN380sN/6YDu45Fk9FDBQdMLqXkWwMCPhri2lf6g0Ck
uXweONcQFsC1trSrD6aRwz5VGQQ9QwjG/5KHuL50iOD24PUHbB024UK+u82c6a/u
MYCtOQ3anFjaSQzioAHkNEvUi+Nza+sgtLXjgcoFl0/uXjfREUBUN7VYiFUWxfa2
mKGWILp9LcTHTQIDAQABo4HeMIHbMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBQZU/aGxQIzn4UCrUUCiXUXECDsazAfBgNVHSMEGDAW
gBTJa0T63DqyzAQAjDnYVdRsWS1FBTBABggrBgEFBQcBAQQ0MDIwMAYIKwYBBQUH
MAKGJGh0dHA6Ly8xOTIuMTY4LjMxLjE4MTo4MjAwL3YxL3BraS9jYTA2BgNVHR8E
LzAtMCugKaAnhiVodHRwOi8vMTkyLjE2OC4zMS4xODE6ODIwMC92MS9wa2kvY3Js
MA0GCSqGSIb3DQEBCwUAA4IBAQALcTi6M6CzEXBMRxeMS/DPowAT6FD/fm+0c4rO
v11tRO3SgNNoOuVWd7qy8qKyS7HtEh6nK1faKoRv+NZbrQGFhV5MBPys7mr8BVIZ
fdR0MyeTIgc3efkrw1BsdaMQLf6YYtPREAQo6gy4jVSslXGDqOe8Rg/xw76pc1Xh
bl8x869zGvneitlAb32yZ4bZxV5laxt9edIhjRR+nf7D8l9YSFtU9KpKXUDK3IDq
CAxwkqtjqLncxEqMzoj7W6Ies63kEihljGOCMPs3SUcAshsRKJh6WfMCKHfmYWTw
Tr0/Ng2KqaABt7tIgns7BNzNMRVH1eTFtcJlTxMZA3EadlhL
-----END CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIDNTCCAh2gAwIBAgIUZgu7wTTdRf/ChofBK9AisqCDdSswDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMjUwNjI4MTAxMzU4WhcNMzUw
NjI2MTAxNDI3WjAWMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALZqsRMNpbc4FPbfqzP7yB/5B1bySPuMKPGC0J1s
3FDqgHU57tP7vK/wODUtCwC62N/PD5xXmu229/LH7I0+HdV1mVpl7lSRM5YifqJN
gjqOaItgGjAPn5V2sdSGWhVBMnybAclPYNDWlZgTMcgKSPPVwJ5vEt1w4sD05Mzg
T63HXQTmtl8ffSqWOp01yVkLIkz3Sr78csJc6YSUh+BycVH/RAX+aXBhg5yNDrJq
ipseLO52Qu2oi9dxqY8P2BwlODAGnxHnFn9TKwX1S6+9INVi0pK1YBP5+c/2XJ4h
sVJxny9/Z+U7/leEYnN7F7HUX0QS3yPVEWDNGH8gzD8tgWkCAwEAAaN7MHkwDgYD
VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMlrRPrcOrLM
BACMOdhV1GxZLUUFMB8GA1UdIwQYMBaAFMlrRPrcOrLMBACMOdhV1GxZLUUFMBYG
A1UdEQQPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBcgeh2NUpD
PMXWZg/04cwuef4mpUwqx31KGNflDoqQRVHtrI149Ma/My6aJka5FHtE68veOFUp
NTHMk8hvdf0NlFaDYKyARJCMdxeQbRvubRwYhJLXGA2fJln5TXONJyjU56GQb2zL
dkAukFJFzFBwDhYISWBWhU74P04CEpN+6jvVnoVxFWK9SlHkrFv+26b1sqn0GwlV
nr90PomwV/RIMowiDgJhYOltr/5Ewssea0ri2mkn3x7KzdbEu+jnw+z3muLzy+i7
NY8KbEMJPEFBkYfpvUenGW2bPT1RZPdM3x29VXWqZiGxaAn9ydeWOR7RBUeHxWo4
QjJ3geelWMr/
-----END CERTIFICATE-----]
certificate -----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIUaLO3+N91dfMuH2P0MyqzjiFAm5swDQYJKoZIhvcNAQEL
BQAwLTErMCkGA1UEAxMiZXhhbXBsZS5jb20gSW50ZXJtZWRpYXRlIEF1dGhvcml0
eTAeFw0yNTA2MjgxMTMxMDNaFw0zNTA1MDcxMTMxMzJaMBsxGTAXBgNVBAMTEHRl
c3QuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL
SOHCtZpJYBZkkgMlKUCj/qaz6mZ0QLjO4p78KRcHpjsaTQEfA/b8bVM3CKSSSaR0
Ix5oDM0dsw58Zbk3pbnBCMTowv1gdoKWXNo57Yl3EAomSkJlXfHbUgIsKVwko6rS
4rwM7Z6axbE5D0y+Jacn/q5DsgisDrg7Z69z2xdnG1yHbq9AjJT/xENExHMXouRi
CQfdLSpjsrzYdjKmQIwfluOdHZNYcqmcglB4o5MgqBdc1CeUohCjSzROMG2aavlv
EMQUo3ZaKcuMatKMJDZGGaXu7uailfKwq2ZMcVFz4J3tLV8fDGt+JHnCCR/ETSeW
6LibH+6Y5gWiTd1fX3tNAgMBAAGjgY8wgYwwDgYDVR0PAQH/BAQDAgOoMB0GA1Ud
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUdP3mWQzuiXmRK8eZ
hJ7BVDKqrHMwHwYDVR0jBBgwFoAUGVP2hsUCM5+FAq1FAol1FxAg7GswGwYDVR0R
BBQwEoIQdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEASHyHKDTk
vKnXKG8h8uD6i8sumRn5PWD8fagm/b9z/5N0vRAAP3R0Rf+66seyGAdVacfJZT0Y
nnXpLf7B1SIvQZU1LZIz/BznBL62UzrmBdEHzM//0heiInMP2y3Ij+FvrHfMldrj
9JD/lENqs0FL8UIV1tFk/uSe32z1KIxBAPMltQHsLkZZEW8G78+7uhiJiuwmYdKu
RpustZTpguYWuXrIFTPLp0mdCOYtXQ7+DtwxYQkw3d9OYYH/ee7Q8OpWsXpIpNfP
ZPIyqf0DF0p/6vPvGj3AAGYcruafIu38HEM2khCK0v+lnx9DY2Xe9GmXB4zbUuCI
zJSlgNipnyrL0w==
-----END CERTIFICATE-----
expiration 2062150292
issuing_ca -----BEGIN CERTIFICATE-----
MIIDsDCCApigAwIBAgIURjYkXHWoC3WreNdW26ozel0iqtYwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMjUwNjI4MTAyNTE1WhcNMzUw
NjI2MTAxNDI3WjAtMSswKQYDVQQDEyJleGFtcGxlLmNvbSBJbnRlcm1lZGlhdGUg
QXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyBRCuWtq
B3Gq0UsWp7A0hHZMJHu/iQv7O9ssw343M/erOhRzI1FtQIkUftvryRhBk+t9gYC3
zBp2zkYE7BPRKzZF8TtjlDvh8EaRfnIRrU4CWpWLMtLY8/vleKuqwXOiyJzgLa4G
ZkqmbuUn0nG62g5JwSVmvPN380sN/6YDu45Fk9FDBQdMLqXkWwMCPhri2lf6g0Ck
uXweONcQFsC1trSrD6aRwz5VGQQ9QwjG/5KHuL50iOD24PUHbB024UK+u82c6a/u
MYCtOQ3anFjaSQzioAHkNEvUi+Nza+sgtLXjgcoFl0/uXjfREUBUN7VYiFUWxfa2
mKGWILp9LcTHTQIDAQABo4HeMIHbMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MB0GA1UdDgQWBBQZU/aGxQIzn4UCrUUCiXUXECDsazAfBgNVHSMEGDAW
gBTJa0T63DqyzAQAjDnYVdRsWS1FBTBABggrBgEFBQcBAQQ0MDIwMAYIKwYBBQUH
MAKGJGh0dHA6Ly8xOTIuMTY4LjMxLjE4MTo4MjAwL3YxL3BraS9jYTA2BgNVHR8E
LzAtMCugKaAnhiVodHRwOi8vMTkyLjE2OC4zMS4xODE6ODIwMC92MS9wa2kvY3Js
MA0GCSqGSIb3DQEBCwUAA4IBAQALcTi6M6CzEXBMRxeMS/DPowAT6FD/fm+0c4rO
v11tRO3SgNNoOuVWd7qy8qKyS7HtEh6nK1faKoRv+NZbrQGFhV5MBPys7mr8BVIZ
fdR0MyeTIgc3efkrw1BsdaMQLf6YYtPREAQo6gy4jVSslXGDqOe8Rg/xw76pc1Xh
bl8x869zGvneitlAb32yZ4bZxV5laxt9edIhjRR+nf7D8l9YSFtU9KpKXUDK3IDq
CAxwkqtjqLncxEqMzoj7W6Ies63kEihljGOCMPs3SUcAshsRKJh6WfMCKHfmYWTw
Tr0/Ng2KqaABt7tIgns7BNzNMRVH1eTFtcJlTxMZA3EadlhL
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAy0jhwrWaSWAWZJIDJSlAo/6ms+pmdEC4zuKe/CkXB6Y7Gk0B
HwP2/G1TNwikkkmkdCMeaAzNHbMOfGW5N6W5wQjE6ML9YHaCllzaOe2JdxAKJkpC
ZV3x21ICLClcJKOq0uK8DO2emsWxOQ9MviWnJ/6uQ7IIrA64O2evc9sXZxtch26v
QIyU/8RDRMRzF6LkYgkH3S0qY7K82HYypkCMH5bjnR2TWHKpnIJQeKOTIKgXXNQn
lKIQo0s0TjBtmmr5bxDEFKN2WinLjGrSjCQ2Rhml7u7mopXysKtmTHFRc+Cd7S1f
HwxrfiR5wgkfxE0nlui4mx/umOYFok3dX197TQIDAQABAoIBAEh6NbO8F8QtdA5r
WJ+5M4jE1B61Zc3w/XMVrWVuKP3bMJtR9SJfwYGCYPbwJ+zYQL//fWnPlpoOKw4D
HqROfAns3He4faoU1r5RYKTioe5HU7cPJtkJQ5/Uf13LaUTO7aq+mBlr5u57qZIU
eGIa/pvt26fbI+hkXx8e+pkt9gwWO6oQ4UTs0xcBjNf+DndzI2O3tRO9KudnxC3Y
kkDX2ELNkt8C2iSkBNv35ycK9Z2zSi7qMq+DMAues/5FAyKg1fNksXAYuk2qHYFF
tlSBrHPaYyoH7kHE47FSqrR5LrMXk7APEGvcq37Q8cA+ZZBS2hMKMxPWIco9cgTg
nWbPbakCgYEAzL6EO3PAIKyg3uJSckJDbuam0hiNBM3I02ENqO5qz9840yLVac/+
2fYBdA7BTx6lqks5HvygkXfSZ93Cd65xBZqjtH6UfU6HiXwom8MCsbQEOZiNOZRX
901rW2gHZq7swatMqJPWKeZ+Pk+AoK6fxwrS3aF1BnzExvzaMwMlqV8CgYEA/izU
VA0nWJBaly6XW8ZB/++HMGfYwsb9WkZLgNQDTPPO3zDV1XCLX0juFLexWbcw/Z8F
y0li5rfKDZ4EjDMPT3xl0h0lL/mYc1QsTmH35WffIrU6NYGNqRrqA9iPe82VPCvC
mbgZGSBPkDZtLI42K6cDL1Y2Hm0U8vrhZgtcXtMCgYEArYWd3iEoqMiFgsB/LXT5
X6k9ovvJsFOTq4oqoIyHm+tMZqy0AHyWOjWjX7ANpzeLIfukyp1CnGbXvM2WPgZq
pVw8+AD7agO/HQdMB07MHr05g3LF5hHSR7amkQ5mj2EbKLw8OPcqX9KIFdkdY5D7
ux5yPgHTg48E2rx7VRaKubMCgYEAx8IPtWcJDy+UItD5H6V25WAojUBwONQO9U3d
tQfq+CV85igJRk/HGUHF6v5bIbk5hXnfId8xHUZAQ+d2h4DxfXS0yScivMuaprj2
gTu5ic/SrAJmFvsUjFycoh0m1xPBP6Lcs9bd0sN0BFDiCGxT4obFmARXUB5GopfN
YVd4ZwUCgYA5CJC7NG29yMwmwNSMX1seg8D9GhaM7rGimTx0dwyjv8aA5aLCCcqu
g22HZwRuu0IAQfQOw9uK/mkozz1Z4MNWRrU9U+s1Cas9J5Ges7mJir9ERsMCrDaG
T6pq9P+M1AW2ZqabmbXSmquKokyAdZHcMDFRTE0gzoz5JAJDxKhMYA==
-----END RSA PRIVATE KEY-----
private_key_type rsa
serial_number 68:b3:b7:f8:df:75:75:f3:2e:1f:63:f4:33:2a:b3:8e:21:40:9b:9b说明:
ca_chain : 根证书和中间证书的合并,将这个证书的下半截(也就是根CA证书)文件导入到windows的“收信任的根证书颁发机构”。
issuing_ca : 中间证书,将这个证书文件导入到windows的“中间证书颁发机构”
certificate : 域名证书,放到nginx的ssl_certificate
private_key :test.example.com 的私钥,放到nginx的ssl_certificate_key
将 certificate 段 的内容 另存为 test.example.com.crt
-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIUaLO3+N91dfMuH2P0MyqzjiFAm5swDQYJKoZIhvcNAQEL
BQAwLTErMCkGA1UEAxMiZXhhbXBsZS5jb20gSW50ZXJtZWRpYXRlIEF1dGhvcml0
eTAeFw0yNTA2MjgxMTMxMDNaFw0zNTA1MDcxMTMxMzJaMBsxGTAXBgNVBAMTEHRl
c3QuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL
SOHCtZpJYBZkkgMlKUCj/qaz6mZ0QLjO4p78KRcHpjsaTQEfA/b8bVM3CKSSSaR0
Ix5oDM0dsw58Zbk3pbnBCMTowv1gdoKWXNo57Yl3EAomSkJlXfHbUgIsKVwko6rS
4rwM7Z6axbE5D0y+Jacn/q5DsgisDrg7Z69z2xdnG1yHbq9AjJT/xENExHMXouRi
CQfdLSpjsrzYdjKmQIwfluOdHZNYcqmcglB4o5MgqBdc1CeUohCjSzROMG2aavlv
EMQUo3ZaKcuMatKMJDZGGaXu7uailfKwq2ZMcVFz4J3tLV8fDGt+JHnCCR/ETSeW
6LibH+6Y5gWiTd1fX3tNAgMBAAGjgY8wgYwwDgYDVR0PAQH/BAQDAgOoMB0GA1Ud
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUdP3mWQzuiXmRK8eZ
hJ7BVDKqrHMwHwYDVR0jBBgwFoAUGVP2hsUCM5+FAq1FAol1FxAg7GswGwYDVR0R
BBQwEoIQdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEASHyHKDTk
vKnXKG8h8uD6i8sumRn5PWD8fagm/b9z/5N0vRAAP3R0Rf+66seyGAdVacfJZT0Y
nnXpLf7B1SIvQZU1LZIz/BznBL62UzrmBdEHzM//0heiInMP2y3Ij+FvrHfMldrj
9JD/lENqs0FL8UIV1tFk/uSe32z1KIxBAPMltQHsLkZZEW8G78+7uhiJiuwmYdKu
RpustZTpguYWuXrIFTPLp0mdCOYtXQ7+DtwxYQkw3d9OYYH/ee7Q8OpWsXpIpNfP
ZPIyqf0DF0p/6vPvGj3AAGYcruafIu38HEM2khCK0v+lnx9DY2Xe9GmXB4zbUuCI
zJSlgNipnyrL0w==
-----END CERTIFICATE-----将 private_key 段 的内容 另存为 test.example.com.key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAy0jhwrWaSWAWZJIDJSlAo/6ms+pmdEC4zuKe/CkXB6Y7Gk0B
HwP2/G1TNwikkkmkdCMeaAzNHbMOfGW5N6W5wQjE6ML9YHaCllzaOe2JdxAKJkpC
ZV3x21ICLClcJKOq0uK8DO2emsWxOQ9MviWnJ/6uQ7IIrA64O2evc9sXZxtch26v
QIyU/8RDRMRzF6LkYgkH3S0qY7K82HYypkCMH5bjnR2TWHKpnIJQeKOTIKgXXNQn
lKIQo0s0TjBtmmr5bxDEFKN2WinLjGrSjCQ2Rhml7u7mopXysKtmTHFRc+Cd7S1f
HwxrfiR5wgkfxE0nlui4mx/umOYFok3dX197TQIDAQABAoIBAEh6NbO8F8QtdA5r
WJ+5M4jE1B61Zc3w/XMVrWVuKP3bMJtR9SJfwYGCYPbwJ+zYQL//fWnPlpoOKw4D
HqROfAns3He4faoU1r5RYKTioe5HU7cPJtkJQ5/Uf13LaUTO7aq+mBlr5u57qZIU
eGIa/pvt26fbI+hkXx8e+pkt9gwWO6oQ4UTs0xcBjNf+DndzI2O3tRO9KudnxC3Y
kkDX2ELNkt8C2iSkBNv35ycK9Z2zSi7qMq+DMAues/5FAyKg1fNksXAYuk2qHYFF
tlSBrHPaYyoH7kHE47FSqrR5LrMXk7APEGvcq37Q8cA+ZZBS2hMKMxPWIco9cgTg
nWbPbakCgYEAzL6EO3PAIKyg3uJSckJDbuam0hiNBM3I02ENqO5qz9840yLVac/+
2fYBdA7BTx6lqks5HvygkXfSZ93Cd65xBZqjtH6UfU6HiXwom8MCsbQEOZiNOZRX
901rW2gHZq7swatMqJPWKeZ+Pk+AoK6fxwrS3aF1BnzExvzaMwMlqV8CgYEA/izU
VA0nWJBaly6XW8ZB/++HMGfYwsb9WkZLgNQDTPPO3zDV1XCLX0juFLexWbcw/Z8F
y0li5rfKDZ4EjDMPT3xl0h0lL/mYc1QsTmH35WffIrU6NYGNqRrqA9iPe82VPCvC
mbgZGSBPkDZtLI42K6cDL1Y2Hm0U8vrhZgtcXtMCgYEArYWd3iEoqMiFgsB/LXT5
X6k9ovvJsFOTq4oqoIyHm+tMZqy0AHyWOjWjX7ANpzeLIfukyp1CnGbXvM2WPgZq
pVw8+AD7agO/HQdMB07MHr05g3LF5hHSR7amkQ5mj2EbKLw8OPcqX9KIFdkdY5D7
ux5yPgHTg48E2rx7VRaKubMCgYEAx8IPtWcJDy+UItD5H6V25WAojUBwONQO9U3d
tQfq+CV85igJRk/HGUHF6v5bIbk5hXnfId8xHUZAQ+d2h4DxfXS0yScivMuaprj2
gTu5ic/SrAJmFvsUjFycoh0m1xPBP6Lcs9bd0sN0BFDiCGxT4obFmARXUB5GopfN
YVd4ZwUCgYA5CJC7NG29yMwmwNSMX1seg8D9GhaM7rGimTx0dwyjv8aA5aLCCcqu
g22HZwRuu0IAQfQOw9uK/mkozz1Z4MNWRrU9U+s1Cas9J5Ges7mJir9ERsMCrDaG
T6pq9P+M1AW2ZqabmbXSmquKokyAdZHcMDFRTE0gzoz5JAJDxKhMYA==
-----END RSA PRIVATE KEY-----将ca_chain和issuing_ca 导入到windows后,如下:


test.example.com相关的2个文件,用于nginx中,nginx的配置文件类似如下:
> cat test.example.com.conf
server {
listen 443 ssl;
server_name test.example.com;
ssl_certificate /etc/nginx/cert/test.example.com.crt;
ssl_certificate_key /etc/nginx/cert/test.example.com.key;
location / {
proxy_pass http://192.168.31.181:8200;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_headers_hash_max_size 51200;
proxy_headers_hash_bucket_size 6400;
client_max_body_size 100m;
}
} 另外,也可以使用如下的方法,把输出的内容直接提取到各个独立的文件中,命令如下:
vault write -format=json pki_int/issue/example-dot-com \
common_name="test.example.com" \
ttl="3600d" > cert_output.json
# 提取证书并保存为PEM文件
jq -r '.data.certificate' cert_output.json > test.example.com.crt
# 提取私钥并保存为PEM文件
jq -r '.data.private_key' cert_output.json > test.example.com.key
# 提取CA链并保存为PEM文件(中间证书+根证书+issuing_ca)
jq -r '.data.issuing_ca,.data.ca_chain[]' cert_output.json > test.example.com-chain.crt
# 提取中间证书
jq -r '.data.issuing_ca' cert_output.json > test.example.com-issuing_ca.crt下图是我证书链(根证书+中间证书)导入到本机windows上, 然后把test.example.com的2个密钥文件放到nginx里面。
最终在chrome上访问,可以看到证书是被信任的,并且有效期差不多是10年。

在linux上,导入ca证书链的写法:
1将证书文件复制到系统证书目录
cp /root/ca-chain.crt /etc/pki/ca-trust/source/anchors
2 更新系统证书
update-ca-trust
3 导入完成后,执行curl请求测试
curl --verbose https://test.example.com -I另外,也可以直接申请通配符的域名,写法如下:
vault write pki_int/issue/example-dot-com common_name="*.example.com" ttl="3600d"
效果如下:

吊销证书时,您可以执行导致 CRL 重新生成的吊销作。当您重新生成 CRL 时,Vault 会从中删除任何过期的证书。
要吊销证书,请执行以下命令,将 <serial_number> 占位符替换为要吊销的证书的实际序列号。
vault write pki_int/revoke serial_number=<serial_number>
TIPS: 这里的serial_number ,我是从vault的web ui里面找的,命令行没找到如何列出这个serial_number清单。
例如
$ vault write pki_int/revoke serial_number="1d:ad:32:80:96:1c:7e:53:03:da:92:a1:bb:fc:5b:a4:e3:33:10:ed"
Key Value
--- -----
revocation_time 1751110272
revocation_time_rfc3339 2025-06-28T11:31:12.103996771Z
state revoked
$ vault write pki_int/revoke serial_number="10:60:95:1f:96:e6:7e:89:32:e2:3d:3e:57:2a:0e:bd:30:44:0e:2f"
Key Value
--- -----
revocation_time 1751110263
revocation_time_rfc3339 2025-06-28T11:31:03.899983257Z
state revoked吊销后,在web ui可以看到多了个Revocation time的内容,如下图:

通过定期删除已过期且超过过期时间的某个缓冲期的证书来保留存储后端和 CRL。
删除已吊销的证书并清理 CRL。
vault write pki_int/tidy tidy_cert_store=true tidy_revoked_certs=true执行完成后,在web ui可以看到如下图:

补充:tidy的作用
官方文档上, 还有其余的步骤,这里不是必须操作,我们这里就不继续深入了。
上面step1-step6的步骤,是基本上照着官方文档演示的。
实际生产中,还有些需要自定义的地方(主要是 path 路径 需要自定义,因为生产的vault可能接入多个域名)
步骤 0:使用root token登陆vault
> export VAULT_ADDR='http://192.168.31.181:8200'
$ vault login hvs.R6BvAMswb8gBJWbFnSTrxI5c
步骤 1:生成根证书颁发机构
1 在 sbtest_ca_pki 路径上启用 pki 密钥引擎。
$ vault secrets enable -path=sbtest_ca_pki pki # 注意: vault secrets enable pki 的时候,一定要自定义路径(带上域名标识),否则后续再纳管其他域名的自签证书的时候,就不方便区分了。
2 优化 sbtest_ca_pki 密钥引擎以颁发最长生存时间 (TTL) 为 10年的证书。
$ vault secrets tune -max-lease-ttl=3650d sbtest_ca_pki
3 生成 sbtest.com 根 CA,为其指定颁发者名称,并将其证书保存在文件 vault-pki_ca.crt 中。
这将生成新的自签名 CA 证书和私有密钥。库 在租约期 (TTL) 结束时自动撤销生成的根。CA 证书对其自己的证书吊销列表 (CRL) 进行签名。
$ vault write -field=certificate sbtest_ca_pki/root/generate/internal \
common_name="sbtest.com" \
issuer_name="sbtest_ca_pki" \
ttl=3650d > vault-pki_ca.crt
4 列出根 CA 的颁发者信息。 sbtest_ca_pki
$ vault list sbtest_ca_pki/issuers/
5 您可以使用其 ID 读取颁发者,以获取有关颁发者的证书和其他元数据。使用如下的命令跳过证书内容的输出,但列出颁发者元数据和使用情况信息。
$ vault read sbtest_ca_pki/issuer/5170cf42-fefe-e589-225b-1dcd363c381d | tail -n 13
6 为根 CA 创建角色。创建此角色允许在必要时为此方案指定颁发者。这也提供了一种简单的方法,通过名称引用一个颁发者来从一个颁发者过渡到另一个颁发者。
$ vault write sbtest_ca_pki/roles/sbtest-role allow_any_name=true
7 配置 CA 和 CRL URL
$ vault write sbtest_ca_pki/config/urls \
issuing_certificates="$VAULT_ADDR/v1/pki/ca" \
crl_distribution_points="$VAULT_ADDR/v1/pki/crl"
步骤 2:生成中间 CA
1 首先,在 sbtest_ca_pki_int 路径启用 pki 密钥引擎。
$ vault secrets enable -path=sbtest_ca_pki_int pki # 注意: vault secrets enable pki 的时候,一定要自定义路径(带上域名标识),否则后续再纳管其他域名的自签证书的时候,就不方便区分了。
2 优化 sbtest_ca_pki_int 密钥引擎以颁发最大生存时间 (TTL) 为 3650d 的证书。
$ vault secrets tune -max-lease-ttl=3650d sbtest_ca_pki_int
3 执行以下命令生成一个中间文件,并将 CSR 另存为 pki_intermediate.csr。
$ vault write -format=json sbtest_ca_pki_int/intermediate/generate/internal \
common_name="sbtest.com Intermediate Authority" \
issuer_name="sbtest-dot-com-intermediate" \
| jq -r '.data.csr' > pki_intermediate.csr
4 使用根 CA 私有密钥对中间证书进行签名,并将生成的证书另存为 intermediate.cert.pem,这个文件实际上也就是证书链文件
$ vault write -format=json sbtest_ca_pki/root/sign-intermediate \
issuer_ref="sbtest_ca_pki" \
csr=@pki_intermediate.csr \
format=pem_bundle ttl="3650d" \
| jq -r '.data.certificate' > intermediate.cert.pem
5 签署 CSR 并且根 CA 返回证书后,可以将其导入回 Vault。
$ vault write sbtest_ca_pki_int/intermediate/set-signed certificate=@intermediate.cert.pem
步骤 3:创建角色
角色是映射到用于生成这些凭证的策略的逻辑名称。它允许配置参数控制证书公用名、备用名称、它们有效的密钥用途等。
创建一个名为 sbtest-dot-com 的角色,该角色允许子域,并将默认颁发者 ref ID 指定为 issuer_ref 的值。
> vault read -field=default sbtest_ca_pki_int/config/issuers
d0f8c790-e68a-700d-efa7-8cac2f691ded
将上一步的值代入下面命令
$ vault write sbtest_ca_pki_int/roles/sbtest-dot-com \
issuer_ref="d0f8c790-e68a-700d-efa7-8cac2f691ded" \
allowed_domains="sbtest.com" \
allow_subdomains=true \
max_ttl="3650d"
步骤 4:请求证书
执行以下命令以请求 test.sbtest.com 域 sbtest-dot-com
$ vault write sbtest_ca_pki_int/issue/sbtest-dot-com common_name="test.sbtest.com" ttl="3600d"
# 注意这里的ttl值必须小于 步骤3中的max_ttl值。
将 ca_chain 段 的内容 另存为 ca-chain.crt
将 certificate 段 的内容 另存为 test.sbtest.com.crt
将 private_key 段 的内容 另存为 test.sbtest.com.key
另外,也可以直接申请通配符的域名,写法如下:
vault write sbtest_ca_pki_int/issue/sbtest-dot-com common_name="*.sbtest.com" ttl="3600d" 原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。