SSL/TLS 证书管理
概述
SSL/TLS 证书是保障网络通信安全的基础。本文介绍如何使用 Let's Encrypt 免费证书,配置 HTTPS,并实现自动化续期。
核心概念
| 术语 | 说明 |
|---|---|
| SSL | Secure Sockets Layer,安全套接层(已废弃) |
| TLS | Transport Layer Security,传输层安全(SSL 的继任者) |
| CA | 证书颁发机构 |
| CSR | 证书签名请求 |
| SNI | 服务器名称指示,支持在同一 IP 上托管多个 HTTPS 站点 |
Let's Encrypt 与 Certbot
Let's Encrypt 提供免费、自动化的 SSL/TLS 证书。Certbot 是官方客户端。
安装 Certbot
# Ubuntu
sudo apt update
sudo apt install certbot python3-certbot-nginx
# CentOS
sudo dnf install certbot python3-certbot-nginx
# Docker
docker run --rm -v /etc/letsencrypt:/etc/letsencrypt certbot/certbot certonly
获取证书
Nginx 方式
# 自动获取并配置 Nginx
sudo certbot --nginx -d example.com -d www.example.com
# 仅获取证书,手动配置
sudo certbot certonly --nginx -d example.com
独立模式(无需 Web 服务器)
sudo certbot certonly --standalone -d example.com \
--non-interactive \
--agree-tos \
-m admin@example.com
DNS 验证(通配符证书)
# 支持 *.example.com
sudo certbot certonly --manual \
--preferred-challenges dns \
-d example.com \
-d "*.example.com"
证书文件结构
/etc/letsencrypt/live/example.com/
├── cert.pem # 服务器证书
├── chain.pem # 中间证书链
├── fullchain.pem # cert.pem + chain.pem(通常使用这个)
├── privkey.pem # 私钥(安全保管!)
└── README
Nginx HTTPS 配置
server {
listen 443 ssl http2;
server_name example.com;
# 证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
# 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# 其他安全头
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
}
# HTTP 跳转
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
自动续期
Certbot 自动续期
# 测试续期流程
sudo certbot renew --dry-run
# 查看续期定时任务
sudo systemctl status certbot.timer
# 手动续期
sudo certbot renew
crontab 方式
# 每天检查两次(推荐)
0 */12 * * * /usr/bin/certbot renew --quiet --no-self-upgrade
续期后重启服务
# 通过 --deploy-hook 在续期后自动重启
sudo certbot renew --deploy-hook "systemctl reload nginx"
# certbot 配置(/etc/letsencrypt/cli.ini)
deploy-hook = systemctl reload nginx
Docker 环境自动续期
# 使用 docker-compose
0 0 * * * docker exec nginx-certbot certbot renew && docker exec nginx nginx -s reload
证书监控
过期检查脚本
#!/bin/bash
# check_cert_expiry.sh
DOMAINS=("example.com" "api.example.com")
WARN_DAYS=30
CRITICAL_DAYS=7
for domain in "${DOMAINS[@]}"; do
expiry_date=$(openssl x509 -in "/etc/letsencrypt/live/$domain/fullchain.pem" \
-noout -enddate | cut -d= -f2)
expiry_epoch=$(date -d "$expiry_date" +%s)
now_epoch=$(date +%s)
days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
if [[ $days_left -lt $CRITICAL_DAYS ]]; then
echo "CRITICAL: $domain 证书将在 $days_left 天后过期!"
# 发送告警
elif [[ $days_left -lt $WARN_DAYS ]]; then
echo "WARNING: $domain 证书将在 $days_left 天后过期"
else
echo "OK: $domain 证书有效期还有 $days_left 天"
fi
done
Prometheus Exporter 监控
# prometheus.yml
scrape_configs:
- job_name: 'ssl_expiry'
static_configs:
- targets: ['ssl-exporter:9219']
安全性最佳实践
1. 证书等级选择
DV (域名验证): 基础 HTTPS,适合个人网站
OV (组织验证): 验证组织身份,适合企业网站
EV (扩展验证): 最高级别,浏览器显示公司名(逐渐被淘汰)
2. 密钥管理
- 私钥权限设置为 600,属主为 root
- 使用硬件安全模块 (HSM) 保护关键证书
- 定期轮换密钥对
3. 评分工具
# 测试 SSL 配置
curl https://www.ssllabs.com/ssltest/analyze.html?d=example.com
# 本地测试
openssl s_client -connect example.com:443 -tls1_3
nmap --script ssl-enum-ciphers -p 443 example.com
常见问题
证书过期导致服务中断
预防措施:
- 监控证书过期时间
- 配置自动续期
- 设置多级告警(30天、14天、7天、1天)
通配符证书
# 获取通配符证书
certbot certonly --manual --preferred-challenges dns \
-d example.com -d "*.example.com"
# DNS TXT 记录验证
_acme-challenge.example.com. IN TXT "..."
多域名证书 SAN
# 一个证书包含多个域名
certbot certonly --nginx \
-d example.com \
-d www.example.com \
-d api.example.com \
-d admin.example.com
总结
SSL/TLS 证书管理是现代网站运营的基础工作。使用 Let's Encrypt + Certbot 可以零成本实现证书的自动获取和续期。关键是要建立证书过期监控、自动化续期和定期安全审计的完整流程,确保 HTTPS 服务的持续可用和安全。