7.1 核心概念
- TLS(Transport Layer Security)
- 为 HTTP 加密传输的协议(SSL 的继任者)。HTTPS = HTTP over TLS,保证数据加密、防篡改、验证服务器身份。
- TLS 终止(TLS Termination)
- 在 Nginx 处解密 HTTPS,再以明文 HTTP 转发给内网后端。后端无需处理证书,集中管理更省心。
- 证书与私钥
fullchain.pem是服务器证书+中间证书链,privkey.pem是配对私钥。私钥绝不能泄露,权限设为 600。- Let's Encrypt / certbot
- 免费的自动化证书颁发机构,certbot 是其官方客户端,能自动签发和续期(证书有效期 90 天)。
- HSTS(HTTP Strict Transport Security)
- 一个响应头,告诉浏览器"以后一律用 HTTPS 访问本站",防止降级攻击和首次跳转的中间人风险。
- HTTP/2 与 HTTP/3
- HTTP/2 多路复用一条连接、头部压缩;HTTP/3 基于 QUIC(UDP),避免队头阻塞、握手更快。二者都需在 TLS 上启用。
7.2 基础 HTTPS 配置
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # 1.25.1+ 用独立指令开启 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;
root /var/www/example;
location / {
try_files $uri /index.html;
}
}
7.3 用 certbot 自动签发
# 安装 certbot 及 Nginx 插件
$ sudo apt install certbot python3-certbot-nginx
# 自动签发并改写 Nginx 配置
$ sudo certbot --nginx -d example.com -d www.example.com
# 测试自动续期(证书 90 天,certbot 会装定时任务)
$ sudo certbot renew --dry-run
续期后要 reload Nginx
certbot 续期只是更新了证书文件,Nginx 还在用内存里的旧证书。certbot 的续期钩子通常会自动 reload,但自签或手动流程里别忘了 systemctl reload nginx,否则新证书不生效。
7.4 HTTP 强制跳转 HTTPS
# 80 端口只负责跳转到 443
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
用 return 301,别用 rewrite + if
网上很多老教程用 if ($scheme = http) { rewrite ... } 做跳转。更简洁高效的是单独一个 return 301 的 server 块。Nginx 社区名言 "if is evil"——在 location 里滥用 if 容易出诡异 bug,能用 return/try_files 就别用 if。
7.5 TLS 协议与套件优化
http {
# 只留现代协议,禁用不安全的旧版本
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off; # TLS1.3 下让客户端选更优
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# 会话复用,减少重复握手
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling:由服务器代查证书吊销状态,加速握手
ssl_stapling on;
ssl_stapling_verify on;
}
7.6 HSTS 与安全头
server {
listen 443 ssl;
# 告诉浏览器一年内强制 HTTPS,含子域
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}
HSTS 是不可逆承诺
一旦发了 HSTS 头,浏览器在 max-age 期内拒绝任何 HTTP 访问该域,包括你自己调试时。上线 includeSubDomains 或 preload 前务必确认所有子域都已支持 HTTPS,否则子域会集体无法访问,且无法快速回退。always 参数确保错误响应也带此头。
7.7 开启 HTTP/3(QUIC)
server {
listen 443 ssl;
listen 443 quic reuseport; # HTTP/3 走 UDP 443
http2 on;
http3 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 通告客户端本站支持 HTTP/3
add_header Alt-Svc 'h3=":443"; ma=86400';
}
HTTP/3 需要较新的 Nginx
HTTP/3 从 Nginx 1.25.0 起进入主线(需编译时带 QUIC 支持)。别忘了在防火墙/安全组放行 UDP 443——很多人只开了 TCP 443,结果 HTTP/3 静默失败、回退到 HTTP/2 还不自知。
7.8 小结与下一步
- Nginx 做 TLS 终止:解密 HTTPS 后以明文转发内网,证书集中管理。
- certbot 自动签发/续期 Let's Encrypt 证书,续期后需 reload。
- HTTP→HTTPS 用独立 server 的 return 301,避免 if。
- 只留 TLSv1.2/1.3、开会话复用与 OCSP Stapling。
- HSTS 强制 HTTPS 但不可逆,preload/includeSubDomains 要谨慎。
- HTTP/2 / HTTP/3 提速,HTTP/3 记得放行 UDP 443。
- 下一章榨干性能——缓存与性能调优。