2631 字
13 分钟
HTTPS/SSL 证书完全指南:从申请到部署再到自动续期 | 2026最新实践
HTTPS 已经不是可选功能,而是网站安全的基本要求。2026 年,浏览器对 HTTP 网站的警告更加严厉,搜索引擎也将 HTTPS 作为重要的排名因素。本文从证书原理到实战部署,全面讲解 HTTPS/SSL 证书的完整知识体系。

本文内容包括:
- SSL/TLS 协议原理与版本选择
- 证书类型对比(DV/OEV/OV/EV)
- Let’s Encrypt 与 ACME 协议详解
- certbot 自动申请与续期配置
- Nginx/Apache/Caddy 证书部署
- HSTS 与 HTTPS 安全加固
- 证书监控与告警
- 常见问题排错与最佳实践
一、SSL/TLS 基础概念
1.1 HTTPS 工作原理
客户端请求 → TCP 握手 → TLS 握手 → 加密通信 ↓ ↓ 建立连接 证书验证 + 密钥交换TLS 握手流程:
- Client Hello:客户端发送支持的 TLS 版本、加密套件列表、随机数
- Server Hello:服务端选择 TLS 版本和加密套件、发送随机数、服务器证书
- Certificate Verify:客户端验证证书有效性
- Key Exchange:协商对称密钥(使用服务端公钥加密)
- Finished:双方确认加密通道建立
1.2 TLS 版本选择
| 协议版本 | 状态 | 安全性 | 推荐 |
|---|---|---|---|
| SSL 2.0 | 废弃 | 严重漏洞 | ❌ 禁用 |
| SSL 3.0 | 废弃 | POODLE 漏洞 | ❌ 禁用 |
| TLS 1.0 | 废弃 | BEAST 漏洞 | ❌ 禁用 |
| TLS 1.1 | 废弃 | RC4 漏洞 | ❌ 禁用 |
| TLS 1.2 | 当前标准 | 安全 | ✅ 推荐 |
| TLS 1.3 | 最新标准 | 更安全更快 | ✅ 强烈推荐 |
1.3 加密套件选择
# 推荐的加密套件优先级(Nginx 配置)ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
# 禁用的弱加密套件# - MD5, SHA1(哈希算法太弱)# - RC4(流密码不安全)# - 3DES(过时且慢)# - RSA 密钥交换(不支持前向保密)二、证书类型对比
2.1 证书类型概览
| 类型 | 验证级别 | 信任度 | 价格 | 适用场景 |
|---|---|---|---|---|
| DV(域名验证) | 仅验证域名所有权 | 基础信任 | 免费 | 个人博客、小型网站 |
| OEV(组织验证增强) | 验证域名+组织信息 | 中等信任 | 低-中 | 中小企业网站 |
| OV(组织验证) | 严格验证组织身份 | 高信任 | 中-高 | 企业官网、电商 |
| EV(扩展验证) | 最严格验证 | 最高信任 | 高 | 金融机构、政府网站 |
2.2 Let’s Encrypt 证书
Let’s Encrypt 是由 ISRG(Internet Security Research Group)运营的免费证书颁发机构:
| 特性 | 说明 |
|---|---|
| 免费 | 永久免费,无隐藏费用 |
| 有效期 | 90 天 |
| 自动续期 | 通过 ACME 协议自动续期 |
| 类型 | DV 证书 |
| 支持 | 单域名、通配符域名 |
| 兼容性 | 支持所有现代浏览器 |
2.3 商业证书对比
| 厂商 | 价格(单域名/年) | 特点 |
|---|---|---|
| Let’s Encrypt | 免费 | 自动续期,DV 级别 |
| Cloudflare | 免费 | 集成 CDN,自动管理 |
| DigiCert | ¥200-500 | 全球信任,OV/EV |
| GlobalSign | ¥300-800 | 多域名支持 |
| Comodo | ¥100-400 | 价格实惠 |
三、Let’s Encrypt 证书申请
3.1 ACME 协议原理
ACME(Automatic Certificate Management Environment)是 Let’s Encrypt 使用的自动化协议:
客户端(certbot) ACME服务器(Let's Encrypt) DNS服务器 │ │ │ ├─→ 请求证书 ────────────→│ │ │ │ │ │←─ 挑战类型 ────────────┤ │ │ │ │ │─→ HTTP-01 挑战 ────────→│ │ │ │ │ │←─ 验证成功 ────────────┤ │ │ │ │ │←─ 签发证书 ────────────┤ │ │ │ │挑战类型:
- HTTP-01:在网站根目录放置验证文件
- DNS-01:在域名 DNS 中添加 TXT 记录(支持通配符证书)
- TLS-ALPN-01:通过 TLS 握手验证
3.2 使用 certbot 申请证书
# 安装 certbot(Ubuntu/Debian)sudo apt update && sudo apt install certbot python3-certbot-nginx
# 安装 certbot(CentOS/RHEL)sudo dnf install certbot python3-certbot-nginx
# 安装 certbot(macOS)brew install certbot
# 自动检测并配置 Nginx(最简单)sudo certbot --nginx -d example.com -d www.example.com
# 仅获取证书(不自动配置)sudo certbot certonly --nginx -d example.com
# 使用 DNS 挑战(适用于通配符证书)sudo certbot certonly --dns-cloudflare -d "*.example.com" -d example.com
# 测试续期(不实际执行)sudo certbot renew --dry-run
# 强制续期sudo certbot renew --force-renewal3.3 certbot 自动续期配置
# certbot 默认会创建 cron 任务或 systemd timer# 检查自动续期配置systemctl list-timers | grep certbot
# 手动创建 cron 任务(如果未自动创建)# 每月 1 号凌晨 2 点检查续期echo "0 2 1 * * root certbot renew --quiet" | sudo tee /etc/cron.d/certbot
# 验证续期配置certbot renew --dry-run3.4 获取通配符证书
# 方法 1:使用 Cloudflare DNS# 需要安装 cloudflare 插件pip install certbot-dns-cloudflare
# 创建 Cloudflare API 令牌配置mkdir -p ~/.secrets/certbotcat > ~/.secrets/certbot/cloudflare.ini << 'EOF'dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKENEOFchmod 600 ~/.secrets/certbot/cloudflare.ini
# 申请通配符证书certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \ -d "*.example.com" \ -d example.com
# 方法 2:手动 DNS 验证certbot certonly \ --manual \ --preferred-challenges dns \ -d "*.example.com"# 按照提示添加 TXT 记录到 DNS四、证书部署实战
4.1 Nginx 配置
server { listen 80; server_name example.com www.example.com;
# HTTP 强制重定向到 HTTPS return 301 https://$host$request_uri;}
server { listen 443 ssl http2; server_name example.com www.example.com;
# 证书文件路径 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS 版本配置 ssl_protocols TLSv1.2 TLSv1.3;
# 加密套件 ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers on;
# 会话缓存(提升性能) ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off;
# OCSP Stapling(提升性能和隐私) ssl_stapling on; ssl_stapling_verify on;
# HSTS(强制 HTTPS) add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# 安全相关头部 add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy strict-origin-when-cross-origin;
# 网站根目录 root /var/www/example.com; index index.html;}4.2 Apache 配置
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com
# 重定向到 HTTPS Redirect permanent / https://example.com/</VirtualHost>
<VirtualHost *:443> ServerName example.com ServerAlias www.example.com
# 证书配置 SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# TLS 配置 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 SSLHonorCipherOrder on
# HSTS Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# 安全头部 Header always set X-Content-Type-Options nosniff Header always set X-Frame-Options DENY Header always set X-XSS-Protection "1; mode=block"
# 文档根目录 DocumentRoot /var/www/example.com</VirtualHost>4.3 Caddy 配置(自动 HTTPS)
# Caddy 2.x 配置(自动获取和续期证书)example.com { # 自动 HTTPS(Let's Encrypt) tls { dns cloudflare YOUR_CLOUDFLARE_API_TOKEN }
# 重定向 www 到 non-www redir www.example.com example.com permanent
# 静态文件服务 root * /var/www/example.com file_server
# HSTS 默认启用,max-age=15768000}4.4 测试配置
# 测试 Nginx 配置nginx -t
# 测试 Apache 配置apache2ctl configtest
# 重载配置nginx -s reloadsystemctl reload apache2
# 使用 SSL Labs 测试curl -s https://www.ssllabs.com/ssltest/analyze.html?d=example.com五、HSTS 配置与安全加固
5.1 HSTS 响应头详解
# 基础配置(推荐)add_header Strict-Transport-Security "max-age=31536000" always;
# 包含子域名add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 申请加入 HSTS 预加载列表add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;参数说明:
max-age:浏览器记住强制 HTTPS 的时间(秒),推荐 31536000(1年)includeSubDomains:应用到所有子域名preload:申请加入 HSTS 预加载列表(需在 hstspreload.org 注册)
5.2 HSTS 预加载申请
# 1. 配置 HSTS 响应头(包含 preload 选项)# 2. 访问 https://hstspreload.org/# 3. 输入域名,检查是否符合要求# 4. 提交申请(审核时间约 1-2 周)
# 检查域名是否在预加载列表中curl -s https://hstspreload.org/api/v2/status/example.com5.3 安全响应头汇总
| 响应头 | 作用 | 推荐值 |
|---|---|---|
Strict-Transport-Security | 强制 HTTPS | max-age=31536000; includeSubDomains; preload |
X-Content-Type-Options | 防止 MIME 嗅探 | nosniff |
X-Frame-Options | 防止点击劫持 | DENY |
X-XSS-Protection | 启用 XSS 保护 | 1; mode=block |
Referrer-Policy | 控制 Referrer 发送 | strict-origin-when-cross-origin |
Content-Security-Policy | 内容安全策略 | 按需配置 |
六、证书监控与告警
6.1 监控证书有效期
# 检查所有证书有效期certbot certificates
# 查看单个证书详情certbot certificates --cert-name example.com
# 使用 openssl 检查openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates
# 检查远程证书openssl s_client -connect example.com:443 </dev/null 2>/dev/null | openssl x509 -noout -dates
# 编写监控脚本cat > /usr/local/bin/check-cert-expiry.sh << 'EOF'#!/bin/bashDOMAIN="example.com"DAYS_BEFORE=30
EXPIRY=$(openssl s_client -connect ${DOMAIN}:443 </dev/null 2>/dev/null | \ openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)NOW_EPOCH=$(date +%s)DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt $DAYS_BEFORE ]; then echo "ALERT: Certificate for ${DOMAIN} expires in ${DAYS_LEFT} days!" # 发送邮件告警 echo "Certificate expiry alert" | mail -s "SSL Certificate Expiry Alert: ${DOMAIN}" admin@example.comelse echo "OK: Certificate for ${DOMAIN} expires in ${DAYS_LEFT} days"fiEOF
chmod +x /usr/local/bin/check-cert-expiry.sh
# 添加到 cron(每天检查)echo "0 9 * * * root /usr/local/bin/check-cert-expiry.sh" | sudo tee /etc/cron.d/check-cert6.2 使用 Prometheus + Grafana 监控
# prometheus.yml 配置scrape_configs: - job_name: 'ssl_certificates' scrape_interval: 1d metrics_path: /probe params: module: [ssl_expiry] static_configs: - targets: - example.com:443 - api.example.com:443 relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: localhost:9115 # blackbox exporter
# blackbox exporter 配置modules: ssl_expiry: prober: http http: tls_config: insecure_skip_verify: false valid_http_versions: ["HTTP/1.1", "HTTP/2"] preferred_ip_protocol: "ip4"七、常见问题排错
Q1: 证书申请失败(HTTP-01 挑战)
# 常见原因:# 1. 80 端口被占用(检查 Nginx/Apache 配置)# 2. 防火墙阻止了 80 端口# 3. 网站根目录权限问题# 4. CDN 或代理拦截了请求
# 解决步骤:# 1. 检查 80 端口netstat -tlnp | grep :80
# 2. 检查防火墙ufw status# 确保 80/tcp 已允许
# 3. 验证网站可访问curl http://example.com/.well-known/acme-challenge/test
# 4. 临时关闭 CDN 或代理Q2: 证书续期失败
# 常见原因:# 1. certbot 版本过旧# 2. 自动续期任务未正确配置# 3. DNS 变更导致验证失败# 4. 服务器时间不正确
# 解决步骤:# 1. 更新 certbotsudo certbot renew --dry-run
# 2. 检查 cron/timersystemctl status certbot.timer
# 3. 手动测试续期certbot renew --force-renewal
# 4. 检查服务器时间dateQ3: 浏览器显示证书不安全
# 常见原因:# 1. 证书过期# 2. 证书链不完整(缺少 intermediate CA)# 3. 证书域名不匹配# 4. 浏览器缓存旧证书
# 解决步骤:# 1. 检查证书状态certbot certificates
# 2. 检查证书链openssl s_client -connect example.com:443 -showcerts
# 3. 确保使用 fullchain.pem(包含完整证书链)# Nginx: ssl_certificate /path/to/fullchain.pem;
# 4. 清除浏览器缓存Q4: OCSP Stapling 不工作
# 检查 OCSP Stapling 状态openssl s_client -connect example.com:443 -status </dev/null 2>&1 | grep OCSP
# 确保配置正确# Nginx:ssl_stapling on;ssl_stapling_verify on;resolver 8.8.8.8 8.8.4.4 valid=300s;resolver_timeout 5s;Q5: 通配符证书不生效
# 检查 DNS 记录nslookup example.comnslookup subdomain.example.com
# 确保证书包含所有域名certbot certificates --cert-name example.com
# 检查服务器配置中是否正确引用证书八、最佳实践总结
✅ 推荐配置清单
| 项目 | 推荐值 |
|---|---|
| TLS 版本 | TLS 1.2 + TLS 1.3 |
| 加密套件 | 优先 ChaCha20-Poly1305 和 AES-GCM |
| HSTS | max-age=31536000; includeSubDomains; preload |
| 证书有效期 | 90 天(自动续期) |
| 证书类型 | Let’s Encrypt(免费)或商业证书(OV/EV) |
| OCSP Stapling | 启用 |
| 会话缓存 | 启用(shared:SSL:10m) |
✅ 安全检查清单
# 1. 禁用弱协议和套件# 2. 启用 HSTS# 3. 配置安全响应头# 4. 使用完整证书链(fullchain.pem)# 5. 定期检查证书有效期# 6. 自动续期测试(certbot renew --dry-run)# 7. 使用 SSL Labs 测试(A+ 评级)# 8. 私钥文件权限(chmod 600)✅ 性能优化
# 启用 HTTP/2# Nginx: listen 443 ssl http2;
# 启用 OCSP Staplingssl_stapling on;
# 配置会话复用ssl_session_cache shared:SSL:10m;
# 使用 TLS 1.3(更快的握手)ssl_protocols TLSv1.2 TLSv1.3;
# 启用 Brotli 压缩brotli on;brotli_types text/plain text/css application/json application/javascript;总结:HTTPS 配置是网站安全的基础,2026 年已没有理由不启用 HTTPS。借助 Let’s Encrypt 和 certbot,证书申请和续期可以完全自动化。关键是配置好 TLS 版本、加密套件、HSTS 和安全响应头,定期监控证书状态,确保网站始终安全可靠。
HTTPS/SSL 证书完全指南:从申请到部署再到自动续期 | 2026最新实践
https://971918.xyz/posts/docs/https-ssl-guide/