简介
Nginx作为一款轻量高性能开源的Web服务器,深受大众欢迎并在服务器中得到了广泛应用。但是Nginx默认是不设防的,即不会自动防御DDOS攻击和CC攻击,因此攻击者可以轻易地发送大量的请求从而耗尽你的服务器资源、恶意盗刷你的服务器流量或者让你的后端服务器崩溃,因此配置Nginx基础防御是很有必要的,本篇文章就记录如何为你的Nginx配置一些基础的防御规则从而保护你的Web服务器。
相关文章链接:
Nginx配置笔记
https://blog.pengcheng.team/index.php/archives/185/
利用Fail2Ban保护你的服务器(Fail2Ban使用教程)
https://blog.pengcheng.team/index.php/archives/187/
Nginx upstream与proxy_pass反向代理配置详解
https://blog.pengcheng.team/index.php/archives/186/
Nginx限制单个IP的TCP连接数与TCP连接速率
示例配置代码:
limit_conn_zone $binary_remote_addr zone=ip_addr:10m;
上面的一行代码的意思是以二进制格式标记客户端的 IP 地址,共享内存区域的名称是 ip_addr
,区域大小是 10 兆字节。
然后在要应用该限制的Server块部分写入下列代码:
limit_conn ip_addr [单IP最大可接受TCP连接数];
limit_conn ip_addr 1;
proxy_download_rate 1000k;
proxy_upload_rate 500k;
建议根据实际情况来设置限制,写后记得好好测试一下再将配置上线,否则可能导致正常用户访问出现异常。
官方文档
https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-tcp/
Nginx限制单个IP的请求速率
示例配置代码:
limit_req_zone $binary_remote_addr zone=peripreq:10m rate=3r/s;
上面的一行代码的意思是:
limit_req_zone
:定义请求限制区域
$binary_remote_addr
:以二进制的方式标记客户端IP
zone=peripreq:10m
:本共享内存区域的名称是peripreq,区域大小是 10 兆字节,它的大小与队列的最大长度有关。
rate=3r/s
:定义单个IP最大可接受的请求速率为3次每秒(可自行更改
这时我们就有一个 限制区域
( limit_req_zone
)了,只需在需要应用该 限制区域
的 Server块
中引用这个区域名称就行。
引用方法:在要应用该限制的Server块部分写入如下代码
limit_req zone=peripreq burst=30 nodelay;
意思是:
limit_req
:请求数限制
zone=peripreq
:区域规则名称为:peripreq
burst=30
:最大可接受突发请求数为30
nodelay
:要求立即返回结果
重点说明一下 burst
和 nodelay
关于 burst
的突发请求数,如果一个IP超过了限制区域原本的限制(比如上面设置的是3r/s),那么就会开始使用突发请求数的配额,如果请求数超过了基础限制速率+突发请求数,则会将该请求放入队列或则直接返回503。
突发请求数会以基础限制速率的速度恢复。
关于 nodelay
参数,这个参数决定了是否将超出的请求放到队列中处理,队列满了才会返回503。加了这个参数的话就是要求立即返回结果,不会将超出范围的请求放入队列中等待,而是立即返回503。
温馨提示:请求数!=用户看的网页数,正常打开一个网页可能会发送几十个请求,请使用网页调试工具查看打开一次自己的网站页面会发送多少个请求,请根据自己网站的实际情况调整并测试。
示例参数大小:
以菜鸟教程和知乎为例,打开一次它们的首页共发送了大约一百多次请求,那么 rate=3r/s
, burst=200
是比较河里的。
疑问:3r/s远远小于200,这难道不是很容易就超出限制了?
那是因为很多资源第一次请求后就缓存下来了,不会再向服务器索取了,因此只有第一次打开会发送这么多的请求数,用适当的突发设置请求应付一下就OK了。


Nginx限制后端服务器的最大请求次数
上面的那些手段对于 DDOS
和 CC
攻击可能有点用,但是如果遇到 DDOS
就用处不是很大,对于这种分布式的攻击,我们应该首先考虑一下对后端的保护,防止服务器后端因同时收到太多请求而直接崩溃导致数据损坏等情况的发生。
示例配置代码:
limit_req_zone $server_name zone=perserverreq:10m rate=20r/s;
上面的一行代码的意思是:
limit_req_zone
:定义请求限制区域
$server_name
:以网站名为单位构建限制区域
zone=peripreq:10m
:本共享内存区域的名称是 perserverreq
,区域大小是 10 兆字节,它的大小与队列的最大长度有关。
rate=20r/s
:定义单个站点最大可接受的请求速率为20次每秒(可自行更改
然后同样在 Server
部分引用该限制区域,再设置个突发请求限制以灵活应对突发请求
limit_req zone=perserverreq burst=100;
这里的20和100只是参考,这两个参数需要根据自己的服务器后端的最大并发处理能力来决定,
配置自动拉黑触发过载保护的IP
以上的那些手段只是配置了一下Nginx的并发限制,达到阈值后Nginx只是会给相应的IP返回错误,并不会拿那些恶意IP怎么样,光做到这些还是不太够的,至少要能把这些恶意IP拉黑掉。
为了实现拉黑功能可以借助一些WAF模块如: ModSecurity
、 http_guard
、 ngx_lua_waf
关于它们的使用方法大家可以上网上搜索一下,这里笔者来介绍一下如何使用 Fail2Ban
来实现IP自动拉黑。
首先你需要在相应Server块定义网站错误日志,例如在server块中加上
error_log /www/wwwlogs/error.log;
Fail2Ban
需要读取这个日志文件以判断封禁IP
关于Fail2Ban的配置和相关的用法详见文章:
利用Fail2Ban保护你的服务器(Fail2Ban使用教程)
https://blog.pengcheng.team/index.php/archives/187/
这里就再写一下如何清空日志吧,我想到的方法很简单:使用echo命令用一个空格覆盖你的日志文件就OK了。例如:
echo " " > /root/nginx/logs/error.log
想要定时清理的话,借助crontab可以轻松实现,它的用法详见文章:
Linux利用Crontab执行定时任务
https://blog.pengcheng.team/index.php/archives/190/
本文链接:https://blog.pengcheng.team/index.php/archives/189/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂