前言
没有 HTTPS 的网站在 2025 年已经"裸奔"得不能再裸奔:浏览器标"不安全"、备案检查、小程序/H5 全要求 HTTPS。这篇把证书到配置的全流程走通。
一、证书从哪来
| 类型 | 说明 | 适合 |
|---|---|---|
| DV(域名验证) | 只验域名所有权,免费渠道多 | 个人站/中小业务 |
| OV(组织验证) | 验证公司身份,收费 | 企业官网 |
| EV(扩展验证) | 严格审核、地址栏显示公司名,贵 | 金融/大厂 |
| 自签 | 自己签给自己 | 仅内网测试 |
免费 DV 证书渠道:
- Let’s Encrypt(ACME 自动化,90 天有效期,可自动续期)
- 腾讯云/阿里云免费证书(每年 20 张,一年期)
- ZeroSSL
二、证书文件的构成
# 典型的一套(Nginx 需要 fullchain + key)
your.crt / your.pem # 证书(公钥 + 签发信息)
your.key # 私钥(!! 绝不外传, 权限 600)
chain.crt / fullchain.crt # 中间证书链(缺它部分客户端报错)
# 查看证书信息(到期时间/域名/签发者)
openssl x509 -in fullchain.crt -noout -dates -subject -issuer
# notAfter=Jan 1 12:00:00 2026 GMT ← 到期时间
openssl x509 -in fullchain.crt -noout -ext subjectAltName
到期监控(配合 cron 篇的知识):
echo | openssl s_client -serverName antidebug.cn -connect antidebug.cn:443 2>/dev/null \
| openssl x509 -noout -enddate
三、Let’s Encrypt 自动化(certbot)
dnf install -y certbot python3-certbot-nginx
# 一条命令: 验证域名 + 改 Nginx 配置 + 自动续期定时器
certbot --nginx -d antidebug.cn -d www.antidebug.cn
# 续期(90天证书, certbot 自动装了 systemd timer)
systemctl list-timers | grep certbot
certbot renew --dry-run # 演练续期
前提:域名已解析到本机、80 端口可访问(HTTP-01 验证要走它)。
四、Nginx HTTPS 配置模板
# ---- HTTP: 全部跳转 HTTPS ----
server {
listen 80;
server_name antidebug.cn www.antidebug.cn;
return 301 https://antidebug.cn$request_uri;
}
# ---- HTTPS 主站 ----
server {
listen 443 ssl;
http2 on; # HTTP/2(多路复用, 提速明显)
server_name antidebug.cn www.antidebug.cn;
# ---- 证书 ----
ssl_certificate /etc/nginx/certs/antidebug.cn/fullchain.crt;
ssl_certificate_key /etc/nginx/certs/antidebug.cn/private.key;
# ---- 协议与加密套件 ----
ssl_protocols TLSv1.2 TLSv1.3; # 1.0/1.1 已淘汰
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# ---- 会话复用(减少握手开销)----
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# ---- 安全头 ----
add_header Strict-Transport-Security "max-age=31536000" always;
# 强制浏览器后续一律走 HTTPS(HSTS)
# ---- OCSP Stapling(客户端不用去问 CA, 加快握手)----
ssl_stapling on;
ssl_stapling_verify on;
root /var/www/blog;
index index.html;
location / { try_files $uri $uri/ =404; }
# TLS 1.3 0-RTT 会重放, 写操作要小心——一般保持默认即可
}
nginx -t && systemctl reload nginx
curl -I https://antidebug.cn/ # 200 ✅
五、验证与评分
# 命令行验证
openssl s_client -connect antidebug.cn:443 -servername antidebug.cn </dev/null 2>/dev/null \
| openssl x509 -noout -dates -subject
# 协议与套件检查
nmap --script ssl-enum-ciphers -p 443 antidebug.cn
# 在线评分
# SSL Labs: https://www.ssllabs.com/ssltest/ 目标 A/A+
# 我的模板实测 A
常见扣分项:
| 问题 | 修复 |
|---|---|
| 支持 TLS 1.0/1.1 | ssl_protocols 只留 1.2/1.3 |
| 弱套件(CBC/3DES) | 用上面的 ECDHE 套件 |
| 无 HSTS | add_header Strict-Transport-Security |
| 链不完整 | 用 fullchain(带中间证书) |
六、自签证书(内网/测试)
# 一行生成自签证书(SAN 必须写对, 新浏览器不认 CN)
openssl req -x509 -nodes -newkey rsa:2048 -days 365 \
-keyout self.key -out self.crt \
-subj "/CN=lab.local" \
-addext "subjectAltName=DNS:lab.local,DNS:*.lab.local,IP:10.0.0.5"
# Nginx 配置同上; 客户端 curl -k 忽略验证
# 内网正规做法: 自建 CA 签发 + 分发 CA 证书到信任库
七、实战坑列表
| 现象 | 原因 |
|---|---|
| 浏览器警告"链不完整" | 只配了 crt 没配 fullchain |
| curl 报 certificate verify failed | 系统缺中间证书/CA;update-ca-trust |
| 部分安卓老设备握手失败 | TLS 版本太新/套件不兼容,酌情放宽 |
| 续期了还是旧证书 | certbot renew 后没 reload nginx → 加 --deploy-hook "systemctl reload nginx" |
| 443 不通 | 安全组/防火墙没放行 |
| http2 on 报错 | 老 nginx 用 listen 443 ssl http2; 旧语法 |
| mixed content | 页面里还引用 http:// 资源,全改 https 或用相对协议 |
八、性能小结
| 手段 | 收益 |
|---|---|
| 会话缓存/复用 | 回访用户省一次完整握手 |
| TLS 1.3 | 握手 1-RTT(0-RTT 可选) |
| OCSP stapling | 客户端少一次查询 |
| HTTP/2 | 多路复用,页面并发资源加载提速 |
| HTTP/3 (QUIC) | 弱网体验更佳(listen 443 quic; 新版本可试) |
小结
- 免费 DV 证书 + certbot 自动续期 = 零成本 HTTPS
- 模板要点:fullchain、TLS1.2/1.3、HSTS、会话复用、HTTP/2
- 上线三验证:
openssl s_client、nmap ssl-enum、SSL Labs 评分 - 续期别忘了 deploy-hook reload
本文是「Linux 运维」系列第 12 篇。