2631 字
13 分钟

HTTPS/SSL 证书完全指南:从申请到部署再到自动续期 | 2026最新实践

HTTPS 已经不是可选功能,而是网站安全的基本要求。2026 年,浏览器对 HTTP 网站的警告更加严厉,搜索引擎也将 HTTPS 作为重要的排名因素。本文从证书原理到实战部署,全面讲解 HTTPS/SSL 证书的完整知识体系。

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 握手流程

  1. Client Hello:客户端发送支持的 TLS 版本、加密套件列表、随机数
  2. Server Hello:服务端选择 TLS 版本和加密套件、发送随机数、服务器证书
  3. Certificate Verify:客户端验证证书有效性
  4. Key Exchange:协商对称密钥(使用服务端公钥加密)
  5. 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 申请证书#

Terminal window
# 安装 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-renewal

3.3 certbot 自动续期配置#

Terminal window
# 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-run

3.4 获取通配符证书#

Terminal window
# 方法 1:使用 Cloudflare DNS
# 需要安装 cloudflare 插件
pip install certbot-dns-cloudflare
# 创建 Cloudflare API 令牌配置
mkdir -p ~/.secrets/certbot
cat > ~/.secrets/certbot/cloudflare.ini << 'EOF'
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
EOF
chmod 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 测试配置#

Terminal window
# 测试 Nginx 配置
nginx -t
# 测试 Apache 配置
apache2ctl configtest
# 重载配置
nginx -s reload
systemctl 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 预加载申请#

Terminal window
# 1. 配置 HSTS 响应头(包含 preload 选项)
# 2. 访问 https://hstspreload.org/
# 3. 输入域名,检查是否符合要求
# 4. 提交申请(审核时间约 1-2 周)
# 检查域名是否在预加载列表中
curl -s https://hstspreload.org/api/v2/status/example.com

5.3 安全响应头汇总#

响应头作用推荐值
Strict-Transport-Security强制 HTTPSmax-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 监控证书有效期#

Terminal window
# 检查所有证书有效期
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/bash
DOMAIN="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.com
else
echo "OK: Certificate for ${DOMAIN} expires in ${DAYS_LEFT} days"
fi
EOF
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-cert

6.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 挑战)#

Terminal window
# 常见原因:
# 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: 证书续期失败#

Terminal window
# 常见原因:
# 1. certbot 版本过旧
# 2. 自动续期任务未正确配置
# 3. DNS 变更导致验证失败
# 4. 服务器时间不正确
# 解决步骤:
# 1. 更新 certbot
sudo certbot renew --dry-run
# 2. 检查 cron/timer
systemctl status certbot.timer
# 3. 手动测试续期
certbot renew --force-renewal
# 4. 检查服务器时间
date

Q3: 浏览器显示证书不安全#

Terminal window
# 常见原因:
# 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 不工作#

Terminal window
# 检查 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: 通配符证书不生效#

Terminal window
# 检查 DNS 记录
nslookup example.com
nslookup subdomain.example.com
# 确保证书包含所有域名
certbot certificates --cert-name example.com
# 检查服务器配置中是否正确引用证书

八、最佳实践总结#

✅ 推荐配置清单#

项目推荐值
TLS 版本TLS 1.2 + TLS 1.3
加密套件优先 ChaCha20-Poly1305 和 AES-GCM
HSTSmax-age=31536000; includeSubDomains; preload
证书有效期90 天(自动续期)
证书类型Let’s Encrypt(免费)或商业证书(OV/EV)
OCSP Stapling启用
会话缓存启用(shared:SSL:10m)

✅ 安全检查清单#

Terminal window
# 1. 禁用弱协议和套件
# 2. 启用 HSTS
# 3. 配置安全响应头
# 4. 使用完整证书链(fullchain.pem)
# 5. 定期检查证书有效期
# 6. 自动续期测试(certbot renew --dry-run)
# 7. 使用 SSL Labs 测试(A+ 评级)
# 8. 私钥文件权限(chmod 600)

✅ 性能优化#

Terminal window
# 启用 HTTP/2
# Nginx: listen 443 ssl http2;
# 启用 OCSP Stapling
ssl_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/
作者
九所长
发布于
2026-06-22
许可协议
CC BY-NC-SA 4.0