HTTPS 与 SSL 配置
给网站装上"小绿锁"(HTTPS)已经从加分项变成必修项——Chrome/Firefox 会把 HTTP 站点直接标记为"不安全",Google 也把 HTTPS 作为搜索排名因素。好消息是,配合 Nginx 和 Let's Encrypt,免费启用 HTTPS 只要 5 分钟。这一章我们完整过一遍。
1. 为什么需要 HTTPS?
HTTP 是明文传输,存在三大风险:
- 窃听:路由器、ISP、咖啡店 WiFi 都能看到你访问的内容。
- 篡改:运营商能在网页里塞广告(你一定见过"快问医生"之类的弹窗)。
- 伪造:钓鱼网站能伪装成银行官网。
HTTPS(HTTP over TLS)通过非对称加密 + 数字证书解决这三个问题。对开发者来说,它还能解锁 PWA、HTTP/2、地理定位、Service Worker 等现代浏览器特性。
2. 最基础的 HTTPS 配置
先看一个能跑起来的最小配置:
# 最基础的 HTTPS 配置
server {
listen 443 ssl;
server_name example.com;
# 证书文件(包含公钥 + 中间证书)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# 私钥文件(绝对不能泄露!)
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
root /var/www/example;
index index.html;
}
}核心就两条指令:ssl_certificate(证书)和 ssl_certificate_key(私钥)。剩下的工作就是怎么搞到这两个文件。
3. SSL 证书从哪来?三种选择
- Let's Encrypt(免费,推荐):自动化申请、90 天有效、自动续期。本系列首推。
- 云厂商免费证书:阿里云、腾讯云、AWS 都提供免费 1 年期单域名证书。缺点是要手动续期。
- 付费证书:DigiCert、GlobalSign 等,单域名几百到几千一年,提供 EV(地址栏公司名)和通配符。
- 自签名证书:仅用于内网测试,浏览器会提示"不安全"。
4. Let's Encrypt + Certbot:一键申请
Certbot 是 Let's Encrypt 官方推荐的客户端工具,它能自动验证域名、申请证书、修改 Nginx 配置、设置自动续期:
# 1. 安装 Certbot(Ubuntu/Debian)
sudo apt install -y certbot python3-certbot-nginx
# 2. 一键申请证书并自动修改 Nginx 配置
sudo certbot --nginx -d example.com -d www.example.com
# Certbot 会自动:
# - 验证你确实拥有该域名(HTTP-01 challenge)
# - 申请证书并保存到 /etc/letsencrypt/live/example.com/
# - 修改 Nginx 配置,加上 ssl_certificate 等指令
# - 配置 HTTP→HTTPS 强制跳转
# 3. 测试自动续期(Let's Encrypt 证书 90 天有效,需定期续)
sudo certbot renew --dry-run
# 4. Certbot 会自动写入 systemd timer 定时续期
sudo systemctl list-timers | grep certbot几个关键点:
- 证书位置:
/etc/letsencrypt/live/<域名>/,fullchain.pem和privkey.pem是常用文件。 - 90 天到期,Certbot 自动安装 systemd timer,到期前 30 天自动续。
- 测试续期命令必须
--dry-run,避免触发 Let's Encrypt 的频率限制。
5. HTTP 强制跳转 HTTPS
光配 443 端口还不够,必须把 80 端口的请求也跳转到 HTTPS,否则用户输入 http:// 时还是明文:
# === HTTP 强制跳转 HTTPS(推荐写法)===
server {
listen 80;
server_name example.com www.example.com;
# 直接 301 永久跳转到 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
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;
# 主站配置...
location / {
root /var/www/example;
}
}
# 也可以用 rewrite,但 return 性能更好
# rewrite ^ https://$host$request_uri? permanent; # 不推荐注意:不要把整个站点配置在 80 和 443 两份,正确做法是 80 端口只负责 301 跳转。
6. SSL 安全最佳实践(生产必读)
默认的 SSL 配置不够安全——很多老协议(SSLv3、TLS 1.0)存在已知漏洞。生产环境应该用 Mozilla SSL Configuration Generator 的"Intermediate"档:
server {
listen 443 ssl http2; # 启用 HTTP/2(性能大幅提升)
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# === 1. 仅启用安全协议 ===
ssl_protocols TLSv1.2 TLSv1.3; # 禁用 SSLv3/TLSv1.0/1.1(已不安全)
ssl_prefer_server_ciphers off; # 让客户端选密码套件(TLS 1.3 推荐)
# === 2. 安全的密码套件 ===
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# 优先使用 ECDHE(前向保密)+ GCM(认证加密)
# === 3. 会话缓存(性能优化)===
ssl_session_cache shared:SSL:10m; # 共享缓存 10MB(约 4 万个会话)
ssl_session_timeout 10m; # 缓存有效期
ssl_session_tickets off; # 关闭 session ticket(前向保密更严格)
# === 4. HSTS(强制浏览器以后都走 HTTPS)===
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# === 5. OCSP Stapling(提升 TLS 握手速度)===
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
}几个关键安全指令解释:
- ssl_protocols TLSv1.2 TLSv1.3:禁用所有不安全的老协议。
- HSTS 头:告诉浏览器"以后半年内都用 HTTPS 访问本站",防止降级攻击。
- OCSP Stapling:让 Nginx 主动去查证书状态,浏览器不用再去查,握手更快。
- ssl_session_cache:缓存 TLS 会话,重连时跳过完整的握手,大幅提升性能。
配置后用 SSL Labs 测试,目标拿到 A 或 A+ 评级。
7. 启用 HTTP/2
HTTP/2 相比 HTTP/1.1 有质的飞跃——多路复用、头部压缩、服务器推送,对页面性能提升明显。HTTPS 是 HTTP/2 的前置条件(所有现代浏览器都只在 HTTPS 上启用 HTTP/2):
# 启用 HTTP/2 的两种写法(Nginx 1.25.1+ 推荐第二种)
# === 旧写法(Nginx 1.9.5 ~ 1.25.0)===
server {
listen 443 ssl http2; # 在 listen 上一起声明
...
}
# === 新写法(Nginx 1.25.1+,官方推荐)===
server {
listen 443 ssl;
http2 on; # 用独立指令声明
...
}
# 验证是否启用 HTTP/2
curl -I --http2 https://example.com/
# 输出: HTTP/2 200
# 浏览器 DevTools 的 Network 面板,看 Protocol 列是 h2 才对注意 Nginx 1.25.1 之后官方推荐用独立的 http2 on 指令,旧写法虽然还能用但即将废弃。
8. 一个完整的 HTTPS 生产模板
把上面的内容整合,下面是一个直接可用的 HTTPS 模板(80 跳转 + 443 安全配置 + HTTP/2):
- 80 端口 301 跳转到 HTTPS;
- 443 端口启用 SSL + HTTP/2;
- 仅 TLS 1.2/1.3;
- HSTS + OCSP Stapling;
- 会话缓存加速握手。
把域名、证书路径改成你的,nginx -s reload 即可。然后用 SSL Labs 跑一遍,拿 A+ 不难。
9. 常见坑与排查
- 证书和私钥不匹配:
nginx -t会报错。用openssl x509 -in cert.pem -noout -modulus和openssl rsa -in key.pem -noout -modulus对比 modulus 是否相同。 - 443 端口未开放:云服务器要检查安全组、
ufw allow 443或firewall-cmd --add-service=https。 - 混合内容(Mixed Content):HTTPS 页面里又引用了 HTTP 的 js/css,浏览器会拦截。改协议为
//或相对路径。 - 证书过期:监控告警必备,certbot 默认 30 天前自动续期,但偶尔会失败,要看日志。
小结
HTTPS 是现代网站的标配,配合 Let's Encrypt + Certbot,免费、自动、安全。这一章你学会了申请证书、配置 SSL、强制跳转、安全加固和 HTTP/2 启用。下一篇讲gzip 压缩——把传输体积砍掉 70%,让页面飞起来。
← 上一篇 反向代理与负载均衡
下一篇 gzip 压缩 →