Nginx fail2ban:个人站点 DDOS 攻击生存指南

栏目: 服务器 · Nginx · 发布时间: 6年前

内容简介:Nginx fail2ban:个人站点 DDOS 攻击生存指南

为了防范潜在的 DDOS 攻击,避免经济损失,我在近期升级了本博客的服务器。更新后,服务器实装了 Nginx 自建的 HTTP 限流模块,配合 fail2ban 封杀恶意 IP,可以有效抵御大量并发请求对服务器的干扰。

Nginx 部分

在 Nginx 上配置 HTTP 限流模块,分为两个步骤:

  1. 创建一个管理区域(以下称 zone)
  2. 将 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 端口的连接。 findtimemaxretry 都使用了默认值,因此那两行也可以不写。

一切就绪后,运行 sudo service fail2ban restart 重载 fail2ban。日志 /var/log/fail2ban.log 中记录了攻击者的 IP 地址。可惜它们通常是肉鸡,不值得打回去。总而言之,咱们服务器管理员要牢记的一点是:网络世界并不太平。


以上所述就是小编给大家介绍的《Nginx fail2ban:个人站点 DDOS 攻击生存指南》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ActionScript 3.0 Cookbook

ActionScript 3.0 Cookbook

Joey Lott、Darron Schall、Keith Peters / Adobe Dev Library / 2006-10-11 / GBP 28.50

Well before Ajax and Microsoft's Windows Presentation Foundation hit the scene, Macromedia offered the first method for building web pages with the responsiveness and functionality of desktop programs......一起来看看 《ActionScript 3.0 Cookbook》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具