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 攻击生存指南》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

第一本Docker书 修订版

第一本Docker书 修订版

詹姆斯·特恩布尔 (James Turnbull) / 李兆海、刘斌、巨震 / 人民邮电出版社 / 2016-4-1 / CNY 59.00

Docker是一个开源的应用容器引擎,开发者可以利用Docker打包自己的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。 本书由Docker公司前服务与支持副总裁James Turnbull编写,是Docker开发指南。本书专注于Docker 1.9及以上版本,指导读者完成Docker的安装、部署、管理和扩展,带领读者经历从测试到生产的整个开发生......一起来看看 《第一本Docker书 修订版》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

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

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具