前言
fail2ban是一款安全保护工具,触发限制后会创建防火墙规则封锁IP,诸如对ssh暴力破解、ftp/http密码穷举等场景提供强有力的保护,主要作用概要为以下几点:
- 避免被穷举攻击(brute force)
- 查看验证失败的日志
- 自动创建防火墙规则封锁IP
- 支持多种服务
- 高度可定制
一、安装
1.软件源安装
发行版 | 安装命令 |
---|---|
Arch | pacman -Sy fail2ban/yay -Sy fail2ban |
CentOS/Redhat | yum install -y fail2ban |
Debian | apt-get install fail2ban |
2.源码安装
git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban
sudo python setup.py install
这会将fail2ban安装到python库目录中。可执行脚本放在 /usr/bin中,配置目录在/etc/fail2ban。
二、配置即参数详解
1.配置备份
以Debian为例,其他发行版大体相同,个别参数的命名可能有所区别。
配置文件路径默在/etc/fail2ban,出于安全起见默认配置最好保留,方便出问题时方便回滚和对照原始配置。
cd /etc/fail2ban
cp jail.conf jail.local
cp fail2ban.conf fail2ban.local
之后我们只需要配置jail.local
和fail2ban.local
这两个文件也是同样生效的。
2.jali.local配置详解
[DEFAULT]
#此参数为加白的网段、IP,可以是域名、网段或单个IP,空格隔开。
ignoreip = 127.0.0.1/8 ::1
#设置被封锁的时间间隔,如下表示10分钟,可以是秒(s)、分钟(m)、小时(h)、天(d),不带单位则默认为s,-1表示永久封锁。
bantime = 10m
#检测的间隔时间,在间隔时间内,当>=maxtretry设置的失败次数,则触发限制,禁止访问。
findtime = 10m
#findtime时间内的最大失败次数
maxretry = 5
三、SSH安全防护
1.启用sshd模块
回到jali.local配置文件,找到[sshd]
模块,并添加一行启用此模块:
[sshd]
enabled = true
port = 22 #ssh端口
logpath = /var/log/auth.log #日志路径
backend = %(sshd_backend)s #后台管理程序,默认由systemd接管,无需修改
enabled = true
表示启用此模块。同时上面提到的[DEFAULT]
配置可以理解为全局选项,对所有服务模块生效,当然也可以在具体的服务模块下添加参数,局部变量优先级大于全局变量,比如:
[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log
backend = %(sshd_backend)s
ignoreip = 127.0.0.1/8 ::1 10.10.0.0/16 172.16.0.0/16
bantime = 60m
findtime = 1m
maxretry = 5
以上配置表示,一分钟内如果ssh登陆失败五次,则封锁访问的IP,同时排除本地回环地址和一些内网网段。
2.启动fail2ban
systemctl restart fail2ban #重启服务
查看fail2ban已经启用的模块:
fail2ban-client status
fail2ban-client status sshd #展示具体模块的详细细节
3.模拟ssh暴力破解
使用hydra模拟ssh穷举:
可以看到fail2ban成功将攻击IP封锁,iptables来看,fail2ban服务在iptables入口加了一条ssh端口的引入,跳转到f2b-sshd链表有一条明确的拒绝规则,拒绝攻击者的流量,并且回复icmp端口不可达:
此时攻击主机用nping探测,明确收到端口不可达回显:
4.手动解除限制
使用unban解除封锁的IP
fail2ban-client unban 192.168.1.16
fail2ban-client unban --all #解除所有
四、HTTP登录防护
1.准备模拟环境
通过htpasswd命令将密码加密后写入到文件:
printf "Rokas:$(openssl passwd -1 Rokasyang)\n" >/etc/nginx/htpasswd #用户名Rokas,密码Rokasyang
nginx配置文件根路径加一个基础验证,读取htpasswd文件密码:
location / {
auth_basic "Rokas auth";
auth_basic_user_file /etc/nginx/htpasswd;
try_files $uri $uri/ =404;
}
之后重启nginx,通过curl模拟请求,可以看到只有输入用户名密码后才能成功登录:
2.配置filter
fail2ban的过滤规则均在/etc/fail2ban/filter.d目录下,比如前面所说的sshd,默认读取的是此目录下的sshd.conf文件。
同理,jail.local配置文件里的nginx-http-auth
模块也有对应命名的filter文件,但里面的匹配规则和我们实际场景不相符。
在/etc/fail2ban/filter.d目录下新增一个nginx-auth.conf
文件,写入如下规则:
[Definition]
failregex= <HOST> -.*- .*HTTP/1.* 401 .*$
ignoreregex =
修改jail.local,启用nginx-http-auth模块:
[nginx-http-auth]
enabled = true
port = 80,443
filter = nginx-auth #过滤规则引用filter.d目录下刚新建的nginx-auth.conf文件
logpath = /var/log/nginx/access.log #nginx的访问日志路径
bantime = 60m
findtime = 1m
maxretry = 3
3.重载fail2ban-client
fail2ban-client reload
4.模拟测试
客户端尝试三次登陆失败后,第四次被拒绝连接:
此时fail2ban已成功将客户端IP封锁:
五、HTTP访问频率限制
1.新增filter
同理,在/etc/fail2ban/filter.d目录下新增规则文件,如nginx-limit-request.conf:
[Definition]
failregex = <HOST>.*-.*-.*$
ignoreregex =
2.配置jail.local
启用nginx-limit-req:
[nginx-limit-req]
enabled = true
port = http,https
filter= nginx-limit-request
logpath = /var/log/nginx/access.log
bantime = 1d
findtime = 1m
maxretry = 10
3.重载fail2ban-client
reload可以是具体的模块,不接模块则reload所有enable的模块:
fail2ban-client reload nginx-limit-req
4.模拟测试
通过11次模拟测试,第11次被拒绝访问:
意料之中,fail2ban已经把客户端IP给BAN了:
总结
通过上述几个例子,其他服务的安全防护配置也能信手拈来,当然有些服务的安全防护本身就是有的,比如nginx的conn_limit模块可以限制访问频率,能用本身自带的安全防护就无需再用fail2ban。
附带PDF版本: