fail2ban_thumbnail.jpg

简介

Fail2Ban 是入侵检测软件框架,保护计算机免受暴力破解(brute-force attack)。以 Python 语言编写,能运行于具有包(packet)控制或防火墙的 POSIX 系统,如 iptables 或 TCP Wrapper.

Fail2Ban可以通过描日志文件并用正则匹配分析,然后通过更新防火墙规则来禁止某些有恶意迹象的 IP(密码失败过多,寻求漏洞利用等)来提高服务器安全性。

前置要求

因为我们需要用Fail2Ban屏蔽恶意访问网站的IP,我们需要安装Nginx,让网站能正常上线。(如果仅用Fail2Ban保护SSH可以忽略)

  • Nginx

安装

演示环境为Ubuntu 20.04.4 LTS,使用root用户。Fail2Ban在大多Linux发行版软件包仓库中都有,因此无需源码编译。

sudo apt-get update && upgrade
sudo apt-get install fail2ban

上述两条命令会更新Ubuntu所有的包,并安装Fail2Ban。Fail2Ban默认只开启了SSHBan保护SSH恶意攻破,要保护网站不被恶意访问,我们需要手动设置自定义规则。

// 触发脚本
action.d/

// 封禁脚本
filter.d/

// 默认配置文件
jail.conf

基本设置

首先,我们需要调整Fail2Ban使用的配置文件,设置当发现违规条目时要采取哪些措施。/etc/fail2ban/jail.conf 是存储该配置的核心文件。

为了避免在未来更新后,我们的自定义设置被覆盖,我们需要首先复制jail.confjail.local,当程序中出现.local文件时会覆盖(Override)jail.conf文件。

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

打开该文件

sudo nano /etc/fail2ban/jail.local

更改默认配置

我们首先应该浏览一下默认设置,这些设置位于[DEFAULT]下方。默认的设置可以被每条独立的规则所覆盖(重载)。

首先,我们可能需要关注一下ignoreip,这些IP会被fail2ban所忽略,建议大家将自己的IP地址添加到后面,防止fail2ban把自己的IP封禁。

[DEFAULT]

. . .
ignoreip = 127.0.0.1/8 (your_home_IP)

其次,我们可能需要修改一下默认封禁时间,该设置位于bantime。fail2ban默认会将该值设置为600秒(10分钟)。

[DEFAULT]

. . .
bantime = 3600

我们同时需要调整一下findtimemaxretry这两项参数。findtime限制了时间范围,maxretry限制了在时间范围内客户端可以重试的最大次数。如果超过阈值,该IP将会根据规则被屏蔽。如下,客户端如果在3600秒内触发相关规则超过6次,将被屏蔽。

[DEFAULT]

. . .
findtime = 3600   # These lines combine to ban clients that fail
maxretry = 6      # to authenticate 6 times within a half hour.

添加自定义规则

进入filter.d目录:

cd /etc/fail2ban/filter.d

Nginx 404

以下规则可以匹配所有触发404,444,403,400,422,401的客户端

新建一个名为nginx-4XX.conf的配置文件:

sudo nano nginx-4XX.conf

在文件内写入如下参数:

[Definition]
failregex = ^<HOST>.*"(GET|POST).*" (404|444|403|400|422|401) .*S
ignoreregex =

Wordpress wp-login

以下规则可以匹配所有访问(wp-includes|wordpress|wp-login)且触发了404的客户端,可预防后台被字典暴力攻破。

新建一个名为noWordpress.conf的配置文件:

sudo nano noWordpress.conf

在文件内写入如下参数:

[Definition]
failregex = ^<HOST> -.*(GET|POST).*(wp-includes|wordpress|wp-login).*(404|444|403|400|422|401)
ignoreregex =

验证自定义规则

我们写完自定义规则后,通常需要验证规则是否有效。防止出现误封、漏封的情况。

fail2ban验证正则的语法如下:

 fail2ban-regex [OPTIONS] <LOG> <REGEX> [IGNOREREGEX]

LOG为需要匹配的日志文件路径,REGEX为正则表达式所在的文件路径(通常位于filter.d文件夹内)。

以下为常用的OPTIONS

// Do not print any missed lines
--print-no-missed

// Do not print any ignored lines
--print-no-ignored

// Print all matched lines
--print-all-matched

// Print all missed lines, no matter how many
--print-all-missed

// Print all ignored lines, no matter how many
--print-all-ignored

启用自定义规则

要启用自定义规则,需要修改jail.local文件。

sudo nano /etc/fail2ban/jail.local

以自定义规则nginx-4XX为例,在文件的尾部添加如下代码块:

[nginx-4XX]
enabled = true                        #是否启用?
port = http,https                     #启用端口
filter = nginx-4XX                    #规则名称(需要与自定义规则里的名称一致,不需要.conf后缀)
action = iptables-allports            #如果被触发,执行怎样的脚本?
logpath = /var/log/nginx/access.log   #fail2ban检测的日志文件路径
bantime = 120m
findtime = 10
maxretry = 5

重启fail2ban服务

sudo service fail2ban restart

检查fail2ban服务状态

sudo fail2ban-client status

会返回已启用规则(jail)的名称

Output
Status
|- Number of jail:      6
`- Jail list:           nginx-4XX, ssh

查看单个规则jail的状态:

sudo fail2ban-client status nginx-4XX
Output
Status for the jail: nginx-4XX
|- filter
|  |- File list:        /var/log/nginx/access.log 
|  |- Currently failed: 0
|  `- Total failed:     12
`- action
   |- Currently banned: 1
   |  `- IP list:       111.111.111.111
   `- Total banned:     1

手动解封

sudo fail2ban-client set nginx-4XX unbanip 111.111.111.111

参考

https://technicalramblings.com/blog/cloudflare-fail2ban-integration-with-automated-set_real_ip_from-in-nginx/#updating-jaillocal

https://www.digitalocean.com/community/tutorials/how-to-protect-an-nginx-server-with-fail2ban-on-ubuntu-14-04

https://www.youtube.com/watch?v=7o6533g0qVs