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.com 和 www.example.com,或主站与博客共用一张多域名证书。

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

通配符证书可以覆盖某个主域名下的所有一级子域名,例如 *.example.com 可以匹配 www.example.com、blog.example.com、api.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:告诉后端原始请求使用的协议(http 或 https)。$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 ssl、ssl_certificate、ssl_certificate_key,到安全增强的 ssl_protocols、ssl_ciphers、HSTS、OCSP Stapling 等,每一个参数都有其特定的作用。

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

相关推荐
GlobalInfo8 小时前
全球及中国机器人现场部署服务行业研究报告(2026版):市场现状、行业前景与占有率分析
大数据·运维·人工智能
Android系统攻城狮8 小时前
Linux FFmpeg深度解析之avformat_open_input调用流程与实战(一)
linux·运维·ffmpeg·车载音视频·ffmpeg音视频·音视频进阶手册
分布式存储与RustFS9 小时前
把 LSM 引擎直接架在对象存储上:slatedb 能不能跑在 RustFS 上?
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
深圳恒讯9 小时前
国外云服务器部署企业官网,怎样确定配置、IP 与后续扩容方案?
运维·服务器·tcp/ip
java_logo9 小时前
Docker 部署 Excalidraw:轻松搭建手绘风格白板
运维·docker·容器·excalidraw·白板·轩辕镜像
吹什么轩9 小时前
linux系统复习:Ext 文件系统(一个文件在磁盘上到底长什么样)
linux·运维·服务器
吹什么轩9 小时前
linux系统复习:全景串联
linux·运维·服务器
Elastic 中国社区官方博客9 小时前
5 分钟内将 56 页扫描文档转化为带引用的答案:面向搜索无法读取的文档的检索增强生成流水线
大数据·运维·人工智能·elasticsearch·搜索引擎·信息可视化·全文检索
John_Hui9 小时前
第 1 篇:VMware 安装 Ubuntu 24.04.3 Server
linux·运维·ubuntu
长不大的杨瑞杰10 小时前
OpenCode v2 团队治理实战:多仓库 Policy、灰度发布与故障回滚
运维·人工智能·安全·软件工程·devops