Nginx SSL/HTTPS配置 #

一、SSL/TLS概述 #

1.1 什么是SSL/TLS #

SSL(Secure Sockets Layer)和TLS(Transport Layer Security)是用于在网络上提供安全通信的加密协议。HTTPS即HTTP over TLS,通过TLS加密HTTP通信。

1.2 TLS版本 #

版本 发布年份 状态
SSL 2.0 1995 已弃用
SSL 3.0 1996 已弃用
TLS 1.0 1999 已弃用
TLS 1.1 2006 已弃用
TLS 1.2 2008 推荐
TLS 1.3 2018 最佳

二、证书获取 #

2.1 Let’s Encrypt免费证书 #

使用Certbot获取免费证书:

bash
sudo apt install certbot python3-certbot-nginx

sudo certbot --nginx -d example.com -d www.example.com

sudo certbot certonly --nginx -d example.com

sudo certbot renew --dry-run

2.2 自动续期 #

Certbot会自动添加续期任务:

bash
sudo systemctl status certbot.timer

sudo crontab -e

添加定时任务:

text
0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"

2.3 商业证书 #

购买商业证书后,通常获得以下文件:

  • 证书文件(.crt/.pem)
  • 私钥文件(.key)
  • 中间证书(CA Bundle)

三、基本HTTPS配置 #

3.1 最简配置 #

nginx
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;
    
    root /var/www/example.com;
    index index.html;
}

3.2 完整HTTPS配置 #

nginx
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    root /var/www/example.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

四、HTTP到HTTPS重定向 #

4.1 简单重定向 #

nginx
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    root /var/www/example.com;
}

4.2 通用重定向 #

nginx
server {
    listen 80;
    server_name _;
    return 301 https://$host$request_uri;
}

4.3 www重定向 #

nginx
server {
    listen 80;
    listen 443 ssl;
    server_name www.example.com;
    
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    return 301 https://example.com$request_uri;
}

server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;
    
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    
    root /var/www/example.com;
}

五、SSL参数详解 #

5.1 协议配置 #

nginx
ssl_protocols TLSv1.2 TLSv1.3;

ssl_prefer_server_ciphers on;

ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;

5.2 推荐密码套件 #

TLS 1.2+推荐:

nginx
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

兼容性优先:

nginx
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA;

5.3 DH参数 #

生成DH参数:

bash
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

配置:

nginx
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

5.4 会话配置 #

nginx
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_session_cache builtin:1000 shared:SSL:10m;
参数 说明
shared:SSL:10m 共享缓存,10MB约存储40000个会话
builtin:1000 内置缓存,存储1000个会话
ssl_session_timeout 会话超时时间
ssl_session_tickets 会话票据(建议关闭)

六、OCSP装订 #

6.1 启用OCSP装订 #

nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

6.2 OCSP说明 #

OCSP(Online Certificate Status Protocol)装订可以让服务器预先获取证书状态,减少客户端验证时间。

七、HSTS配置 #

7.1 基本HSTS #

nginx
add_header Strict-Transport-Security "max-age=31536000" always;

7.2 完整HSTS #

nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
参数 说明
max-age 有效期(秒)
includeSubDomains 包含子域名
preload 允许加入浏览器预加载列表

7.3 HSTS预加载 #

访问 hstspreload.org 提交域名。

八、安全头配置 #

8.1 完整安全头 #

nginx
server {
    listen 443 ssl;
    server_name example.com;
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:;" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
}

8.2 安全头说明 #

说明
Strict-Transport-Security 强制HTTPS
X-Frame-Options 防止点击劫持
X-Content-Type-Options 防止MIME类型嗅探
X-XSS-Protection XSS保护
Referrer-Policy Referer策略
Content-Security-Policy 内容安全策略
Permissions-Policy 权限策略

九、证书链配置 #

9.1 证书链顺序 #

正确的证书链顺序:

  1. 服务器证书
  2. 中间证书
  3. 根证书(可选)

9.2 合并证书 #

bash
cat server.crt intermediate.crt > fullchain.pem

9.3 验证证书链 #

bash
openssl verify -CAfile chain.pem server.crt
openssl s_client -connect example.com:443 -showcerts

十、多证书配置 #

10.1 多域名证书 #

nginx
server {
    listen 443 ssl;
    server_name example.com www.example.com;
    
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
}

server {
    listen 443 ssl;
    server_name blog.example.com;
    
    ssl_certificate /etc/nginx/ssl/blog.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/blog.example.com.key;
}

10.2 SNI配置 #

Nginx支持SNI(Server Name Indication),可以在同一IP上配置多个证书:

nginx
server {
    listen 443 ssl;
    server_name site1.example.com;
    ssl_certificate /etc/nginx/ssl/site1.crt;
    ssl_certificate_key /etc/nginx/ssl/site1.key;
}

server {
    listen 443 ssl;
    server_name site2.example.com;
    ssl_certificate /etc/nginx/ssl/site2.crt;
    ssl_certificate_key /etc/nginx/ssl/site2.key;
}

十一、客户端证书认证 #

11.1 基本配置 #

nginx
server {
    listen 443 ssl;
    server_name secure.example.com;
    
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    
    ssl_client_certificate /etc/nginx/ssl/ca.crt;
    ssl_verify_client on;
    ssl_verify_depth 2;
}

11.2 可选认证 #

nginx
ssl_verify_client optional;

location / {
    if ($ssl_client_verify != SUCCESS) {
        return 403;
    }
    proxy_pass http://backend;
}

11.3 传递客户端证书信息 #

nginx
location / {
    proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
    proxy_set_header X-SSL-Client-S-DN $ssl_client_s_dn;
    proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
    proxy_pass http://backend;
}

十二、SSL变量 #

12.1 常用SSL变量 #

nginx
$ssl_protocol
$ssl_cipher
$ssl_server_name
$ssl_client_fingerprint
$ssl_client_verify
$ssl_client_s_dn
$ssl_client_i_dn
$ssl_session_id
$ssl_session_reused

12.2 日志记录SSL信息 #

nginx
log_format ssl '$remote_addr - $remote_user [$time_local] '
               '"$request" $status $body_bytes_sent '
               'ssl_protocol=$ssl_protocol ssl_cipher=$ssl_cipher';

十三、SSL测试 #

13.1 测试工具 #

13.2 命令行测试 #

bash
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
nmap --script ssl-enum-ciphers -p 443 example.com

十四、完整配置示例 #

nginx
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    
    root /var/www/example.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

十五、总结 #

本章我们学习了:

  1. SSL/TLS基础:协议版本和选择
  2. 证书获取:Let’s Encrypt和商业证书
  3. 基本配置:证书路径和参数
  4. HTTP重定向:强制HTTPS
  5. 安全参数:协议、密码套件、DH参数
  6. OCSP装订:提升证书验证速度
  7. HSTS配置:强制HTTPS策略
  8. 安全头:完整的安全头配置
  9. 客户端证书:双向认证

掌握SSL/HTTPS配置后,让我们进入下一章,学习缓存配置!

最后更新:2026-03-27