3. 自签名证书生成:使用 OpenSSL 生成 CA 证书、服务端证书、客户端证书的完整步骤

在生产环境中,为 Exporter 启用 TLS 通信需要一套完整的证书体系。自签名证书虽然不受公共 CA 信任,但在内部网络、测试环境或受控集群中,通过自建 CA 并签发服务端与客户端证书,能够以零成本实现与商业 CA 同等级别的加密与双向认证。本节将使用 OpenSSL 工具,按标准 PKI 流程逐步生成 CA 证书、服务端证书及客户端证书。

3.1 证书体系架构概览

在开始操作前,先明确三张证书在 TLS 通信中的角色与关系:

证书体系角色说明:
  • CA 证书(根证书):自建证书颁发机构的身份凭证,用于签发服务端和客户端证书,也是验证链的信任锚点。
  • 服务端证书:安装在 Exporter 端,向客户端证明自身身份,包含服务端域名/IP 与公钥。
  • 客户端证书:安装在 Prometheus Server 或采集端,用于向 Exporter 证明客户端身份,实现双向 TLS(mTLS)认证。
自签名证书体系架构与信任链 自签名证书体系架构与信任链 CA 根证书 自建证书颁发机构 服务端证书 Exporter 端 CN = exporter.example.com 客户端证书 Prometheus 端 CN = prometheus-client mTLS 双向认证 信任链验证路径 客户端 → 服务端证书 → CA 证书(信任锚点) | 服务端 → 客户端证书 → CA 证书(信任锚点)

3.2 准备工作:目录结构与配置文件

在生成证书前,建议建立规范的目录结构,便于管理与后续维护。同时需要准备 OpenSSL 主配置文件,用于定义证书扩展属性。

3.2.1 创建目录结构

mkdir -p ~/ssl-ca/{certs,crl,newcerts,private,requests}
cd ~/ssl-ca
chmod 700 private
touch index.txt
echo 1000 > serial
目录/文件 用途
certs/ 存放已签发的证书文件(.pem)
private/ 存放 CA 私钥(权限 700)
newcerts/ 存放 OpenSSL 自动生成的证书副本
index.txt 证书数据库文件,记录已签发证书
serial 下一个证书的序列号(初始值建议 ≥ 1000)

3.2.2 准备 OpenSSL 主配置文件

创建一个自定义的 OpenSSL 配置文件 ca-openssl.cnf,用于控制 CA 操作和证书扩展:

# ca-openssl.cnf
[ ca ]
default_ca = CA_default

[ CA_default ]
dir               = ~/ssl-ca
certs             = $dir/certs
crl_dir           = $dir/crl
database          = $dir/index.txt
new_certs_dir     = $dir/newcerts
certificate       = $dir/certs/ca.cert.pem
serial            = $dir/serial
private_key       = $dir/private/ca.key.pem
RANDFILE          = $dir/private/.rand
default_days      = 3650
default_crl_days  = 30
default_md        = sha256
preserve          = no
policy            = policy_strict

[ policy_strict ]
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256
x509_extensions     = v3_ca

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address

[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints       = critical, CA:TRUE
keyUsage               = critical, digitalSignature, cRLSign, keyCertSign

[ server_cert ]
basicConstraints       = CA:FALSE
nsCertType             = server
nsComment              = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage               = critical, digitalSignature, keyEncipherment
extendedKeyUsage       = serverAuth

[ client_cert ]
basicConstraints       = CA:FALSE
nsCertType             = client
nsComment              = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage               = critical, digitalSignature
extendedKeyUsage       = clientAuth
配置要点:
  • policy_strict 要求 CA 签发时,国家、省份、组织必须与 CA 证书一致,增强安全性。
  • server_cert 和 client_cert 段落分别定义了服务端和客户端证书的 X.509 v3 扩展属性。
  • extendedKeyUsage 区分了证书用途:serverAuth 用于服务端,clientAuth 用于客户端。

3.3 生成 CA 根证书

CA 根证书是整个信任链的基石,需要先生成 CA 私钥,再自签名生成根证书。

步骤 1:生成 CA 私钥

openssl genrsa -aes256 -out private/ca.key.pem 4096
chmod 400 private/ca.key.pem

参数说明:-aes256 对私钥进行 AES-256 加密,启动时需输入密码;4096 为密钥长度,推荐 CA 使用 4096 位。

步骤 2:生成 CA 自签名证书

openssl req -config ca-openssl.cnf \
    -key private/ca.key.pem \
    -new -x509 -days 7300 -sha256 \
    -extensions v3_ca \
    -out certs/ca.cert.pem

交互式填写示例:

字段 示例值
Country Name CN
State or Province Name Beijing
Locality Name Beijing
Organization Name MyCompany
Common Name MyCompany Root CA

步骤 3:验证 CA 证书

openssl x509 -in certs/ca.cert.pem -text -noout | grep -E "Subject:|Issuer:|CA:TRUE|Key Usage"

确认输出中包含 CA:TRUE 和 Key Usage: Certificate Sign, CRL Sign。

3.4 生成服务端证书

服务端证书用于 Exporter 端,需要先生成私钥和证书签名请求(CSR),再由 CA 签发。

步骤 1:生成服务端私钥

openssl genrsa -out private/server.key.pem 2048
chmod 400 private/server.key.pem

步骤 2:生成服务端 CSR

openssl req -config ca-openssl.cnf \
    -key private/server.key.pem \
    -new -sha256 \
    -out requests/server.csr.pem

Common Name 必须填写 Exporter 的域名或 IP,例如 exporter.example.com 或 192.168.1.100。

步骤 3:CA 签发服务端证书

openssl ca -config ca-openssl.cnf \
    -extensions server_cert \
    -days 365 -notext -md sha256 \
    -in requests/server.csr.pem \
    -out certs/server.cert.pem

步骤 4:验证服务端证书

openssl x509 -in certs/server.cert.pem -text -noout | grep -E "Subject:|Issuer:|X509v3 Extended Key Usage"

确认 Extended Key Usage 包含 TLS Web Server Authentication。

3.5 生成客户端证书

客户端证书用于 Prometheus Server 或其他采集端,流程与服务端证书类似,但扩展属性不同。

步骤 1:生成客户端私钥

openssl genrsa -out private/client.key.pem 2048
chmod 400 private/client.key.pem

步骤 2:生成客户端 CSR

openssl req -config ca-openssl.cnf \
    -key private/client.key.pem \
    -new -sha256 \
    -out requests/client.csr.pem

Common Name 建议填写有意义的标识,如 prometheus-server-01。

步骤 3:CA 签发客户端证书

openssl ca -config ca-openssl.cnf \
    -extensions client_cert \
    -days 365 -notext -md sha256 \
    -in requests/client.csr.pem \
    -out certs/client.cert.pem

步骤 4:验证客户端证书

openssl x509 -in certs/client.cert.pem -text -noout | grep -E "Subject:|Issuer:|X509v3 Extended Key Usage"

确认 Extended Key Usage 包含 TLS Web Client Authentication。

3.6 证书文件清单与用途汇总

生成完成后,~/ssl-ca/ 目录下应包含以下关键文件:

文件路径 用途 安全要求
private/ca.key.pem CA 私钥,用于签发所有证书 最高机密,离线存储,权限 400
certs/ca.cert.pem CA 根证书,分发给所有客户端和服务端 公开分发,需防篡改
private/server.key.pem Exporter 私钥 机密,仅 Exporter 持有
certs/server.cert.pem Exporter 证书 公开,需与私钥配对
private/client.key.pem Prometheus 私钥 机密,仅 Prometheus 持有
certs/client.cert.pem Prometheus 证书 公开,需与私钥配对
自签名证书生成完整流程 自签名证书生成完整流程 ① 生成 CA 根证书 genrsa + req -x509 ② 生成服务端证书 genrsa → req → ca -ext server ③ 客户端证书 genrsa → req → ca -ext client 每个证书生成的子步骤 ① 生成私钥(genrsa) → ② 生成 CSR(req -new) → ③ CA 签发(ca -in) ④ 验证证书(x509 -text) → ⑤ 分发证书与私钥到对应组件 最终输出文件 ca.cert.pem + ca.key.pem | server.cert.pem + server.key.pem | client.cert.pem + client.key.pem

3.7 常见问题与避坑指南

⚠️ 关键注意事项:
  • Common Name 匹配问题:服务端证书的 CN 必须与 Exporter 实际访问的域名或 IP 完全一致,否则客户端会报证书名称不匹配错误。
  • 私钥权限:所有私钥文件必须设置为 400 或 600,防止被其他进程或用户读取。
  • CA 私钥保护:CA 私钥建议使用 AES-256 加密存储,并离线保管;一旦泄露,整个信任链失效。
  • 证书有效期:CA 证书有效期建议 5-10 年,服务端和客户端证书建议 1 年,到期前需续签。
  • SAN(Subject Alternative Name):如果 Exporter 通过多个域名或 IP 访问,必须在 CSR 中附加 SAN 扩展,否则浏览器或 Prometheus 会拒绝连接。

3.8 证书分发与后续步骤

证书生成完成后,需要将对应文件分发到正确的组件:

  • Exporter 节点:接收 server.cert.pem、server.key.pem、ca.cert.pem。
  • Prometheus Server 节点:接收 client.cert.pem、client.key.pem、ca.cert.pem。
  • 其他采集端:根据是否启用 mTLS,决定是否分发客户端证书。