Nginx 配置 HTTPS 全指南:每个参数逐一详解

1. 引言

随着网络安全意识的提升,HTTPS 已成为网站部署的标配。HTTPS 不仅能够加密客户端与服务器之间的数据传输,防止中间人攻击,还能提升搜索引擎排名和用户信任度。Nginx 作为高性能的 Web 服务器和反向代理服务器,配置 HTTPS 是其核心功能之一。

本文将带你从零开始,在 Nginx 中配置 HTTPS,并对配置文件中的每一个参数进行详细解读,帮助你不仅会配置,更理解每一行配置背后的含义。

2. 准备工作

在开始配置之前,需要做好以下准备:

  • 一台已安装 Nginx 的服务器(本文以 Ubuntu/Debian 系统为例,其他系统命令略有差异)。
  • 一个已解析到该服务器的域名。
  • 一份 SSL 证书及私钥文件。你可以从证书颁发机构(CA)购买,也可以使用 Let's Encrypt 免费获取。

2.1 检查 Nginx 是否安装

bash 复制代码
nginx -v

如果未安装,可使用以下命令安装:

bash 复制代码
sudo apt update
sudo apt install nginx -y

2.2 获取 SSL 证书

以 Let's Encrypt 为例,使用 Certbot 工具可以快速获取免费证书:

bash 复制代码
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com -d www.example.com

Certbot 会自动修改 Nginx 配置并启用 HTTPS。但为了深入理解配置,本文将手动编写配置。

3. 基础 HTTPS 配置

首先,我们来看一个最基础的 HTTPS 配置示例:

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;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

3.1 listen 443 ssl

nginx 复制代码
listen 443 ssl;

参数解读

  • listen:指定 Nginx 监听的端口和协议。
  • 443:HTTPS 的默认端口。
  • ssl:告诉 Nginx 在该端口上启用 SSL/TLS 加密。这是启用 HTTPS 的关键参数。

注意 :在较新版本的 Nginx 中,ssl 参数可以省略,因为 listen 443 默认会启用 SSL。但为了兼容性和明确性,建议保留。

3.2 server_name

nginx 复制代码
server_name example.com www.example.com;

参数解读

  • server_name:指定该虚拟主机匹配的域名。
  • 可以配置多个域名,用空格分隔。
  • 当客户端请求的 Host 头与这里的域名匹配时,Nginx 会使用该 server 块处理请求。

3.3 ssl_certificate

nginx 复制代码
ssl_certificate /etc/nginx/ssl/example.com.crt;

参数解读

  • ssl_certificate:指定 SSL 证书文件的路径。
  • 证书文件通常以 .crt.pem.cer 为扩展名。
  • 该文件包含服务器的公钥证书,由 CA 签发。
  • 如果证书链中包含中间证书,需要将服务器证书和中间证书合并到同一个文件中。

3.4 ssl_certificate_key

3.5 多域名与通配符证书

在实际部署中,一个站点往往需要同时服务多个域名,或者为某个主域名下的所有子域名提供 HTTPS。这时就需要用到多域名证书或通配符证书。

3.5.1 同一 server 块配置多个域名共用一张证书

如果一张证书的 SAN(Subject Alternative Name,主题备用名称)字段中包含了多个域名,那么可以在同一个 server 块中配置这些域名,共用这一张证书:

nginx 复制代码
server {
    listen 443 ssl;
    server_name example.com www.example.com blog.example.com;

    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

参数解读

  • server_name:这里列出了三个域名,用空格分隔。只要请求的 Host 头匹配其中任意一个,Nginx 就会使用该 server 块处理请求。
  • ssl_certificate / ssl_certificate_key:指向同一张证书和对应的私钥。这张证书必须同时覆盖上面列出的所有域名,否则浏览器会提示证书不匹配。

适用场景 :当几个域名指向同一个站点、且证书已包含这些域名时使用。例如公司官网同时使用 example.comwww.example.com,或主站与博客共用一张多域名证书。

3.5.2 使用通配符证书(*.example.com)

通配符证书可以覆盖某个主域名下的所有一级子域名,例如 *.example.com 可以匹配 www.example.comblog.example.comapi.example.com 等,但不匹配 example.com 本身。

nginx 复制代码
server {
    listen 443 ssl;
    server_name *.example.com;

    ssl_certificate /etc/nginx/ssl/wildcard.example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/wildcard.example.com.key;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

参数解读

  • server_name *.example.com:使用通配符匹配所有一级子域名。
  • ssl_certificate / ssl_certificate_key:指向通配符证书及其私钥。通配符证书的 CN 或 SAN 字段为 *.example.com

注意 :通配符证书只匹配一级子域名,a.b.example.com 这类多级子域名无法被 *.example.com 覆盖,需要单独配置或使用多域名证书。
适用场景 :当子域名数量较多、且未来可能动态新增子域名时使用。例如 SaaS 平台为每个客户分配独立的 customer.example.com,使用通配符证书可以避免频繁申请新证书。

nginx 复制代码
ssl_certificate_key /etc/nginx/ssl/example.com.key;

参数解读

  • ssl_certificate_key:指定 SSL 私钥文件的路径。
  • 私钥文件通常以 .key 为扩展名。
  • 私钥必须保密,不能泄露给任何人。
  • 私钥与证书必须匹配,否则 Nginx 启动时会报错。

安全提示 :私钥文件的权限应设置为仅 root 可读,例如 chmod 600 example.com.key

4. 增强 HTTPS 安全性的配置

基础配置已经可以启用 HTTPS,但为了提升安全性,还需要进行以下优化。

4.1 HTTP 自动跳转 HTTPS

为了让用户访问 HTTP 时自动跳转到 HTTPS,可以添加一个额外的 server 块:

nginx 复制代码
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

参数解读

  • listen 80:监听 HTTP 默认端口。
  • return 301:返回 301 永久重定向状态码。
  • https://$host$request_uri:重定向目标地址。$host 是请求的域名,$request_uri 是请求的 URI。

说明:使用 301 永久重定向有利于 SEO,搜索引擎会将权重转移到 HTTPS 页面。

4.2 配置 HTTP/2

HTTP/2 可以显著提升页面加载速度,Nginx 1.9.5 及以上版本支持:

nginx 复制代码
listen 443 ssl http2;

参数解读

  • http2:启用 HTTP/2 协议。
  • HTTP/2 支持多路复用、头部压缩等特性,能减少延迟、提升性能。
  • 注意:HTTP/2 需要 SSL/TLS 支持,因此必须与 ssl 同时使用。

4.3 配置 TLS 协议版本

nginx 复制代码
ssl_protocols TLSv1.2 TLSv1.3;

参数解读

  • ssl_protocols:指定允许使用的 TLS 协议版本。
  • TLSv1.2:目前广泛支持的版本,安全性较高。
  • TLSv1.3:最新版本,安全性最高,性能更好。
  • 建议禁用 SSLv3、TLSv1.0 和 TLSv1.1,这些旧版本存在已知安全漏洞。

4.4 配置加密套件

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';

参数解读

  • ssl_ciphers:指定允许的加密套件列表,用冒号分隔。
  • 加密套件决定了密钥交换、认证、加密和消息认证的方式。
  • 上述配置优先使用 ECDHE 密钥交换(支持前向保密)和 AES-GCM 加密算法(高效且安全)。
  • 建议使用 Mozilla 推荐的加密套件配置。

4.5 配置 SSL 会话缓存

nginx 复制代码
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

参数解读

  • ssl_session_cache:配置 SSL 会话缓存。shared:SSL:10m 表示在共享内存中分配 10MB 缓存,大约可以存储 40000 个会话。
  • ssl_session_timeout:会话超时时间,超过该时间后会话失效,需要重新握手。
  • 启用会话缓存可以减少重复握手的开销,提升性能。

4.6 配置 OCSP Stapling

nginx 复制代码
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

参数解读

  • ssl_stapling on:启用 OCSP Stapling。服务器主动向 CA 查询证书状态并缓存,在 TLS 握手时直接返回给客户端,无需客户端再向 CA 查询,提升握手速度。
  • ssl_stapling_verify on:验证 OCSP 响应。
  • resolver:指定 DNS 解析器,用于解析 OCSP 响应服务器的域名。
  • resolver_timeout:DNS 解析超时时间。

4.7 配置 HSTS

nginx 复制代码
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

参数解读

  • add_header:添加 HTTP 响应头。
  • Strict-Transport-Security:HSTS 头,告诉浏览器只能通过 HTTPS 访问该站点。
  • max-age=31536000:有效期 1 年(单位秒)。
  • includeSubDomains:对子域名同样生效。
  • always:无论响应状态码是什么都添加该头。

注意:启用 HSTS 后,浏览器会强制使用 HTTPS,如果证书配置有误,用户将无法访问站点。建议先在测试环境验证。

4.8 配置 TLS 会话票据

4.9 HTTPS 反向代理配置

Nginx 最常见的用途之一就是作为反向代理:对外提供 HTTPS 加密访问,对内将请求转发给后端的 HTTP 服务(如 Tomcat、Node.js、Gunicorn 等)。这样既能让后端服务专注于业务逻辑,又能在入口统一处理 TLS 加密、负载均衡和安全策略。

nginx 复制代码
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # 证书配置
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # 协议与加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    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';
    ssl_prefer_server_ciphers on;

    # 反向代理配置
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

参数解读

  • proxy_pass:指定后端服务的地址。这里将请求转发到本机的 8080 端口,即后端 HTTP 服务监听的端口。
  • proxy_set_header Host $host:将客户端请求的 Host 头原样传递给后端,保证后端能正确识别域名。
  • proxy_set_header X-Real-IP $remote_addr:传递客户端的真实 IP 地址。由于 Nginx 转发后,后端看到的连接来源是 Nginx 本身,需要该头才能获取真实客户端 IP。
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for:追加客户端 IP 到转发链中,常用于日志记录和访问控制。
  • proxy_set_header X-Forwarded-Proto $scheme:告诉后端原始请求使用的协议(httphttps)。$scheme 变量在 HTTPS 请求中取值为 https

说明X-Forwarded-Proto 是解决后端重定向协议丢失问题的关键。如果缺少该头,后端在生成重定向 URL 时(例如登录成功后跳转)会误以为原始请求是 HTTP,从而生成 http:// 开头的地址,导致用户被重定向到非加密页面,甚至出现「重定向次数过多」的错误。

4.9.1 后端重定向协议丢失的解决方案

当后端服务需要根据请求协议生成绝对 URL 时(如 Spring Boot 的 RedirectView、Django 的 HttpResponseRedirect),必须让后端感知到原始请求是 HTTPS。除了设置 X-Forwarded-Proto 头,部分框架还需要额外配置:

nginx 复制代码
# 对于需要识别 X-Forwarded-Proto 的框架(如 Django、Spring Boot)
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;

参数解读

  • X-Forwarded-Proto $scheme:声明原始请求协议为 HTTPS,后端据此生成 https:// 开头的重定向地址。
  • X-Forwarded-Port $server_port:传递 Nginx 监听的端口(443),供后端生成包含正确端口的 URL。

注意 :部分框架默认不信任代理设置的 X-Forwarded-* 头,需要显式开启。例如 Django 需在 settings.py 中配置 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),Spring Boot 需设置 server.forward-headers-strategy=framework。否则后端仍会忽略该头,重定向协议问题依旧存在。

nginx 复制代码
ssl_session_tickets on;

参数解读

  • ssl_session_tickets:启用 TLS 会话票据(Session Tickets)。
  • 与会话缓存不同,会话票据由服务器加密后发给客户端,客户端在后续连接中携带票据即可恢复会话,无需服务器存储会话状态。
  • 适用于多台服务器负载均衡的场景。

5. 完整的安全配置示例

将以上配置整合,得到一个完整的 HTTPS 配置示例:

nginx 复制代码
# HTTP 跳转 HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS 主配置
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # 证书配置
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # 协议与加密套件
    ssl_protocols TLSv1.2 TLSv1.3;
    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';
    ssl_prefer_server_ciphers on;

    # 会话缓存与票据
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets on;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 站点根目录
    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

5.1 ssl_prefer_server_ciphers

nginx 复制代码
ssl_prefer_server_ciphers on;

参数解读

  • ssl_prefer_server_ciphers:当客户端支持多种加密套件时,是否优先使用服务器端配置的加密套件顺序。
  • 设置为 on 可以确保优先使用服务器端更安全的加密套件。

6. 验证配置并重启 Nginx

配置完成后,需要验证配置文件的正确性并重启 Nginx:

bash 复制代码
# 验证配置
sudo nginx -t

# 重启 Nginx
sudo systemctl restart nginx

如果配置正确,nginx -t 会输出:

复制代码
nginx: configuration file /etc/nginx/nginx.conf test is successful

7. 常见问题排查

7.1 证书不匹配

如果证书与私钥不匹配,Nginx 启动时会报错。可以使用以下命令验证:

bash 复制代码
# 查看证书信息
openssl x509 -in /etc/nginx/ssl/example.com.crt -noout -modulus | openssl md5

# 查看私钥信息
openssl rsa -in /etc/nginx/ssl/example.com.key -noout -modulus | openssl md5

两个命令输出的 MD5 值应一致。

7.2 证书链不完整

如果浏览器提示证书链不完整,需要将服务器证书和中间证书合并:

bash 复制代码
cat example.com.crt intermediate.crt > combined.crt

然后将 ssl_certificate 指向合并后的文件。

7.3 端口被占用

如果 443 端口被其他程序占用,可以使用以下命令查看:

bash 复制代码
sudo netstat -tlnp | grep 443

8. 总结

本文详细介绍了 Nginx 配置 HTTPS 的完整流程,并对每个参数进行了深入解读。从基础的 listen 443 sslssl_certificatessl_certificate_key,到安全增强的 ssl_protocolsssl_ciphers、HSTS、OCSP Stapling 等,每一个参数都有其特定的作用。

配置 HTTPS 不仅仅是启用加密,更重要的是通过合理的参数配置,在安全性、性能和兼容性之间找到最佳平衡。希望本文能帮助你深入理解 Nginx HTTPS 配置的每一个细节,在实际部署中游刃有余。

相关推荐
❁满城风絮*1 小时前
Nginx—从默认页面到高性能网
网络·nginx
FIT2CLOUD飞致云1 小时前
GPU监控支持华为昇腾设备,防火墙管理焕新,虚拟机管理下放至专业版,1Panel v2.3.0版本发布
运维·ai·开源·1panel·运维面板
一只小李郁vickie2 小时前
Redis 集群部署手册(3主3从)
运维·redis
牢姐与蒯2 小时前
Linux文件(三).Ext系列文件系统
linux·运维·服务器
懂软件的胡子个哥2 小时前
微信工单系统如何基于 WechatApi 做消息分流和状态流转
运维·分布式·微信·架构·企业微信
进击的荆棘3 小时前
Linux系统——进程控制(下)
linux·运维·服务器·进程
优化Henry3 小时前
学习笔记之关于MME不通问题归纳
运维·网络·学习·5g·信息与通信
考虑考虑10 小时前
数据库中的EXISTS
运维·数据库·后端
天远数科12 小时前
零信任架构实战:基于天远全能消金报告构建自动化信贷评估网关
运维·人工智能·架构·自动化