Nginx SSL 证书配置与优化

Nginx SSL 证书配置与优化详解

在当今互联网环境中,HTTPS(Hypertext Transfer Protocol Secure)已经成为网站的标配。HTTPS 通过 SSL/TLS 协议对客户端和服务器之间的通信进行加密,确保数据传输的安全性、完整性和真实性。Nginx 作为一款高性能的 Web 服务器和反向代理服务器,在配置和优化 HTTPS 方面有着广泛的应用。本文将深入探讨 Nginx SSL 证书的配置、优化以及常见问题的解决,帮助您构建安全、高效的 HTTPS 网站。

一、SSL/TLS 协议基础

在深入 Nginx 配置之前,我们需要了解 SSL/TLS 协议的基础知识。

1.1 SSL/TLS 的作用

SSL/TLS 协议主要有以下几个作用:

  • 机密性 (Confidentiality): 使用加密算法(如 AES、ChaCha20)对通信数据进行加密,防止第三方窃听。
  • 完整性 (Integrity): 使用消息认证码(MAC)或哈希算法(如 SHA256、SHA384)来确保数据在传输过程中没有被篡改。
  • 认证性 (Authentication): 通过数字证书验证服务器和/或客户端的身份,防止中间人攻击。

1.2 SSL/TLS 握手过程

SSL/TLS 的核心在于握手过程,它建立了安全通信的基础。握手过程大致如下:

  1. 客户端 Hello (ClientHello): 客户端向服务器发送连接请求,包含支持的协议版本、加密套件、随机数等信息。
  2. 服务器 Hello (ServerHello): 服务器回应客户端,选择一个双方都支持的协议版本、加密套件,发送服务器的随机数。
  3. 证书 (Certificate): 服务器发送其数字证书给客户端。
  4. 服务器密钥交换 (ServerKeyExchange): 如果证书中没有包含足够的密钥交换信息,服务器会发送此消息。
  5. 证书请求 (CertificateRequest): 如果服务器需要验证客户端的身份,会发送此消息(可选)。
  6. 服务器 Hello 完成 (ServerHelloDone): 服务器发送此消息表示 Hello 阶段结束。
  7. 客户端密钥交换 (ClientKeyExchange): 客户端生成一个预主密钥(PreMasterSecret),并使用服务器证书中的公钥加密后发送给服务器。
  8. 更改密码规范 (ChangeCipherSpec): 客户端通知服务器后续消息将使用协商好的密钥和算法进行加密。
  9. 已完成 (Finished): 客户端发送一条加密的 Finished 消息,包含之前所有握手消息的哈希值和 MAC 值。
  10. 更改密码规范 (ChangeCipherSpec): 服务器通知客户端后续消息将使用协商好的密钥和算法进行加密。
  11. 已完成 (Finished): 服务器发送一条加密的 Finished 消息。

握手完成后,客户端和服务器就可以使用协商好的密钥和算法进行安全通信了。

1.3 数字证书

数字证书是 SSL/TLS 协议中用于验证身份的关键组件。它由受信任的证书颁发机构(CA)签发,包含以下信息:

  • 证书持有者的公钥: 用于加密客户端发送的预主密钥。
  • 证书持有者的信息: 如域名、组织名称等。
  • 证书颁发机构的信息: 用于验证证书的有效性。
  • 证书有效期: 证书的生效时间和过期时间。
  • 数字签名: CA 使用其私钥对证书内容进行签名,确保证书的完整性和真实性。

客户端通过验证证书的数字签名、有效期以及证书链,来确认服务器的身份。

二、Nginx SSL 证书配置

现在我们来详细了解如何在 Nginx 中配置 SSL 证书。

2.1 获取 SSL 证书

首先,您需要获取一个 SSL 证书。您可以从以下途径获取:

  • 商业 CA: 如 DigiCert、GlobalSign、Let's Encrypt 等。商业 CA 提供不同类型的证书,如域名验证(DV)、组织验证(OV)和扩展验证(EV)证书,它们提供不同级别的信任和验证。
  • Let's Encrypt: Let's Encrypt 是一个免费、自动化和开放的证书颁发机构,提供 DV 证书。它通过自动化流程简化了证书的申请和续期过程。
  • 自签名证书: 使用openssl等工具可以自己制作证书,但是因为没有CA机构担保,客户端通常会显示不安全。

2.2 安装 SSL 证书

获取证书后,您需要将证书文件(通常是 .crt 或 .pem 文件)和私钥文件(通常是 .key 文件)上传到服务器。建议将证书文件和私钥文件存放在一个安全的目录,例如 /etc/nginx/ssl/

2.3 Nginx 配置

接下来,编辑 Nginx 配置文件(通常是 /etc/nginx/nginx.conf/etc/nginx/conf.d/default.conf),添加以下配置:

```nginx
server {
listen 443 ssl; # 监听 443 端口,启用 SSL
server_name yourdomain.com www.yourdomain.com; # 替换为您的域名

ssl_certificate /etc/nginx/ssl/yourdomain.com.crt;  # 证书文件路径
ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key;  # 私钥文件路径

# 其他 SSL 配置...

location / {
    # 网站根目录或其他配置...
    root /var/www/html;
    index index.html index.htm;
}

}
```

  • listen 443 ssl;: 指定监听 443 端口(HTTPS 默认端口),并启用 SSL。
  • server_name: 指定您的域名。
  • ssl_certificate: 指定证书文件的路径。
  • ssl_certificate_key: 指定私钥文件的路径。

2.4 重启 Nginx

保存配置文件后,重启 Nginx 以使配置生效:

bash
sudo systemctl restart nginx

现在,您的网站应该已经可以通过 HTTPS 访问了。您可以使用浏览器或其他工具来验证证书是否正确安装。

三、Nginx SSL 优化

配置好 SSL 证书后,我们可以进一步优化 Nginx 的 SSL 性能和安全性。

3.1 启用 HTTP/2

HTTP/2 是 HTTP 协议的下一个版本,它带来了许多性能改进,如头部压缩、多路复用、服务器推送等。Nginx 从 1.9.5 版本开始支持 HTTP/2,您只需在 listen 指令中添加 http2 参数即可启用:

nginx
listen 443 ssl http2;

3.2 配置 SSL 协议和加密套件

为了提高安全性,您应该禁用不安全的 SSL 协议和加密套件。建议使用 TLS 1.2 和 TLS 1.3,并选择安全的加密套件。

nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;

  • ssl_protocols: 指定启用的 SSL/TLS 协议版本。
  • ssl_ciphers: 指定启用的加密套件。
  • ssl_prefer_server_ciphers: 设置为 on 表示服务器优先选择加密套件,而不是客户端。

建议使用 Mozilla SSL Configuration Generator 来生成适合您需求的配置: https://ssl-config.mozilla.org/

3.3 启用 OCSP Stapling

OCSP(Online Certificate Status Protocol)是一种用于检查证书是否被吊销的协议。OCSP Stapling 是一种优化技术,它允许服务器在 TLS 握手过程中将 OCSP 响应发送给客户端,而无需客户端单独向 CA 查询。这可以减少客户端的延迟并提高安全性。

nginx
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt; # CA 证书链文件路径

  • ssl_stapling: 启用 OCSP Stapling。
  • ssl_stapling_verify: 启用 OCSP 响应验证。
  • ssl_trusted_certificate: 指定 CA 证书链文件路径,用于验证 OCSP 响应。

3.4 启用 HSTS

HSTS(HTTP Strict Transport Security)是一种安全机制,它告诉浏览器在一段时间内只通过 HTTPS 访问网站,即使 URL 中指定的是 HTTP。这可以防止中间人攻击和协议降级攻击。

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

  • max-age: 指定 HSTS 策略的有效期(以秒为单位)。
  • includeSubDomains: 表示 HSTS 策略适用于所有子域名。
  • preload: 表示将您的域名添加到浏览器的 HSTS 预加载列表中,从而在首次访问时就强制使用 HTTPS。

3.5 会话缓存

启用会话缓存可以减少 SSL 握手的次数,从而提高性能。Nginx 提供了两种会话缓存机制:

  • ssl_session_cache: 配置会话缓存。
  • ssl_session_timeout: 设置会话缓存的过期时间。

nginx
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

shared:SSL:10m 定义了一个名为“SSL”的共享缓存,大小为 10MB。可以存储大约 40,000 个会话。ssl_session_timeout将缓存的会话的过期时间设置为了 10 分钟。

3.6 调整 worker_processes 和 worker_connections

Nginx 的性能与 worker 进程数和每个 worker 进程的连接数有关。您可以根据服务器的 CPU 核心数和负载情况调整这些参数。

nginx
worker_processes auto; # 自动根据 CPU 核心数设置
events {
worker_connections 1024; # 每个 worker 进程的最大连接数
}

四、常见问题与解决方案

4.1 证书链不完整

如果您的证书链不完整,浏览器可能会显示警告或错误。请确保您的证书文件中包含了所有中间证书,并按照正确的顺序排列(通常是服务器证书、中间证书、根证书)。

4.2 证书过期

定期检查证书的有效期,并在证书过期前及时续期。Let's Encrypt 证书的有效期为 90 天,建议使用自动化工具(如 Certbot)来自动续期。

4.3 混合内容

如果您的 HTTPS 网站中包含了 HTTP 资源(如图片、CSS、JavaScript 文件),浏览器可能会显示警告或阻止加载这些资源。请确保您的网站中所有资源都使用 HTTPS 加载。

4.4 协议或加密套件不安全

使用 SSL Labs 等工具检查您的 SSL 配置,确保没有使用不安全的协议或加密套件。

https://www.ssllabs.com/ssltest/

4.5 客户端不支持 SNI

SNI(Server Name Indication)是一种扩展,它允许服务器在同一个 IP 地址和端口上托管多个 HTTPS 网站。如果您的客户端不支持 SNI,它可能无法正确访问您的网站。请确保您的客户端支持 SNI,或者为每个网站使用不同的 IP 地址。

五、总结

本文详细介绍了 Nginx SSL 证书的配置、优化以及常见问题的解决方案。通过合理的配置和优化,您可以构建安全、高效的 HTTPS 网站,保护用户数据并提升网站的整体性能。请记住,SSL/TLS 配置是一个持续的过程,您需要定期检查和更新您的配置,以应对不断变化的安全威胁和技术发展。

希望本文对您有所帮助!

THE END