在 HAProxy 中阻止 IP

Gri*_*... 4 brute-force-attacks haproxy rate-limiting

一个客户的网站目前受到攻击,我被要求修复它。

大量 IP(轻松超过 5,000 个)不断攻击/login,大概是试图强行进入。

我更改了站点,因此页面返回 500 错误,但他们并没有放弃。显然,这对现在无法登录的真实用户不利。

负载平衡是通过HAProxy完成的,我对此知之甚少(尽管我比几个小时前知道的要多得多)。我已经尝试了很多我在网上找到的明智的方法,但似乎都没有帮助,可能是因为有如此大的 IP 块在执行攻击。

那么问题来了: 如果一个 IP在Y秒内命中/login超过X次,我该如何拒绝?

而且,子点 - 我怎样才能看到拒绝日志,所以我知道它确实在工作?

这是haproxy.log的示例

Jun  3 14:24:50 hap-server haproxy[11831]: 46.161.62.79:15290 [03/Jun/2017:14:24:49.505] www-https-test~ www-backend/www-03 751/0/202/38/991 500 220 - - ---- 428/428/120/38/0 0/0 "GET /login HTTP/1.1"
Jun  3 14:24:50 hap-server haproxy[11831]: 46.161.63.132:47804 [03/Jun/2017:14:24:49.505] www-https-test~ www-backend/www-04 751/0/202/38/991 500 220 - - ---- 428/428/119/42/0 0/0 "GET /login HTTP/1.1"
Jun  3 14:24:50 hap-server haproxy[11831]: 46.161.62.43:53176 [03/Jun/2017:14:24:49.505] www-https-test~ www-backend/www-02 751/0/202/38/991 500 220 - - ---- 428/428/118/38/0 0/0 "GET /login HTTP/1.1"
Run Code Online (Sandbox Code Playgroud)

Gri*_*... 13

感谢 EEAA 的评论,我能够使用 fail2ban 解决这个问题。

然而,关于如何将fail2ban 与HAProxy 一起使用的文档很少——事实上,这个页面已经接近谷歌搜索“haproxy fail2ban”的顶部,所以我将详细说明我是如何做到的。

首先,安装fail2ban。如果你做不到那一点,你可能不应该在没有更多帮助的情况下继续。

fail2ban 的工作原理是扫描您的访问日志,寻找您设置的模式。如果它在 Y 秒内发现该模式 X 次,它将自动禁止该 IP Z 秒。

您的 HAProxy 日志应位于/var/log/haproxy.log. 如果你的负载很重,它可能太大而无法用 Vim 或 Nano 打开,所以只需使用 tail 查看最后几行:tail -n50 /var/log/haproxy.log

我的日志中“坏”条目的示例如下所示:

Jun  3 16:48:03 hap-server haproxy[21751]: 178.159.100.29:48806 [03/Jun/2017:16:48:03.735] www-https-test~ www-backend/www-04 172/0/2/3/177 200 339 - - ---- 36/36/0/0/0 0/0 "GET /login HTTP/1.1"
Run Code Online (Sandbox Code Playgroud)

我们希望fail2ban 掌握的重要信息是攻击者的IP 和他们点击的页面。

要告诉fail2ban 如何做到这一点,首先我们要创建一个过滤器。在文件夹中创建一个文件/etc/fail2ban/filter.d。我叫我的,applogin.conf但你可以随心所欲地称呼它,只要它以.conf.

内容如下:

[Definition]

failregex = ^.*haproxy\[[0-9]+\]: <HOST>:.* "(GET |POST )/login HTTP/1.1"$
ignoreregex =
Run Code Online (Sandbox Code Playgroud)

<HOST>是日志中出现 IP 地址的行中的点。如果您想使用与我相同的正则表达式,请替换/login为攻击者在您的服务器上针对的地址。

现在你必须告诉fail2ban你希望它寻找那个过滤器。复制一份/etc/fail2ban/jail.conf(以防万一你搞砸了,需要重新开始),然后打开jail.conf并在底部添加以下几行。

[app-login]
enabled  = true
bantime  = 1200
findtime = 120
maxretry = 6
filter   = applogin
logpath  = /var/log/haproxy.log
port     = http,https
Run Code Online (Sandbox Code Playgroud)

方括号中的部分只是一个名称 - 使用您喜欢的。 bantime是用户被禁止的秒数。maxretry是用户在findtime几秒钟内可以点击页面的次数。因此,在我的示例中,如果有人试图在 2 分钟内访问 www.mydomain.com/login 超过 6 次(或者可能正好是 6 次,我不确定),那么他们将被禁止 20 分钟。 filter是您在其中创建的文件的名称/etc/fail2ban/filter.d(但没有.conf)。 logpath是您希望它在其中搜索的日志文件的路径。

保存该文件,然后重新启动fail2ban:service fail2ban restart 跟踪fail2ban 日志文件:tail -f /var/log/fail2ban.log希望一两分钟后,您将开始看到类似的内容

2017-06-03 17:04:32,040 fail2ban.actions: WARNING [app-login] Ban 146.185.200.122
Run Code Online (Sandbox Code Playgroud)

就是这样!你可以远离坏人(那些试图进入那个特定页面的人,无论如何)。

注意 - 您可能还会在 fail2ban 日志中看到一些 SSH 禁令。它在安装时会自动为 SSH 创建一些规则,所以不要惊慌。


小智 8

我很高兴您似乎已经解决了fail2ban的直接问题,并且在 iptables 级别进行阻止确实有意义,但是您可以在 HAProxy 配置中执行完全相同的操作:您可以将 acl 与 src_http_req_rate() 或甚至 src_http_err_rate(Abuse):我在一些用于缓解 DDOS 的 haproxy 配置示例中使用了它们。

长期来看:听起来您可能想为该页面实现双重登录,如果用户接受它,那么您可以在登录页面中添加一个额外的 htaccess 密码,这样他们就需要单独登录(相当困难)用脚本破解)。或者您可以使用 mod_security 来做同样的事情或某种蜜糖陷阱