生产环境必配!Nginx限流防攻击完整教程,复制就能上线,告别恶意请求
|
admin
2026年4月1日 22:2
本文热度 32
|
上一篇我们掌握了Nginx HTTPS配置,实现了网站加密访问,解决了浏览器“不安全”提示,满足了生产环境的安全基础要求。但生产环境中,仅靠HTTPS还不够——网站上线后,难免会遇到恶意请求、高频爬虫、DDoS攻击:比如有人恶意高频请求接口,导致服务器负载飙升、卡顿崩溃;爬虫疯狂抓取网站数据,消耗服务器带宽和资源;甚至有人发起DDoS攻击,直接导致网站无法访问。本篇文件教你用Nginx实现限流防攻击,从核心限流策略到防爬虫、防恶意请求,全程大白话、无复杂操作,新手跟着步骤走,15分钟就能完成配置,复制配置就能直接上线,彻底保护服务器安全,避免被恶意请求压垮。
- 用大白话搞懂:什么是Nginx限流,为什么生产环境必须配置
- Nginx 3种核心限流策略(固定窗口、滑动窗口、漏桶),按需选型
- 企业级限流完整配置(直接复制,适配HTTPS/负载均衡场景)
- 限流防攻击最常见6个报错,一键解决(限流失效、误拦正常请求等)
- 限流+HTTPS+负载均衡联动配置(企业安全部署方案)
提前说明:限流防攻击是Nginx生产环境必备的安全防护,配置后不会影响正常用户访问,只会拦截高频恶意请求、爬虫和攻击请求。本文配置将完全兼容前面的HTTPS、负载均衡配置,新手无需担心衔接问题,直接叠加配置即可。还是用生活例子讲明白,不用记复杂的技术原理,和前面的“奶茶店”例子衔接,更容易理解:你的奶茶店(服务器)正常营业,每天能接待1000个顾客(正常请求),秩序井然。但突然来了一群人(恶意请求/爬虫),每分钟疯狂涌入100人,远超奶茶店的接待能力,导致正常顾客无法进店、店内混乱(服务器卡顿、崩溃)。为了解决这个问题,你在店门口安排了保安(Nginx限流),规定“每分钟最多接待20人”,超过这个数量的人,暂时不让进店(拦截请求)——这就是 Nginx限流 。用技术语言总结: Nginx限流是通过限制单位时间内的请求数量,拦截高频恶意请求、爬虫和攻击请求,避免服务器负载过高、卡顿崩溃,保护服务器安全,同时保证正常用户的访问体验 。
- 防恶意攻击:拦截高频请求、DDoS攻击,避免服务器被压垮,保证服务可用;
- 防爬虫:阻止爬虫疯狂抓取网站数据,节省服务器带宽和资源;
- 保障正常用户:避免恶意请求占用过多资源,确保正常用户能流畅访问。
关键提醒:限流不是“禁止所有高频请求”,而是“限制请求频率”,正常用户的访问频率(比如每分钟访问10次)不会被拦截,只有超过设定阈值的高频请求(比如每分钟访问100次)才会被拦截。Nginx提供了3种核心限流策略,基于ngxhttplimitreqmodule和ngxhttplimitconnmodule模块实现(默认已安装),不同场景选择不同策略,新手重点掌握前2种,就能应对90%的安全场景。所有策略的配置,都需要在nginx.conf的 http块 中定义(和server块、upstream块同级),再在server块或location块中引用,直接复制配置即可使用。策略1:固定窗口限流(limit_req,最常用)核心逻辑:将时间划分为固定的窗口(比如1秒),规定每个窗口内最多允许的请求数量,超过数量的请求直接拦截,适用于“限制单位时间内请求总数”的场景(比如限制每秒最多100个请求)。核心指令: limitreqzone(定义限流规则)、 limit_req(引用限流规则)。http { limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; server { listen 443 ssl http2; server_name www.xxx.com; limit_req zone=req_limit burst=5 nodelay; }}
示例:每秒最多允许10个请求,超过10个后,最多再接收5个突发请求,超过15个的请求,直接被拦截(返回503错误)。新手推荐:固定窗口限流配置简单、效果直观,适合大多数场景(比如接口限流、网站整体限流),优先选择这种策略。策略2:滑动窗口限流(limit_req+滑动窗口,解决固定窗口缺陷)核心逻辑:在固定窗口的基础上,将窗口划分为更小的时间片(比如1秒划分为10个100ms的时间片),实时计算滑动窗口内的请求数量,避免“固定窗口临界值”的缺陷(比如1秒窗口的最后100ms和下一秒的前100ms,连续发送20个请求,不会被固定窗口拦截)。http { limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; server { listen 443 ssl http2; server_name www.xxx.com; limit_req zone=req_limit burst=5 nodelay window=100ms; }}
适用场景:对限流精度要求较高的场景(比如支付接口、核心业务接口),避免固定窗口的临界值缺陷。策略3:连接数限流(limit_conn,辅助限流)核心逻辑:限制同一客户端(IP)同时建立的连接数量,适用于“限制单个IP的并发连接”的场景(比如防止单个IP同时建立大量连接,占用服务器资源),常和固定窗口限流配合使用。核心指令: limitconnzone(定义连接数限流规则)、 limit_conn(引用规则)。http { limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn_limit:10m; server { listen 443 ssl http2; server_name www.xxx.com; limit_req zone=req_limit burst=5 nodelay; limit_conn conn_limit 5; }}
示例:同一IP同时最多建立5个连接,超过5个连接的请求,会被拦截(返回503错误),避免单个IP占用过多连接资源。结合前面的限流策略,我们给出企业级完整配置,包含“固定窗口限流+连接数限流+防爬虫+防恶意IP+防敏感路径”,直接复制到nginx.conf中,修改域名、限流阈值即可上线,完全兼容HTTPS、负载均衡配置。user nginx;worker_processes auto;error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events { worker_connections 10240; use epoll;}http { include mime.types; default_type application/octet-stream; server_tokens off; limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=conn_limit:10m; limit_req_status 503; limit_conn_status 503; error_page 503 /503.html; location = /503.html { root /data/www; internal; } if ($http_user_agent ~* "Baiduspider|Googlebot|SogouSpider|Yahoo|bingbot|AhrefsBot") { return 403 "Forbidden: Crawler is not allowed"; } location ~* /(admin|api)/ { limit_req zone=req_limit burst=3 nodelay; if ($http_user_agent ~* "Baiduspider|Googlebot") { return 403; } } deny 192.168.1.100; deny 10.0.0.0/24; allow all; upstream backend { server 127.0.0.1:8080 weight=5 max_fails=3 fail_timeout=10s; server 127.0.0.1:8081 weight=3 max_fails=3 fail_timeout=10s; server 192.168.1.101:8080 weight=2 max_fails=3 fail_timeout=10s; } server { listen 443 ssl http2; server_name www.xxx.com; ssl_certificate /etc/nginx/ssl/xxx.pem; ssl_certificate_key /etc/nginx/ssl/xxx.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; limit_req zone=req_limit burst=5 nodelay; limit_conn conn_limit 5; location ~* \.(html|css|js|png|jpg)$ { root /data/www; expires 365d; } location /api { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location = /503.html { root /data/www; internal; } } server { listen 80; server_name www.xxx.com; return 301 https://$host$request_uri; }}
- server_name:修改为你的域名(和HTTPS证书域名一致);
- sslcertificate、sslcertificate_key:修改为你的证书路径;
- 限流阈值:rate=10r/s(每秒10个请求)、limitconn connlimit 5(5个连接),可根据服务器性能修改(性能好可提高,性能差可降低);
- 恶意IP:deny后面添加需要拦截的恶意IP/IP段,可根据实际情况补充;
- 503页面:在/data/www目录下创建503.html(简单写“服务繁忙,请稍后再试”即可),提升用户体验。
如果输出“nginx: configuration file /etc/nginx/nginx.conf test is successful”,说明配置正确,重启成功;如果报错,对照报错提示,检查限流规则、证书路径是否正确。配置重启后,我们通过3种方式验证,确保限流、防爬虫、防恶意IP能正常生效,不影响正常用户访问。在Linux服务器上,执行以下命令,模拟高频请求(每秒发送20个请求):ab -n 100 -c 20 https://www.xxx.com/api/test
查看结果:会有部分请求返回503错误(被限流拦截),正常请求返回200 OK,说明限流生效——高频请求被拦截,正常请求可正常访问。执行以下命令,模拟爬虫请求(设置User-Agent为百度爬虫):curl -H "User-Agent: Baiduspider" https://www.xxx.com
查看结果:返回403错误(“Forbidden: Crawler is not allowed”),说明爬虫被成功拦截。
- 在配置中添加一个测试IP(比如192.168.1.100)到deny列表;
- 从该IP的服务器上,执行curl命令访问你的网站:
查看结果:返回403错误,说明恶意IP被成功拦截;其他IP访问正常,说明没有误拦。实战总结:到这里,限流防攻击配置已全部完成,能有效拦截高频恶意请求、爬虫和恶意IP,保护服务器安全,同时不影响正常用户访问,满足生产环境安全防护要求。前面的配置已经能满足基本安全需求,下面补充2个企业级精细化配置,进一步提升防护效果,适合核心业务网站使用,直接复制添加到对应位置即可。场景:核心接口(比如支付接口)需要更严格的限流,普通接口可放宽限流阈值,配置如下:limit_req_zone $binary_remote_addr zone=pay_limit:10m rate=5r/s;
location /api/pay { proxy_pass http://backend; limit_req zone=pay_limit burst=2 nodelay; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;}
场景:企业内部IP、测试IP,需要不受限流限制,配置如下:http { geo $white_ip { default 0; 192.168.1.0/24 1; 127.0.0.1 1; } limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; server { limit_req zone=req_limit burst=5 nodelay if=$white_ip; }}
新手配置限流防攻击,最容易遇到以下报错,对照报错信息,复制对应的解决方法,一键搞定,不用浪费时间查百度。报错1:Nginx重启报错:nginx: [emerg] unknown directive "limitreqzone"原因:Nginx未安装ngxhttplimitreqmodule模块(默认已安装,部分精简版Nginx缺失);解决:检查模块是否安装: nginx -V 2>&1 | grep limit_req;如果没有输出,重新安装Nginx。原因:限流阈值设置过低(比如rate=2r/s),正常用户的访问频率超过阈值;解决:提高限流阈值(比如修改rate=10r/s、rate=20r/s),同时调整burst参数(比如burst=10),允许更多突发请求。原因:User-Agent匹配规则过宽,误将正常浏览器的User-Agent识别为爬虫;解决:修改爬虫User-Agent匹配规则,删除正常浏览器的标识,只保留常见爬虫标识(参考配置中的爬虫列表)。原因:限流阈值设置过低,或burst参数设置过小,导致正常请求被限流;解决:提高rate和burst参数,或检查是否有恶意IP高频请求,添加到deny列表。报错5:Nginx重启报错:nginx: [emerg] invalid value "window=100ms" in "limit_req" directive原因:Nginx版本过低,不支持window参数(滑动窗口),Nginx 1.17.10及以上版本才支持;解决:升级Nginx版本,或放弃滑动窗口,使用固定窗口限流。原因:deny配置错误,或忘记添加allow all;(允许所有IP访问);解决:检查配置,确保deny后面只添加恶意IP/IP段,并且最后添加allow all;(放在deny后面)。核心联动:限流防攻击 + HTTPS + 负载均衡结合前面的内容,给大家梳理企业真实安全部署的完整流程(限流防攻击+HTTPS加密+负载均衡+反向代理+静态资源分离),新手理解这个流程,就能直接应对生产环境的安全部署:1.用户发起请求,访问http://www.xxx.com,自动跳转到https://www.xxx.com(HTTPS配置);2.Nginx先验证请求IP和User-Agent:
- 动态接口请求:通过负载均衡策略,转发到多台后端服务中的一台;
6.Nginx将响应结果通过HTTPS返回给用户;7.全程实现“加密传输+限流防攻击+负载均衡”,既保证安全,又保证服务高可用、正常用户流畅访问。这个流程,就是企业生产环境中最标准、最安全的Nginx部署方案,涵盖了我们前面所学的所有核心知识点,新手掌握后,就能独立完成生产环境的安全部署。今天这篇,我们掌握了Nginx限流防攻击的核心用法,重点总结:
- 限流核心:限制请求频率和连接数,拦截恶意请求、爬虫和攻击,保护服务器安全,保障正常用户访问;
- 3种策略:重点掌握固定窗口限流(常用)、滑动窗口限流(高精度),连接数限流(辅助),按需选型;
- 完整配置:限流+防爬虫+防恶意IP+HTTPS+负载均衡,直接复制就能上线,兼容前面所有配置;
- 实战验证:3种方式(高频请求、模拟爬虫、恶意IP),确保配置生效;
到这里,你已经掌握了Nginx的核心安全防护能力——静态网站、反向代理、负载均衡、HTTPS加密、限流防攻击,能独立完成企业级前后端分离项目的完整、安全部署,应对高并发、高可用、高安全的生产环境场景。
阅读原文:原文链接
该文章在 2026/4/2 12:25:28 编辑过