Nginx 教程

纯干货教学,从零开始学习 Nginx

Nginx SSL 配置

掌握 Nginx 的 SSL/TLS 配置,实现 HTTPS 安全访问

什么是 SSL/TLS?

SSL(Secure Sockets Layer)和 TLS(Transport Layer Security)是用于在网络通信中提供加密和身份验证的协议。TLS 是 SSL 的后继版本,目前广泛使用的是 TLS 1.2 和 TLS 1.3。

SSL/TLS 的作用

  • 数据加密:保护传输中的数据不被窃取
  • 身份验证:确保通信双方的身份真实可信
  • 数据完整性:确保数据在传输过程中不被篡改

SSL 证书获取

自签名证书(用于测试)

# 生成私钥
openssl genrsa -out server.key 2048

# 生成 CSR(证书签名请求)
openssl req -new -key server.key -out server.csr

# 生成自签名证书
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

免费 SSL 证书(Let's Encrypt)

# 安装 certbot
sudo apt install certbot python3-certbot-nginx  # Ubuntu/Debian
sudo yum install certbot python3-certbot-nginx  # CentOS/RHEL

# 自动获取并配置证书
sudo certbot --nginx -d example.com -d www.example.com

# 测试证书自动续期
sudo certbot renew --dry-run

付费 SSL 证书

可以从正规的证书颁发机构(CA)购买,如 DigiCert、GlobalSign、Comodo 等。

基本 SSL 配置

server {
    listen 443 ssl;
    server_name example.com;
    
    # SSL 证书配置
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    
    # SSL 协议配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    
    # SSL 会话缓存
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # 启用 HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    # 其他配置
    location / {
        root /var/www/html;
        index index.html;
    }
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

配置说明

  • ssl_certificate - SSL 证书文件路径
  • ssl_certificate_key - SSL 私钥文件路径
  • ssl_protocols - 启用的 SSL/TLS 协议版本
  • ssl_ciphers - 启用的密码套件
  • ssl_session_cache - SSL 会话缓存配置
  • Strict-Transport-Security - HTTP 严格传输安全头

高级 SSL 配置

启用 HTTP/2

server {
    listen 443 ssl http2;
    server_name example.com;
    
    # 其他 SSL 配置...
}

OCSP 装订

server {
    listen 443 ssl;
    server_name example.com;
    
    # 其他 SSL 配置...
    
    # 启用 OCSP 装订
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
}

SSL 会话票证

# 在 http 块中配置
http {
    # 生成 SSL 会话票证密钥
    ssl_session_tickets on;
    ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
    
    # 其他配置...
}

# 生成会话票证密钥文件
openssl rand 80 > /etc/nginx/ssl/ticket.key
chmod 600 /etc/nginx/ssl/ticket.key

SSL 优化

性能优化

server {
    listen 443 ssl http2;
    server_name example.com;
    
    # SSL 证书配置
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    
    # 性能优化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets on;
    ssl_session_ticket_key /etc/nginx/ssl/ticket.key;
    
    # 启用 OCSP 装订
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    # 其他配置...
}

安全优化

server {
    listen 443 ssl http2;
    server_name example.com;
    
    # SSL 证书配置
    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    
    # 安全优化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    
    # HSTS 配置
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    
    # 其他安全头
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options SAMEORIGIN always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # 其他配置...
}

SSL 证书管理

证书续期

# Let's Encrypt 证书自动续期
sudo certbot renew

# 添加到定时任务(每天执行)
sudo crontab -e
# 添加以下行
0 12 * * * /usr/bin/certbot renew --quiet

证书验证

# 检查证书信息
openssl x509 -in server.crt -text -noout

# 检查证书是否过期
openssl x509 -in server.crt -dates -noout

# 验证证书链
openssl verify -CAfile ca.crt server.crt

实践练习

练习1:配置自签名 SSL 证书

  1. 生成自签名 SSL 证书
  2. 配置 Nginx 使用该证书
  3. 测试 HTTPS 连接

练习2:使用 Let's Encrypt 获取免费 SSL 证书

  1. 安装 certbot
  2. 使用 certbot 获取并配置 SSL 证书
  3. 测试证书是否正确配置
  4. 测试证书自动续期功能

练习3:优化 SSL 配置

  1. 配置 HTTP/2
  2. 启用 OCSP 装订
  3. 添加安全 HTTP 头
  4. 使用 SSL Labs 测试 SSL 配置

常见问题解答

Q: 自签名证书和 Let's Encrypt 证书有什么区别?

A: 自签名证书由用户自己生成和签名,浏览器会显示安全警告;Let's Encrypt 证书由受信任的证书颁发机构签名,浏览器不会显示警告。

Q: SSL 证书过期了怎么办?

A: 对于自签名证书,需要重新生成;对于 Let's Encrypt 证书,可以使用 certbot renew 命令续期。

Q: 如何测试 SSL 配置的安全性?

A: 可以使用 SSL Labs 的 SSL Test 工具(https://www.ssllabs.com/ssltest/)测试 SSL 配置的安全性。

Q: 启用 SSL 后网站访问速度变慢怎么办?

A: 可以通过以下方法优化:启用 HTTP/2、配置 SSL 会话缓存、启用 OCSP 装订、使用更高效的密码套件。