Nginx 安全防护与 HTTPS 部署实战

一、实战背景

Nginx 作为高性能 Web 服务器和反向代理工具,凭借轻量级、高并发、模块化设计的优势,占据全球近三分之一 Web 服务器市场份额。但随着 DDoS、SQL 注入、恶意爬虫等网络攻击手段升级,以及 GDPR、等保 2.0 等数据隐私法规的要求,做好 Nginx 安全防护与 HTTPS 部署,是运维工程师的核心必备技能。

本次实战将从核心安全配置高级安全防护HTTPS 原理与部署三部分展开,包含完整实操代码,同时补充关键知识点,兼顾实用性和易理解性。

二、核心安全配置

核心安全配置是 Nginx 安全的基础,涵盖编译安装、版本隐藏、请求限制、防盗链等关键操作,从服务器基础部署到请求层安全做全方位防护。

2.1 编译安装 Nginx(含安全模块)

编译安装可自主选择安全相关模块,相比 yum 安装更灵活,是生产环境的首选方式。

2.1.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 部署、SSL 加密的核心依赖,缺少则无法编译http_ssl_module模块。

2.1.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

补充知识点/sbin/nologin让用户仅能运行 Nginx 进程,无法通过终端登录服务器,从账户层面提升安全。

2.1.3 编译安装 Nginx(启用安全模块)

以 nginx-1.26.3 为例,启用 SSL、真实 IP、请求状态统计等核心安全模块:

复制代码
[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 \    # HTTPS核心模块
--with-http_v2_module \     # HTTP/2模块,需基于HTTPS
--with-http_realip_module \ # 获取客户端真实IP,防代理隐藏
--with-http_stub_status_module \ # 监控Nginx连接状态
--with-http_gzip_static_module \ # 静态资源压缩,降低带宽消耗
--with-pcre \
--with-stream               # 四层转发,支持TCP/UDP代理
[root@localhost nginx-1.26.3]# make && make install
2.1.4 创建软链接 + 添加系统服务

创建软链接让系统识别 nginx 命令,添加 systemd 服务实现开机自启和便捷管理:

复制代码
# 创建软链接
[root@localhost nginx-1.26.3]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
# 编写系统服务文件
[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

重载服务并设置开机自启:

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

补充知识点ExecStartPre=/usr/local/sbin/nginx -t是关键安全操作,避免配置文件错误导致 Nginx 启动失败,保障服务可用性。

2.2 隐藏 Nginx 版本号

攻击者常通过版本号针对性利用漏洞,隐藏版本号可大幅降低被攻击概率。

2.2.1 查看当前版本号
复制代码
[root@localhost ~]# curl -I 192.168.10.101  # 服务器IP
# 输出会显示 Server: nginx/1.26.3,暴露版本
2.2.2 修改配置文件隐藏版本
复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

http块中添加server_tokens off;,注释或保留原有核心配置:

nginx

复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;
    server_tokens off;  # 隐藏Nginx版本号
    # 其他配置...
}
2.2.3 验证配置并生效
复制代码
[root@localhost ~]# nginx -t  # 语法检查
[root@localhost ~]# nginx -s reload  # 平滑重启
# 再次查看,版本号消失
[root@localhost ~]# curl -I 192.168.10.101
# 输出 Server: nginx,无版本信息

2.3 限制危险 HTTP 请求方法

HTTP 的 PUT、DELETE、TRACE、CONNECT 等方法存在安全风险(如 PUT 可上传文件、TRACE 引发 XST 攻击),仅保留业务必需的 GET、HEAD、POST 方法。

2.3.1 修改配置文件
复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

server块中添加请求方法判断,非白名单方法返回 444(静默断开连接):

nginx

复制代码
server {
    listen       80;
    server_name  localhost;
    # 限制请求方法,仅允许GET、HEAD、POST
    if ($request_method !~ ^(GET|HEAD|POST)$) {
        return 444;
    }
    # 其他配置...
}
2.3.2 验证配置并测试
复制代码
[root@localhost ~]# nginx -t && nginx -s reload
# 测试PUT方法,返回空响应(444)
[root@localhost ~]# curl -XPUT -I 192.168.10.101
# 输出 curl: (52) Empty reply from server

补充知识点:Nginx 默认禁用 TRACE 方法,直接返回 405;CONNECT 方法若目标非代理服务器,会被核心层拦截返回 400,因此这两种方法无需额外配置。

2.4 限制请求速率(防御 CC 攻击)

CC 攻击通过大量小流量请求耗尽服务器资源,利用 Nginx 的limit_req模块限制单 IP 请求速率,是防御 CC 攻击的核心手段。

2.4.1 修改配置文件开启限速
复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

http块定义限速内存区,在server块的location中启用限速:

nginx

复制代码
http {
    # 定义限速区:10M内存存储IP,单IP每秒最多10个请求
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
    # 其他配置...
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
            # 启用限速,突发请求缓冲区20个,无延迟处理
            limit_req zone=req_limit burst=20 nodelay;
        }
        # 其他配置...
    }
}

补充知识点$binary_remote_addr以二进制存储客户端 IP,相比普通 IP 存储更节省内存;burst=20为突发请求设置缓冲区,避免正常突发请求被拦截;nodelay表示缓冲区请求立即处理,超出部分直接返回 503。

2.4.2 安装压测工具验证

使用 ApacheBench(ab)压测,验证限速效果:

复制代码
# 安装ab工具
[root@localhost ~]# dnf install httpd-tools -y
# 发起300个请求,并发30个
[root@localhost ~]# ab -n 300 -c 30 http://192.168.10.101/
# 查看日志,大量请求返回503(服务暂时不可用)
[root@localhost ~]# tail -300 /usr/local/nginx/logs/access.log | grep -c 503

2.5 配置防盗链(防止资源盗用)

盗链指其他网站未经授权引用本站静态资源(图片、视频、SWF),导致本站带宽消耗、版权受损,通过 Nginx 配置可限制资源引用来源。本次实战需两台主机:源主机(192.168.10.101,www.aaa.com)、盗链主机(192.168.10.102,www.bbb.com)。

2.5.1 配置域名与 IP 映射

Windows 主机 :修改C:\Windows\System32\drivers\etc\hosts

plaintext

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

两台 OpenEuler 主机 :修改/etc/hosts

复制代码
[root@localhost ~]# vi /etc/hosts
192.168.10.101 www.aaa.com
192.168.10.102 www.bbb.com
2.5.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>
2.5.3 配置盗链主机(www.bbb.com

安装 httpd 并编辑首页,未经授权引用源主机图片:

复制代码
[root@localhost ~]# dnf -y install httpd
[root@localhost ~]# vi /var/www/html/index.html
<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

此时访问www.bbb.com可看到源主机图片,盗链成功。

2.5.4 源主机配置 Nginx 防盗链
复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

server块中添加防盗链规则,仅允许本站域名引用资源:

nginx

复制代码
server {
    listen       80;
    server_name  www.aaa.com;
    # 对图片、SWF等静态资源做防盗链
    location ~* \.(jpg|gif|swf|png)$ {
        root   html;
        # 信任的域名:本站及子域名
        valid_referers aaa.com *.aaa.com;
        # 非信任来源返回403
        if ($invalid_referer) {
            return 403;
        }
    }
    # 其他配置...
}
2.5.5 验证防盗链效果
复制代码
[root@localhost ~]# nginx -t && nginx -s reload

再次访问www.bbb.com,图片位置显示 403 错误,盗链失败。补充知识点~*表示正则匹配不区分大小写;valid_referers后可添加none(允许直接访问资源,如直接输入图片 URL)、blocked(允许来源地址被隐藏的请求)。

三、高级安全防护

核心配置解决基础安全问题,高级防护针对动态攻击场景做优化,包括动态黑名单 (实时封禁恶意 IP),相比静态allow/deny更灵活,无需重启 Nginx 即可更新封禁规则。

3.1 配置静态动态黑名单

3.1.1 创建黑名单配置文件
复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/blockips.conf
# 格式:IP/网段 标记值(0=允许,1=403封禁,2=444静默断开,3=503服务不可用)
192.168.1.0/24 1;  # 封禁整个网段
192.168.10.102 1;  # 封禁盗链主机IP
3.1.2 修改 Nginx 主配置文件引入黑名单

利用 Nginx 内置geo模块处理 IP 逻辑,动态识别黑名单 IP:

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

http块中添加geo配置,在server块中添加封禁规则:

nginx

复制代码
http {
    # 定义geo模块,判断客户端IP是否在黑名单
    geo $block_ip {
        default 0;  # 默认允许所有IP
        include /usr/local/nginx/conf/blockips.conf;  # 引入黑名单文件
    }
    # 其他配置...
    server {
        listen       80;
        server_name  localhost;
        # 若IP在黑名单(block_ip=1),返回403
        if ($block_ip) {
            return 403;
        }
        # 其他配置...
    }
}
3.1.3 验证黑名单效果
复制代码
[root@localhost ~]# nginx -t && nginx -s reload
# 用被封禁的IP测试访问,返回403
[root@localhost ~]# curl 192.168.10.101
# 输出403 Forbidden页面

3.2 编写脚本实现自动封禁恶意 IP

手动维护黑名单效率低,编写 Shell 脚本,自动封禁访问次数超过阈值的 IP,适配高并发攻击场景。

3.2.1 编写自动封禁脚本
复制代码
[root@localhost ~]# vi /root/auto_block_ip.sh
#!/bin/bash
# 自动封禁访问次数超过100次的IP
# 从Nginx访问日志提取IP,统计访问次数,按次数倒序
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr \
# 过滤访问次数>100的IP,写入黑名单文件
| awk '{if($1>100) print $2" 1;"}' > /usr/local/nginx/conf/blockips.conf
# 平滑重启Nginx,使黑名单生效
/usr/local/sbin/nginx -s reload
3.2.2 赋予脚本执行权限并测试
复制代码
[root@localhost ~]# chmod +x /root/auto_block_ip.sh
[root@localhost ~]# sh /root/auto_block_ip.sh

补充知识点 :可通过crontab设置脚本定时执行,实现实时监控封禁,例如每 5 分钟执行一次:

复制代码
[root@localhost ~]# crontab -e
# 添加以下内容
*/5 * * * * /root/auto_block_ip.sh

四、HTTPS 部署实战

HTTP 为明文传输,存在窃听、篡改、冒充三大风险,HTTPS(HTTP+SSL/TLS)通过加密解决上述问题,同时是 HTTP/2、小程序开发、搜索引擎优化的必备条件。

4.1 HTTPS 核心基础知识点

  1. 加密模式:混合加密(握手阶段非对称加密,传输阶段对称加密),兼顾安全性和传输效率;
  2. 核心协议:SSL 已废弃,主流使用 TLS1.2/TLS1.3(TLS1.0/TLS1.1 于 2021 年弃用);
  3. 数字证书:解决公钥传输信任问题,由 CA 机构签发,包含域名、公钥、数字签名等信息,操作系统内置根 CA 公钥,可验证证书真伪;
  4. 证书类型:CA 签名证书(公网环境使用,如 Let's Encrypt 免费证书)、自签名证书(测试 / 内网环境使用,不被公网信任)。

4.2 生成自签名证书(测试环境)

生产环境需向 CA 机构申请证书,测试环境可通过 OpenSSL 生成自签名证书,步骤如下:

4.2.1 创建证书存储目录
复制代码
[root@localhost ~]# mkdir -p /etc/nginx/ssl
4.2.2 生成自签名证书和私钥
复制代码
[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"

参数解释

  • -x509:生成自签名证书(非 CSR 请求文件);
  • -nodes:不加密私钥,避免 Nginx 启动时需要输入密码;
  • -days 365:证书有效期 1 年;(现实不建议怎么长时间)
  • -newkey rsa:2048:生成 2048 位 RSA 私钥(密钥越长越安全,推荐 2048 位及以上);
  • -subj:证书主题信息(C = 国家,ST = 省份,L = 城市,O = 组织,CN = 域名 / IP)。

4.3 Nginx 配置 HTTPS 并实现 HTTP 重定向

4.3.1 修改 Nginx 主配置文件
复制代码
[root@localhost ~]# vi /usr/local/nginx/conf/nginx.conf

配置 443 端口(HTTPS 默认端口),指定证书 / 私钥路径,同时将 80 端口 HTTP 请求重定向到 HTTPS:

复制代码
http {
    # 其他全局配置...
    # 配置HTTPS服务
    server {
        listen       443 ssl;  # 监听443端口,启用SSL
        server_name  localhost; # 对应证书的CN字段(域名/IP)

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

        # 配置SSL协议和加密套件,仅启用安全版本
        ssl_protocols TLSv1.2 TLSv1.3;
        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 index.htm;
        }
    }

    # 将80端口HTTP请求永久重定向到443端口HTTPS
    server {
        listen       80;
        server_name  localhost;
        return 301 https://$host$request_uri;  # $host为域名,$request_uri为请求路径
    }
}

补充知识点return 301为永久重定向,搜索引擎会将 HTTP 地址的权重转移到 HTTPS 地址,利于 SEO;ssl_prefer_server_ciphers on让服务器端选择更安全的加密套件,避免客户端选择低安全套件。

4.3.2 验证配置并生效
复制代码
[root@localhost ~]# nginx -t  # 语法检查
[root@localhost ~]# nginx -s reload  # 平滑重启

4.4 验证 HTTPS 访问

通过浏览器访问https://服务器IP(如https://192.168.10.101),浏览器会提示 "证书不安全"(自签名证书未被 CA 信任),选择高级继续前往 ,即可看到 HTTPS 加密的站点页面,同时访问http://服务器IP会自动跳转到 HTTPS 地址。

补充知识点:生产环境使用 CA 签名证书后,浏览器会显示绿色锁标,无安全警告,可通过 Let's Encrypt 申请免费的 CA 签名证书,有效期 3 个月,支持自动续期。

五、实战总结

本次 Nginx 安全防护与 HTTPS 部署实战,从基础编译安装核心安全配置 ,再到高级动态防护HTTPS 加密部署,形成了完整的 Nginx 安全防护体系,核心要点如下:

  1. 编译安装 Nginx 时,需启用http_ssl_modulehttp_realip_module等安全模块,同时使用专用低权限用户运行;
  2. 核心安全配置需做到:隐藏版本号、限制危险请求方法、限速防 CC 攻击、配置防盗链,从请求层阻断大部分攻击;
  3. 动态黑名单可实时封禁恶意 IP,结合 Shell 脚本和定时任务,实现自动化攻击防护;
  4. HTTPS 是公网站点的必备配置,采用混合加密模式,配置时需启用 TLS1.2/TLS1.3,同时实现 HTTP 到 HTTPS 的自动重定向;
  5. 测试环境使用自签名证书,生产环境需使用 CA 机构签发的证书(如 Let's Encrypt 免费证书),保障证书被公网信任。

通过以上配置,可大幅提升 Nginx 服务器的安全性和可靠性,有效抵御常见的网络攻击,同时满足数据隐私保护的法规要求。

相关推荐
皙然2 小时前
深入浅出 HTTP 与 HTTPS:核心区别、加密原理与实战解析
网络协议·http·https
ego.iblacat2 小时前
Nginx 安全防护与 HTTPS 部署实战
nginx·安全·https
好家伙VCC2 小时前
# Deno实战:从零搭建一个安全、现代的后端服务在Node.js生态逐渐臃肿
java·python·安全·node.js
刘晨鑫12 小时前
Nginx安全防护与HTTPS部署实战
nginx·安全·https
白帽子黑客-宝哥2 小时前
应急响应是什么?网络安全事件的“消防队”
网络·安全·web安全·应急响应·攻防演练
星幻元宇VR2 小时前
VR消防安全学习机|让安全教育更立体、更真实
科技·学习·安全·vr·虚拟现实
写代码的小阿帆2 小时前
SpringBoot项目部署——命令行、Nginx代理与docker容器
spring boot·nginx·docker
一起来学吧2 小时前
【OpenClaw系列教程】第五篇:OpenClaw安全指南 - 了解风险,安全使用 AI Agent
安全·ai·openclaw
J超会运2 小时前
Nginx安全配置实战:8大核心功能详解
运维·nginx·安全