13.6.2 证书管理与自动化更新
在HAProxy中进行SSL终止后,证书管理决定安全性与可维护性。本节提供证书生命周期管理的原理草图、目录组织、自动化更新脚本、无损加载流程、排错与练习。
原理与流程草图
证书类型与适用场景
- 公有CA:公网服务必选,兼容性高。
- 内部CA:内网微服务通信,成本低且可控。
- 通配符/多域名:降低管理成本,但需控制使用权限。
- ECC/RSA:ECC性能好;兼容性优先可选择RSA。
证书目录与权限(示例)
# 创建证书目录并授权给haproxy用户
sudo mkdir -p /etc/haproxy/certs/example.com
sudo chown -R haproxy:haproxy /etc/haproxy/certs
sudo chmod 750 /etc/haproxy/certs
PEM合并与链完整性(可执行示例)
# 假设证书与私钥来源于ACME或CA
# server.crt: 服务器证书
# fullchain.crt: 服务器证书+中间证书链
# server.key: 私钥
cat /etc/ssl/example.com/server.crt \
/etc/ssl/example.com/fullchain.crt \
/etc/ssl/example.com/server.key \
> /etc/haproxy/certs/example.com/example.com.pem
# 权限最小化,仅haproxy可读
sudo chown haproxy:haproxy /etc/haproxy/certs/example.com/example.com.pem
sudo chmod 640 /etc/haproxy/certs/example.com/example.com.pem
HAProxy引用证书(配置片段)
# /etc/haproxy/haproxy.cfg
frontend https_in
bind *:443 ssl crt /etc/haproxy/certs/example.com/example.com.pem
mode http
default_backend web_pool
自动化更新与无损加载(示例脚本)
#!/usr/bin/env bash
# /usr/local/bin/renew_and_reload_haproxy.sh
set -euo pipefail
DOMAIN="example.com"
CERT_DIR="/etc/ssl/${DOMAIN}"
PEM_DST="/etc/haproxy/certs/${DOMAIN}/${DOMAIN}.pem"
TMP_PEM="/etc/haproxy/certs/${DOMAIN}/${DOMAIN}.pem.tmp"
# 1) 获取/更新证书(示例使用acme.sh,可替换为certbot)
# 假设acme.sh已安装并注册
/usr/local/bin/acme.sh --issue -d "${DOMAIN}" --standalone
# 2) 合并PEM并校验有效期
cat "${CERT_DIR}/server.crt" \
"${CERT_DIR}/fullchain.crt" \
"${CERT_DIR}/server.key" \
> "${TMP_PEM}"
openssl x509 -in "${CERT_DIR}/server.crt" -noout -dates
# 3) 原子替换并设置权限
mv "${TMP_PEM}" "${PEM_DST}"
chown haproxy:haproxy "${PEM_DST}"
chmod 640 "${PEM_DST}"
# 4) 无损加载
systemctl reload haproxy
# 5) 验证证书生效
echo | openssl s_client -connect 127.0.0.1:443 -servername "${DOMAIN}" 2>/dev/null | openssl x509 -noout -subject -dates
命令解释
- acme.sh --issue:向CA申请/续期证书。
- openssl x509 -noout -dates:检查证书有效期,避免过期证书上线。
- mv:原子替换文件,降低并发读写风险。
- systemctl reload haproxy:无损加载配置与证书。
- openssl s_client:验证握手与证书链是否正确。
安装与依赖准备(示例)
# 安装openssl与acme.sh所需依赖
sudo yum -y install openssl curl
curl https://get.acme.sh | sh
# 安装haproxy(示例,按发行版调整)
sudo yum -y install haproxy
证书健康检查与监控(示例命令)
# 查看到期时间
openssl x509 -in /etc/ssl/example.com/server.crt -noout -enddate
# 提取剩余天数(可用于监控脚本)
END_DATE=$(openssl x509 -in /etc/ssl/example.com/server.crt -noout -enddate | cut -d= -f2)
echo "Cert expires at: $END_DATE"
常见问题排查(带命令)
1. 握手失败/证书链不完整
# 检查证书链输出是否包含中间证书
openssl s_client -connect example.com:443 -servername example.com -showcerts
- 更新未生效
# 确认reload成功及进程PID变化
systemctl status haproxy
ps -ef | grep haproxy
- 权限错误
# 确认haproxy用户可读
sudo -u haproxy cat /etc/haproxy/certs/example.com/example.com.pem >/dev/null
练习
1. 使用自签名证书生成并配置到HAProxy,完成本地HTTPS访问。
2. 编写脚本在证书到期前30天自动续期并reload。
3. 故意删掉中间证书后,使用openssl s_client观察错误并恢复。