Nginx 安全防护与 HTTPS 部署实战全解析

前言

在互联网技术高速发展的当下,Web 服务的安全性和可靠性已然成为企业与开发者的核心关注重点。Nginx 作为一款高性能的 Web 服务器和反向代理工具,凭借轻量级架构、高并发处理能力以及灵活的模块化设计,占据了全球近三分之一的 Web 服务器市场份额,成为众多企业搭建 Web 服务的首选。

但随着网络攻击手段的不断迭代升级,DDoS、SQL 注入、恶意爬虫、CC 攻击等安全威胁层出不穷,同时全球范围内对数据隐私保护的法规要求日益严苛,如 GDPR、等保 2.0 等,这就要求运维工程师和开发者必须熟练掌握 Nginx 的安全防护策略与 HTTPS 部署技能,为 Web 服务筑牢安全防线。本文将从核心安全配置、高级防护手段、HTTPS 原理与实战部署三个维度,全面讲解 Nginx 安全防护的实操方法,助力开发者打造高安全等级的 Nginx 服务环境。

一、Nginx 核心安全配置

Nginx 的核心安全配置是保障 Web 服务基础安全的关键,涵盖编译安装的安全优化、版本号隐藏、危险请求方法限制、CC 攻击防御、防盗链配置等多个方面,每一项配置都能针对性解决一类安全隐患,以下为详细的实操步骤。

1. 编译安装 Nginx(安全编译与环境配置)

Nginx 的编译安装相比 yum 等一键安装方式,能更灵活地开启安全相关模块、指定运行用户,从安装层面规避安全风险。本次编译安装基于 OpenEuler 系统,其他 Linux 发行版可参考适配。

(1)安装支持软件

Nginx 的配置和运行依赖 pcre、zlib、openssl 等软件包,需预先安装其开发包以提供对应的库和头文件,同时安装编译工具和基础工具,命令如下:

复制代码
[root@localhost ~]# dnf install -y gcc make pcre-devel zlib-devel openssl-devel perl-ExtUtils-MakeMaker git wget tar

其中,openssl-devel是实现 HTTPS 加密的核心依赖,pcre-devel用于支持正则表达式匹配,是 Nginx 配置防盗链、请求限制的基础。

(2)创建专用运行用户、组和日志目录

为避免 Nginx 以 root 用户运行带来的高权限风险,需创建无登录权限的专用运行用户,并为日志目录设置专属权限,防止日志文件被篡改:

复制代码
[root@localhost ~]# useradd -M -s /sbin/nologin nginx
[root@localhost ~]# mkdir -p /var/log/nginx
[root@localhost ~]# chown -R nginx:nginx /var/log/nginx

-M表示不创建用户家目录,/sbin/nologin限制该用户无法通过终端登录,从权限层面降低安全风险。

(3)编译安装 Nginx(开启安全相关模块)

本次编译选择 Nginx 1.26.3 版本,核心是开启http_ssl_module(HTTPS 模块)、http_realip_module(获取真实客户端 IP)、stream(四层代理)等安全和实用模块,具体命令如下:

复制代码
[root@localhost ~]# tar zxf nginx-1.26.3.tar.gz 
[root@localhost ~]# cd nginx-1.26.3 
[root@localhost nginx-1.26.3]# ./configure \
  --prefix=/usr/local/nginx \
  --user=nginx \
  --group=nginx \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_stub_status_module\
  --with-http_gzip_static_module \
  --with-pcre \
  --with-stream 
[root@localhost nginx-1.26.3]# make && make install

编译完成后,为方便全局调用 Nginx 命令,创建主程序的软链接:

复制代码
[root@localhost nginx-1.26.3]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
(4)添加 Nginx 系统服务(实现安全的服务管理)

为 Nginx 添加 systemd 系统服务,可实现服务的启动、停止、重启等规范化管理,同时配置服务的运行权限和超时策略,配置文件如下:

复制代码
[root@localhost ~]# vi /lib/systemd/system/nginx.service

写入以下内容:

复制代码
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target

[Service]
Type=forking
ExecStartPre=/usr/local/sbin/nginx -t
ExecStart=/usr/local/sbin/nginx
ExecReload=/usr/local/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
User=root
Group=root

[Install]
WantedBy=multi-user.target

其中,ExecStartPre=/usr/local/sbin/nginx -t表示启动前先检查配置文件语法,避免因配置错误导致服务异常;PrivateTmp=true为 Nginx 分配独立的临时目录,防止临时文件被篡改。

配置完成后,重新加载系统服务并设置 Nginx 开机自启:

复制代码
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# systemctl enable nginx

2. 隐藏 Nginx 版本号

Nginx 的默认配置会在响应头中暴露版本号,攻击者可利用特定版本的漏洞发起针对性攻击,因此生产环境中必须隐藏版本号。

(1)查看当前版本号暴露情况

可通过curl命令查看 Nginx 的响应头,确认版本号是否暴露:

复制代码
[root@localhost ~]# curl -I 192.168.10.101
HTTP/1.1 200 OK
Server: nginx/1.26.3
......

响应头中Server: nginx/1.26.3明确显示了 Nginx 的版本号,存在安全隐患。

(2)修改配置文件隐藏版本号

编辑 Nginx 主配置文件,添加server_tokens off;指令:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

http块中添加该指令:

复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;     #隐藏版本号
    ......
}
(3)验证配置效果

检查配置文件语法并重新加载 Nginx,再次通过curl命令验证:

复制代码
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload
[root@localhost ~]# curl -I 192.168.10.101
HTTP/1.1 200 OK
Server: nginx
......

此时响应头中仅显示nginx,版本号已成功隐藏,有效规避了版本漏洞针对性攻击。

3. 限制危险 HTTP 请求方法

HTTP 协议支持多种请求方法,其中 GET、POST、HEAD 是日常 Web 服务中最常用的安全方法,而 PUT、DELETE、TRACE、CONNECT 等方法存在较高的安全风险:PUT/DELETE 可被利用修改或删除服务器文件,TRACE 易引发 XST 跨站追踪攻击,CONNECT 可能被滥用为代理通道。因此需通过配置限制仅允许安全的请求方法,非白名单方法直接返回 444 状态码(无响应关闭连接)。

(1)HTTP 常用方法说明

为更清晰地理解各请求方法的作用,以下为核心 HTTP 方法的功能描述:

表格

HTTP 方法 描述 安全风险
GET 请求获取 Request-URI 标识的资源 低(参数暴露在 URL,无文件操作权限)
POST 向 Request-URI 标识的资源附加新数据 低(参数隐藏在请求体,无文件操作权限)
HEAD 仅获取资源的响应消息报头 低(无实际资源获取,仅返回头信息)
PUT 请求服务器存储一个资源,以 Request-URI 为标识 高(可直接写入文件到服务器)
DELETE 请求服务器删除 Request-URI 标识的资源 高(可直接删除服务器文件)
TRACE 回显服务器收到的请求 高(引发 XST 跨站追踪攻击)
CONNECT 建立隧道连接,通常用于代理 高(被滥用为恶意代理通道)

同时,GET 和 POST 作为最常用的两种方法,在使用场景上有明显区别,具体对比如下:

表格

特性 GET 方法 POST 方法
数据长度限制 URL 最大 2048 个字符 无限制
缓存 能被浏览器缓存 不能缓存
安全性 低(参数在 URL 中,易被窃取) 高(参数在请求体,不记录在日志 / 历史)
浏览器历史 参数保留在历史中 参数不保留
书签 可收藏为书签 不可收藏

对于用户密码、表单提交等敏感操作,建议优先使用 POST 方法,避免参数泄露。

(2)配置请求方法限制

编辑 Nginx 主配置文件,在server块中添加正则匹配规则,仅允许 GET、HEAD、POST 方法:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

server块中写入:

复制代码
server {
    ......
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return 444;
       }
    ......
}
(3)验证配置效果

重新加载 Nginx 配置后,测试 PUT、DELETE 等危险方法,查看返回结果:

复制代码
[root@localhost ~]# nginx -s reload
[root@localhost ~]# curl -XPUT -I 192.168.10.101
curl: (52) Empty reply from server

查看 Nginx 访问日志,可发现该请求被记录为 444 状态码:

复制代码
[root@localhost ~]# cat /usr/local/nginx/logs/access.log
192.168.10.101 - - [11/Mar/2025:18:30:46 +0800] "PUT / HTTP/1.1" 444 0 "-" "curl/8.4.0"

注意:测试 TRACE 和 CONNECT 方法时,状态码并非 444:CONNECT 请求若目标非代理服务器,Nginx 核心层会直接返回 400 Bad Request;现代 Nginx 默认禁用 TRACE 方法,会直接返回 405 Not Allowed,这两种方法无需额外配置即可实现拦截。

4. 请求限制(CC 攻击防御)

CC 攻击(Challenge Collapsar 挑战崩溃攻击)是一种常见的应用层攻击,攻击者通过发送大量合法的小流量请求,耗尽服务器的 CPU、内存、网络等资源,导致正常用户无法访问。Nginx 提供了limit_req模块可实现请求速率限制,从源头防御 CC 攻击。

(1)配置请求速率限制

编辑 Nginx 主配置文件,在http块中定义共享内存限制区,在serverlocation块中实施速率限制:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

写入以下配置:

复制代码
http {
    # 定义限制区:10MB内存存储客户端IP,每个IP每秒最多10个请求
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
    # 其他全局配置...

    server {
        location / {
            root html;
            index index.html index.php;
            # 实施速率限制,突发请求最大20个,无延迟处理
            limit_req zone=req_limit burst=20 nodelay;
        }
        ......
    }
}
(2)核心参数说明

上述配置中核心参数的功能和作用如下,是保障限流效果的关键:

  • $binary_remote_addr:Nginx 内置变量,以二进制格式表示客户端 IP,相比字符串格式的$remote_addr,更节省内存空间;
  • zone=req_limit:10m:创建名为req_limit的共享内存区,大小 10MB,用于存储客户端 IP 和请求计数,共享内存区可实现 Nginx 多进程间的计数同步;
  • rate=10r/s:限制每个客户端 IP 每秒最多发起 10 个请求,可根据服务器性能调整;
  • burst=20:设置请求突发缓冲区,超出rate限制的请求会进入缓冲区等待,缓冲区最大可容纳 20 个请求;
  • nodelay:立即处理缓冲区中的突发请求,不进行延迟排队,若缓冲区占满,多余请求直接返回 503 Service Unavailable。
(3)压力测试验证限流效果

使用 ApacheBench(ab)工具进行压力测试,验证 CC 攻击防御效果,首先安装 ab 测试工具:

复制代码
[root@localhost ~]# dnf install httpd-tools -y

发起压力测试,模拟 30 个并发用户,总请求数 300 个:

复制代码
[root@localhost ~]# ab -n 300 -c 30 http://192.168.10.101/

测试完成后,查看 Nginx 访问日志,统计 503 状态码的请求数,验证限流效果:

复制代码
[root@localhost ~]# tail -300 /usr/local/nginx/logs/access.log | grep -c 503
279

结果显示,有 279 个请求被返回 503 状态码,说明限流配置生效,大量并发请求被成功拦截,有效防御了 CC 攻击。

5. 防盗链配置

盗链是指未经授权的网站直接链接到其他网站的静态资源(如图片、视频、音频、CSS/JS 文件),利用他人的服务器资源展示自身内容,不仅侵犯了内容创作者的版权,还会导致原网站带宽过度消耗,影响正常用户的访问速度。Nginx 可通过valid_referers指令实现防盗链配置,仅允许信任的域名访问静态资源,非信任域名直接返回 403 Forbidden。

本次防盗链实验需要两台 OpenEuler 主机,分别作为源主机(提供静态资源)和盗链主机(尝试盗用资源),具体环境信息如下:

表格

操作系统 域名 IP 地址 服务角色
OpenEuler www.aaa.com 192.168.10.101 源主机(Nginx)
OpenEuler www.bbb.com 192.168.10.102 盗链主机(httpd)
(1)配置域名与 IP 映射

为实现域名访问,需在 Windows 客户端和两台 Linux 主机的hosts文件中配置域名与 IP 的映射关系。

Windows 客户端 :编辑C:\Windows\System32\drivers\etc\hosts文件,添加:

复制代码
192.168.10.101 www.aaa.com
192.168.10.102 www.bbb.com

Linux 主机 :编辑/etc/hosts文件,添加相同的映射内容:

复制代码
[root@localhost ~]# vi /etc/hosts
192.168.10.101 www.aaa.com
192.168.10.102 www.bbb.com
(2)配置源主机(www.aaa.com

将静态资源图片kgc.png放到 Nginx 的工作目录,并编辑源网站首页,引用该图片:

复制代码
# 放入图片资源
[root@localhost ~]# cp kgc.png /usr/local/nginx/html/
# 编辑首页文件
[root@localhost ~]# vi /usr/local/nginx/html/index.html

写入以下内容:

复制代码
<html>
<body>
         <h1>aaa It work! </h1>
         <img src="kgc.png"/> 
</body>
</html>

配置完成后,通过浏览器访问http://www.aaa.com,可正常看到图片,说明源主机资源配置正常。

(3)配置盗链主机(www.bbb.com

在盗链主机上安装 httpd 服务,编辑首页文件,直接链接源主机的图片资源,模拟盗链行为:

复制代码
# 安装httpd服务
[root@localhost ~]# dnf -y install httpd
# 编辑首页文件
[root@localhost ~]# vi /var/www/html/index.html

写入以下内容,直接引用源主机的kgc.png

复制代码
<html>
<body>
    <h1>bbb It work! </h1>
    <img src="http://www.aaa.com/kgc.png"/>                          
</body>
</html>

启动 httpd 服务并关闭防火墙,确保可正常访问:

复制代码
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# systemctl start httpd

此时通过浏览器访问http://www.bbb.com,可正常看到源主机的图片,说明盗链行为成功,源主机的静态资源被非法盗用。

(4)配置 Nginx 防盗链

回到源主机,编辑 Nginx 主配置文件,添加防盗链规则,仅允许aaa.com及其子域名访问静态资源:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

server块中添加以下配置:

复制代码
location ~* \.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|webp|ico)$ {
    root html;
    # 配置信任的域名
    valid_referers  aaa.com *.aaa.com;
    # 非信任域名返回403
    if ($invalid_referer) {
        return 403;
    }
}
(5)防盗链配置核心说明

上述配置中,核心指令的功能和作用如下,可根据实际需求调整:

  • ~* \.(gif|jpg|jpeg|png|bmp|swf|flv|mp4|webp|ico)$:正则表达式,~*表示不区分大小写匹配,后面为需要保护的静态资源后缀,可根据实际业务添加 / 删除;
  • valid_referers aaa.com *.aaa.com:配置信任的引用域名,仅这些域名的请求可访问静态资源,*.aaa.com表示匹配aaa.com的所有子域名;
  • $invalid_referer:Nginx 内置变量,若请求的 Referer 头不在valid_referers配置的范围内,该变量值为 1,触发return 403
(6)验证防盗链效果

重新加载 Nginx 配置,使防盗链规则生效:

复制代码
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload

再次通过浏览器访问http://www.bbb.com,发现图片无法加载,浏览器控制台显示 403 Forbidden 错误,说明盗链行为被成功拦截,防盗链配置生效。

二、Nginx 高级防护手段

在核心安全配置的基础上,针对更复杂的网络攻击场景,Nginx 还提供了动态黑名单等高级防护手段,相比静态的allow/deny指令,动态黑名单可实现实时拦截恶意 IP,且无需重启 Nginx 服务,灵活性和效率更高,适用于高并发、攻击 IP 多变的生产环境。

1. 动态黑名单原理

动态黑名单基于 Nginx 的geo模块实现,geo模块是 Nginx 的内置模块,专门用于处理 IP 地址相关的逻辑,可根据客户端 IP 地址生成自定义变量,用于后续的访问控制判断。

动态黑名单的核心思路是:创建独立的黑名单配置文件,记录需要封禁的 IP 地址或网段及封禁策略;在 Nginx 主配置文件中通过geo模块引入该黑名单文件,生成标记变量;通过if判断指令,对标记为封禁的 IP 执行对应的拦截动作。

黑名单配置文件可手动编辑,也可通过脚本自动更新(如封禁访问次数过多的恶意 IP),实现黑名单的动态管理,无需修改主配置文件和重启 Nginx。

2. 手动配置动态黑名单

(1)创建黑名单配置文件

在 Nginx 配置目录下创建blockips.conf文件,作为动态黑名单的配置文件,记录封禁的 IP / 网段和封禁策略:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/blockips.conf

写入以下内容,封禁指定网段和 IP:

复制代码
192.168.1.0/24 1; # 封禁整个192.168.1.0/24网段
192.168.10.102 1; # 封禁盗链主机IP 192.168.10.102

其中,IP 地址后的数字代表封禁策略,不同数字对应不同的拦截动作,具体定义如下:

  • 0:允许访问(默认值);
  • 1:返回 403 Forbidden(完全封禁);
  • 2:返回 444 No Response(静默断开连接);
  • 3:返回 503 Service Unavailable(模拟服务不可用)。

可根据攻击场景选择合适的封禁策略,例如针对恶意爬虫可使用 444 静默断开,针对暴力破解可使用 403 完全封禁。

(2)在主配置文件中引入黑名单

编辑 Nginx 主配置文件,在http块中通过geo模块引入黑名单配置文件,生成标记变量$block_ip

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

写入以下配置:

复制代码
http {
    ......
    # 配置geo模块,生成$block_ip变量
    geo $block_ip {
        default 0;          # 默认允许所有IP访问,标记为0
        include /usr/local/nginx/conf/blockips.conf;  # 引入黑名单配置文件
    }
    ......
    server {
        ......
        # 判断标记变量,若为非0则执行封禁动作
        if ($block_ip) {    
            return 403;     # 封禁动作,返回403 Forbidden
        }
        ......
    }
}
(3)验证手动封禁效果

重新加载 Nginx 配置,使动态黑名单生效:

复制代码
[root@localhost ~]# nginx -t
[root@localhost ~]# nginx -s reload

使用被封禁的 IP(192.168.10.102)测试访问源主机,查看返回结果:

复制代码
[root@localhost ~]# curl 192.168.10.101
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>

结果显示返回 403 Forbidden,说明动态黑名单生效,被封禁的 IP 无法正常访问。若需要解封 IP,只需在blockips.conf文件中删除对应的 IP 记录,重新加载 Nginx 配置即可,无需重启服务,操作灵活。

3. 脚本自动更新动态黑名单

在生产环境中,恶意 IP 的数量多、变化快,手动编辑黑名单效率低,可通过 Shell 脚本实现黑名单的自动更新,例如封禁一定时间内访问次数超过阈值的 IP,从源头拦截暴力破解、恶意爬虫等行为。

(1)编写自动封禁脚本

创建 Shell 脚本auto_block_ip.sh,实现统计 Nginx 访问日志中访问次数超过 100 次的 IP,并自动写入黑名单配置文件:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/auto_block_ip.sh

写入以下内容:

复制代码
#!/bin/bash
# 自动封禁Nginx访问日志中访问次数超过100次的IP
# 统计访问日志中的客户端IP,排序并去重计数,筛选出访问次数>100的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | awk '{if($1>100) print $2" 1;"}' > /usr/local/nginx/conf/blockips.conf
# 重新加载Nginx配置,使黑名单生效
/usr/local/sbin/nginx -s reload
(2)脚本核心命令说明

脚本中核心的 Linux 命令功能如下,是实现 IP 统计和筛选的关键:

  • awk '{print $1}' /var/log/nginx/access.log:提取 Nginx 访问日志中的第一列(客户端 IP 地址);
  • sort:对提取的 IP 地址进行排序,为后续去重做准备;
  • uniq -c:对排序后的 IP 地址去重,并统计每个 IP 的访问次数,结果为 "访问次数 IP 地址";
  • sort -nr:按访问次数进行降序排序,方便筛选高频访问 IP;
  • awk '{if($1>100) print $2" 1;"}':筛选出访问次数大于 100 的 IP,按黑名单的格式写入配置文件。
(3)设置脚本定时执行

为实现脚本的自动运行,通过crontab设置定时任务,例如每 10 分钟执行一次,自动更新黑名单:

复制代码
# 赋予脚本执行权限
[root@localhost ~]# chmod +x /usr/local/nginx/conf/auto_block_ip.sh
# 编辑crontab定时任务
[root@localhost ~]# crontab -e

写入以下内容,设置每 10 分钟执行一次:

复制代码
*/10 * * * * /usr/local/nginx/conf/auto_block_ip.sh

保存后,crontab 会自动加载定时任务,脚本将每 10 分钟统计一次访问日志,自动封禁高频访问的恶意 IP,实现动态黑名单的自动化管理,大幅提升防护效率。

三、Nginx HTTPS 部署实战

HTTP 协议采用明文传输,存在窃听、篡改、冒充三大安全风险,而 HTTPS 协议通过 SSL/TLS 加密实现了数据的安全传输,是当前 Web 服务的标配。同时,Google、Chrome、苹果、微信等各大平台均对 HTTPS 提供优先支持,HTTP/2 协议也需基于 HTTPS 实现。本节将从 HTTPS 核心原理入手,详细讲解 Nginx 中 HTTPS 的部署步骤,包括自签名证书生成和正式 CA 证书的配置思路。

1. HTTPS 核心概念与原理

(1)HTTPS 的定义

HTTPS 的全称为 HyperText Transfer Protocol over Secure Socket Layer,即基于 SSL/TLS 加密的超文本传输协议,本质上是 "HTTP + SSL/TLS" 的组合,在 HTTP 协议和 TCP 协议之间增加了 SSL/TLS 加密层,实现了应用层数据的加解密,保障数据传输的安全性。

(2)SSL/TLS 协议演进

SSL 和 TLS 是实现加密的核心协议,二者是继承与发展的关系,目前 TLS 已取代 SSL 成为主流,具体的版本演进和现状如下:

  • SSL 协议:由 Netscape 公司开发,包括 SSL 1.0(未公开发布)、SSL 2.0(存在严重安全漏洞,已废弃)、SSL 3.0(2014 年因 POODLE 攻击漏洞被逐步淘汰);
  • TLS 协议:由 IETF(互联网工程任务组)制定,基于 SSL 3.0 改进而来,包括 TLS 1.0(1999 年发布)、TLS 1.1(2006 年发布)、TLS 1.2(2008 年发布,主流使用)、TLS 1.3(2018 年发布,性能和安全性更优);
  • 现状:TLS 1.0 和 TLS 1.1 已于 2021 年被正式弃用,生产环境中建议仅开启 TLS 1.2 和 TLS 1.3。
(3)HTTP 的三大安全风险

HTTP 协议因明文传输的特性,在数据传输过程中存在三大核心安全风险,这也是 HTTPS 的解决核心:

  1. 窃听风险:中间人可通过抓包等方式获取 HTTP 传输的明文内容,例如用户的账号密码、交易信息等,造成敏感信息泄露;
  2. 篡改风险:中间人可截获 HTTP 请求 / 响应报文,修改其中的内容后重新发送,例如修改支付金额、订单信息等,造成业务损失;
  3. 冒充风险:中间人可伪装成合法的服务器与客户端通信,例如搭建钓鱼网站,骗取用户的敏感信息,用户无法识别通信对象的真实性。
(4)安全通信的四大原则

为解决 HTTP 的安全风险,安全的网络通信需遵循四大原则,而 HTTPS 通过 SSL/TLS 加密完美实现了这四大原则:

  1. 机密性:对传输的数据进行加密,即使数据被中间人截获,也无法解析出明文,解决窃听风险;
  2. 完整性:通过消息摘要验证数据的完整性,数据在传输过程中若被篡改,接收方可立即识别,解决篡改风险;
  3. 身份认证:通过数字证书验证通信双方的真实身份,确保客户端访问的是合法服务器,解决冒充风险;
  4. 不可否认:通过数字签名证明数据的发送方,发送方无法否认已发送的信息,保障交易的有效性。
(5)HTTPS 的通信原理

HTTPS 的通信原理核心是混合加密机制 (非对称加密 + 对称加密),结合了非对称加密的安全性和对称加密的高效性,同时通过数字证书解决了非对称加密中公钥的传输信任问题,整个通信过程可分为证书验证、密钥协商、数据传输三个阶段,具体流程如下:

阶段 1:证书验证(解决身份认证和公钥信任问题)
  1. 客户端向服务器发起 HTTPS 请求,服务器将自身的数字证书(包含服务器公钥、域名、证书有效期、CA 签名等信息)返回给客户端;
  2. 客户端接收到数字证书后,使用操作系统内置的根 CA 公钥验证证书的数字签名:根 CA 证书是操作系统信任的权威证书,内置在 Windows、Linux、macOS 等系统中,无需网络传输;
  3. 若签名验证通过,说明数字证书合法,服务器身份真实,客户端可从证书中提取服务器的公钥;若验证失败,客户端会向用户提示证书不安全,终止连接。

数字证书的作用:防止服务器公钥在传输过程中被中间人调包,解决了非对称加密中公钥的信任问题。中间人无法伪造合法的数字证书,因为伪造的证书无法通过根 CA 公钥的签名验证,且数字证书中包含的域名是唯一的,无法伪装成合法域名。

阶段 2:密钥协商(通过非对称加密协商对称加密密钥)
  1. 客户端生成一个随机的会话密钥(即对称加密的密钥),使用服务器的公钥对该会话密钥进行加密;
  2. 客户端将加密后的会话密钥发送给服务器;
  3. 服务器接收到后,使用自身的私钥解密,获取客户端生成的会话密钥。

此阶段使用非对称加密,因为非对称加密的公钥加密、私钥解密特性,可保障会话密钥在传输过程中的安全性,即使被中间人截获,也无法解密出会话密钥。

阶段 3:数据传输(通过对称加密传输实际数据)

客户端和服务器使用协商好的会话密钥进行对称加密,后续的所有 HTTP 请求和响应数据,都通过该会话密钥进行加解密后传输。

混合加密的原因:非对称加密的加解密效率较低,若直接用于大量数据的传输,会导致服务器性能下降、通信延迟增加;而对称加密的加解密效率极高,适合大量数据的传输,但对称加密的密钥需要安全协商。因此 HTTPS 采用 "非对称加密协商密钥,对称加密传输数据" 的混合模式,兼顾安全性和效率。

2. 生成 SSL 证书

SSL 证书是 HTTPS 部署的核心,分为自签名证书CA 签名证书两种,二者的适用场景和生成方式不同,具体如下:

  • 自签名证书:由自己为自己签发的证书,无需第三方 CA 机构参与,生成简单,适用于测试、内部环境或无需公开信任的场景,但浏览器会提示证书不安全;
  • CA 签名证书:由受信任的第三方 CA 机构(如 Let's Encrypt、DigiCert、阿里云、腾讯云等)签发的证书,浏览器会信任该证书,适用于生产环境,需要向 CA 机构申请并完成身份验证。

本节首先讲解自签名证书的生成方法(适用于实验和测试),同时介绍 CA 签名证书的申请流程(适用于生产环境)。

(1)生成自签名证书(OpenSSL 工具)

使用 Linux 系统自带的 OpenSSL 工具生成自签名证书,步骤如下:

步骤 1:创建证书存储目录

为方便管理,在/etc/nginx/下创建 ssl 目录,用于存储证书和私钥:

复制代码
[root@localhost ~]# mkdir -p /etc/nginx/ssl
步骤 2:生成自签名证书和私钥

使用openssl req命令生成自签名证书,一次性生成私钥文件nginx-selfsigned.key和证书文件nginx-selfsigned.crt,命令如下:

复制代码
[root@localhost ~]# openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx-selfsigned.key \
-out /etc/nginx/ssl/nginx-selfsigned.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/CN=localhost"
步骤 3:核心参数说明

上述命令中核心参数的功能和作用如下,可根据实际需求调整:

  • -x509:指定生成自签名证书,而非证书签名请求(CSR);
  • -nodes:表示不加密私钥文件,避免 Nginx 启动时需要输入私钥密码;
  • -days 365:设置证书的有效期为 365 天,到期后需重新生成;
  • -newkey rsa:2048:生成一个新的 2048 位的 RSA 私钥,2048 位是当前的安全标准,避免使用 1024 位(安全性较低);
  • -keyout:指定私钥文件的存储路径和名称;
  • -out:指定自签名证书文件的存储路径和名称;
  • -subj:指定证书的主题信息,无需交互式输入,各字段含义:
    • C:国家代码(如 CN 表示中国);
    • ST:省份 / 州(如 Beijing 表示北京市);
    • L:城市 / 地区(如 Beijing 表示北京市);
    • O:组织 / 公司名称(如 MyOrg 表示自定义组织);
    • CN:通用名称(如localhost表示本地测试,生产环境需填写域名)。

生成完成后,可在/etc/nginx/ssl/目录下看到生成的私钥和证书文件:

复制代码
[root@localhost ~]# ls /etc/nginx/ssl/
nginx-selfsigned.crt  nginx-selfsigned.key
(2)申请 CA 签名证书(生产环境)

生产环境中需使用 CA 签名证书,以获得浏览器的信任,目前 Let's Encrypt 提供免费的 CA 签名证书,各大云厂商(阿里云、腾讯云、华为云)也提供付费的 CA 签名证书,申请流程大致如下:

  1. 生成私钥和 CSR 文件:使用 OpenSSL 工具生成服务器私钥和证书签名请求(CSR)文件,CSR 文件包含服务器的公钥、域名、组织信息等;
  2. 提交 CSR 文件:将 CSR 文件提交给 CA 机构(如 Let's Encrypt、阿里云),并完成域名验证(如 DNS 验证、文件验证),证明域名的所有权;
  3. 获取 CA 证书:CA 机构验证通过后,会生成 CA 签名证书,包含服务器证书、中间 CA 证书等,下载并保存到服务器;
  4. 配置证书:将 CA 机构提供的证书和自身的私钥配置到 Nginx 中,即可实现 HTTPS 的生产环境部署。

3. Nginx 配置 HTTPS 并实现 HTTP 重定向

生成证书后,编辑 Nginx 主配置文件,开启 443 端口(HTTPS 默认端口),配置证书和私钥路径,同时为提升用户体验,可配置将 HTTP(80 端口)请求自动重定向到 HTTPS(443 端口),实现全站 HTTPS。

(1)编辑 Nginx 主配置文件

打开 Nginx 主配置文件,添加 HTTPS 的 server 块配置,并配置 HTTP 重定向的 server 块:

复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf
(2)配置 HTTPS 核心参数

在配置文件中写入以下内容,核心是开启 443 ssl 监听、指定证书和私钥路径、配置安全的 SSL/TLS 协议和加密套件:

复制代码
# HTTPS配置块,监听443端口
server {
    listen 443 ssl;  # 监听HTTPS默认端口443,开启ssl
    server_name localhost;  # 本地测试填写localhost,生产环境填写实际域名(如www.aaa.com)

    # 指定SSL证书和私钥的路径
    ssl_certificate      /etc/nginx/ssl/nginx-selfsigned.crt;
    ssl_certificate_key  /etc/nginx/ssl/nginx-selfsigned.key;

    # 配置SSL/TLS协议,仅开启安全的TLS 1.2和TLS 1.3
    ssl_protocols TLSv1.2 TLSv1.3;
    # 配置安全的加密套件,优先使用GCM模式的加密算法
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    # 优先使用服务器端的加密套件选择策略
    ssl_prefer_server_ciphers on;

    # 网站根目录和默认首页配置
    location / {
        root /usr/local/nginx/html;
        index index.html;
    }
}

# HTTP重定向到HTTPS配置块,监听80端口
server {
    listen 80;
    server_name localhost;  # 与HTTPS的server_name保持一致
    # 301永久重定向,将所有HTTP请求重定向到HTTPS
    return 301 https://$host$request_uri;
}

关键注意点 :HTTP 重定向的 server 块需单独配置,不能写在 HTTPS 的 server 块中,否则会导致无限重定向,引发服务异常。

(3)核心 SSL/TLS 配置说明

上述配置中,SSL/TLS 的相关配置是提升 HTTPS 安全性的关键,避免使用不安全的协议和加密套件,具体说明:

  • ssl_protocols TLSv1.2 TLSv1.3:仅开启 TLS 1.2 和 TLS 1.3,禁用已废弃的 SSL 3.0、TLS 1.0、TLS 1.1,降低漏洞风险;
  • ssl_ciphers:配置加密套件,选择安全性高、性能好的 GCM 模式加密算法,避免使用 CBC 模式(存在漏洞风险);
  • ssl_prefer_server_ciphers on:让服务器优先选择自己的加密套件,而非客户端的,确保使用最安全的加密方式。
(4)验证配置并重启 Nginx

配置完成后,首先检查 Nginx 配置文件的语法,避免因配置错误导致服务异常:

复制代码
[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

语法检查通过后,重新加载 Nginx 配置,使 HTTPS 配置生效:

复制代码
[root@localhost ~]# nginx -s reload

4. 验证 HTTPS 部署效果

(1)浏览器访问验证

通过浏览器访问https://服务器IP(如https://192.168.10.101),由于使用的是自签名证书,浏览器会提示 "您的连接不是私密连接",这是正常现象(测试环境可忽略)。

点击浏览器的 "高级" 选项,选择 "继续前往" 或 "信任此证书",即可正常访问网站,此时浏览器地址栏会显示锁形图标,说明 HTTPS 连接已成功建立。

同时,访问http://服务器IP(如http://192.168.10.101),会自动跳转到https://服务器IP,说明 HTTP 重定向到 HTTPS 的配置生效,实现了全站 HTTPS。

(2)命令行验证

可通过curl命令验证 HTTPS 连接和重定向效果,具体命令如下:

复制代码
# 验证HTTPS连接
[root@localhost ~]# curl -I https://192.168.10.101 -k
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html
Content-Length: 615
Last-Modified: Wed, 10 Mar 2025 08:00:00 GMT
Connection: keep-alive
ETag: "6617f000-267"
Accept-Ranges: bytes

-k参数表示忽略证书验证(自签名证书专用),返回 200 OK 说明 HTTPS 连接正常。

复制代码
# 验证HTTP重定向
[root@localhost ~]# curl -I http://192.168.10.101
HTTP/1.1 301 Moved Permanently
Server: nginx
Location: https://192.168.10.101/
Content-Length: 162
Content-Type: text/html

返回 301 Moved Permanently,且Location指向 HTTPS 地址,说明重定向配置生效。

四、总结

本文从实战角度出发,全面讲解了 Nginx 的安全防护策略与 HTTPS 部署方法,核心内容可分为三大模块:

  1. 核心安全配置:从 Nginx 的编译安装入手,通过隐藏版本号、限制危险请求方法、配置请求限流防御 CC 攻击、设置防盗链等操作,筑牢 Web 服务的基础安全防线,每一项配置都针对性解决了一类常见的安全隐患;
  2. 高级防护手段 :基于 Nginx 的geo模块实现动态黑名单,支持手动和脚本自动更新,可实时拦截恶意 IP,相比静态的allow/deny指令更灵活高效,适用于高并发的生产环境;
  3. HTTPS 部署实战:从 HTTPS 的核心原理出发,讲解了 SSL/TLS 协议、混合加密机制、数字证书的作用,通过 OpenSSL 工具生成自签名证书,配置 Nginx 实现 HTTPS 访问,并将 HTTP 请求自动重定向到 HTTPS,同时介绍了生产环境中 CA 签名证书的申请思路。

Nginx 的安全防护是一个持续的过程,除了本文介绍的配置外,生产环境中还可结合 WAF(Web 应用防火墙)、日志审计、服务器防火墙(如 iptables、firewalld)等手段,构建多层级的安全防护体系。同时,需及时更新 Nginx 版本,修复已知漏洞,根据业务场景调整安全配置参数,才能始终保持 Web 服务的高安全性和高可用性。

相关推荐
MaximusCoder2 小时前
等保测评命令——达梦数据库 DM
linux·运维·数据库·安全·ffmpeg·安全威胁分析
主角1 72 小时前
Nginx性能优化与监控
网络·nginx·性能优化
Wyawsl2 小时前
nginx安全笔记
笔记·nginx·安全
老赵聊算法、大模型备案3 小时前
网信办公示 2026 年 1-2 月生成式 AI 备案登记情况:新增 94 款,累计突破 1200 款
人工智能·算法·安全·aigc
jixingkj3 小时前
手机截屏失败全解析:从操作误区到系统设置的深度解密
大数据·安全·智能手机
小草cys3 小时前
电网的安全稳定裕度
安全·电网安全
funkygroove3 小时前
药物安全信息如何高效利用?结构化数据如何提升效率
安全·医药数据库
左左右右左右摇晃3 小时前
HTTP与HTTPS整理
笔记·http·https
桌面运维家3 小时前
Windows医疗云桌面:安全高效解决方案
安全