内容简介:Nginx fail2ban:个人站点 DDOS 攻击生存指南
为了防范潜在的 DDOS 攻击,避免经济损失,我在近期升级了本博客的服务器。更新后,服务器实装了 Nginx 自建的 HTTP 限流模块,配合 fail2ban 封杀恶意 IP,可以有效抵御大量并发请求对服务器的干扰。
Nginx 部分
在 Nginx 上配置 HTTP 限流模块,分为两个步骤:
- 创建一个管理区域(以下称 zone)
- 将 zone 应用于指定的文件路径(location)
我曾在文章 本博客现已启用全站 HTTPS 加密通讯
中贴出了配置文件 nginx.conf
的代码片段。简明起见,那篇博客省略了配置文件的根节点。实际上,整个文件的结构是这样子的:
# 进程设定 ... http { # 逻辑服务器设定 server { listen 80; ... # 文件路径映射 location / { root /var/www/html; } ... } server { listen 443 ssl; ... } # 其它设定 -- TCP SSL 日志 压缩等 ... }
Nginx 的每个 zone 记录了一套管理规则。这个规则会在开启了该 zone 的 location 上生效。也就是说,应在“其它设定”下面声明 zone,并在“文件路径映射”那里引用它。
来看两个 zone 的声明的例子。
limit_req_zone $binary_remote_addr zone=perip:10m rate=30r/m;
第一个例子中, limit_req_zone
表明这条语句声明一个限流 zone。 $binary_remote_addr
是 Nginx 内置的变量,用来表示客户端的 IP 地址。它决定了这个 zone 会以客户端 IP 作为控制条件。 perip
是 zone 的名字。冒号后的 10m
表示这个 zone 最大可占用的内存空间。zone 要存储包括 IP 地址在内的客户端状态信息。根据 官方文档
,状态信息在 32 位机上占用 64 字节,而在 64 位机上占用 128 字节。对我的 64 位服务器而言,10 MB 的内存理论上支持 8 万个并发连接,是绰绰有余的。最后 30r/m
规定,每个 IP 地址的平均请求速度不得大于每分钟 30 次。因为不支持小数的缘故,这里不能写作 0.5r/s
。
limit_req_zone $server_name zone=perserver:10m rate=100r/s;
第二个例子使用了内置变量 $server_name
,使得这个 zone 作用于 Nginx 自己。它的意思是,当某个逻辑服务器的平均请求速度大于每秒 100 次时,将不再受理新的请求。
在 location 内引用一个 zone,请参考下面的例子。
limit_req zone=perip burst=5 nodelay;
这条指令为当前的 location 启用 perip
zone。尽管 perip
限制了平均请求速度,Nginx 依旧允许客户端并发创建 5 个连接,以适应现代浏览器的需要。过载后,开启了 nodelay
的 Nginx 将立即向客户端返回错误码。如果没有 nodelay
选项,Nginx 会故意延迟响应客户端的请求,以便将其响应请求的平均速度拉低到限定值以下。因为在这种情况下,服务器仍然需要消耗内存记录尚未响应的请求,所以对付 DDOS 攻击一定要开启 nodelay
选项。
在声明 zone 的位置,同时可以自定义返回的状态码。默认返回的状态码是 503 服务暂时不可用。我建议通过 limit_req_status 444;
将它替换成 444 无回应断开连接。444 是一个由 Nginx 引入的非标准 HTTP 状态码,它从字面上将拒绝服务的责任从服务器端 (5xx) 转移到客户端 (4xx),更加真实地反映了客观情况。
如果 Nginx 服务器流量超限,我们可以在 error 日志中找到这样的记录:
... limiting requests, excess:..., client:..., server:..., request:..., host:...
Nginx 的限流仅仅可以停止响应服务,但客户端依然能不断地发送 TCP 请求建立新的连接。这时需要 fail2ban 上场彻底阻断恶意客户端的魔爪。fail2ban 的工作,就是从监控日志开始的。
fail2ban 部分
fail2ban 可在各 Linux 发行版的包管理器中安装。它的过滤规则位于 /etc/fail2ban/filter.d/
路径下。新安装的 fail2ban 已经设置好了多项规则,我们只要照着模板完成 nginx-http-limit-req.conf
文件即可(文件名任取)。
# nginx-http-limit-req.conf [Definition] failregex = limiting requests, excess:.*client: <HOST> ignoreregex =
failregex
描述了 fail2ban 期望匹配的特征。 .*
用于匹配中间的任意多个字符。重点是 client: <HOST>
,fail2ban 依此来抓取客户端的 IP 地址。
之后,需要注册并启用这条规则。因为原始的配置文件 /etc/fail2ban/jail.conf
会随着版本更新而被覆盖,我们要创建一个副本 /etc/fail2ban/jail.local
,并在其中填写配置。在文件的最后插入下面这段内容:
[nginx-http-limit-req] enabled = true port = http,https logpath = %(nginx_error_log)s findtime = 600 maxretry = 5 bantime = 7200
注意,标签要与过滤规则的文件名相同。在默认状态,所有规则都是禁用的,我们需要单独启用想要加载的规则。fail2ban 运行后,会自动监测 %(nginx_error_log)s
文件,如果在 600 秒的时间内( findtime
)连续 5 次( maxretry
)发现客户端的请求速度超过限额,则在将来的 7200 秒内( bantime
)禁止该 IP 到服务器 http 和 https 端口的连接。 findtime
和 maxretry
都使用了默认值,因此那两行也可以不写。
一切就绪后,运行 sudo service fail2ban restart
重载 fail2ban。日志 /var/log/fail2ban.log
中记录了攻击者的 IP 地址。可惜它们通常是肉鸡,不值得打回去。总而言之,咱们服务器管理员要牢记的一点是:网络世界并不太平。
以上所述就是小编给大家介绍的《Nginx fail2ban:个人站点 DDOS 攻击生存指南》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
第一本Docker书 修订版
詹姆斯·特恩布尔 (James Turnbull) / 李兆海、刘斌、巨震 / 人民邮电出版社 / 2016-4-1 / CNY 59.00
Docker是一个开源的应用容器引擎,开发者可以利用Docker打包自己的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。 本书由Docker公司前服务与支持副总裁James Turnbull编写,是Docker开发指南。本书专注于Docker 1.9及以上版本,指导读者完成Docker的安装、部署、管理和扩展,带领读者经历从测试到生产的整个开发生......一起来看看 《第一本Docker书 修订版》 这本书的介绍吧!