起因是看到使用iptables限制区域访问 - 配置调优 - LINUX DO这篇帖子,我就想起我当时天天被爆破ssh时的解决方案
安装
Fail2Ban的安装和配置过程非常直接,相关信息可以在其GitHub仓库以及官方Wiki中找到:
配置
wiki里是这么说的:
If not configured manually, Fail2ban will load configuration files from the directory
/etc/fail2ban
. You can find many files called*.conf
there.
Before you start the fail2ban service for the first time, you should do some configuration appropriate to your system. The least would be to enable jails for the services that you want to protect with fail2ban.[Q] Should I make my configuration directly in
jail.conf
andfail2ban.conf
?
[A] No. You should avoid to change.conf
files, created by fail2ban installation. Instead, you should create new files with a.local
extension.
官方推荐在配置 fail2ban 的时候应该避免直接更改由 fail2ban 安装创建的.conf
文件(例如 fail2ban.conf
和 jail.conf
),应该创建扩展名为.local
的新文件(例如 jail.local
)来进行自定义配置。
.local
文件将覆盖.conf
文件相同部分的参数。
我拿sshd爆破来举个例子:
-
首先创建
.local
文件:vim /etc/fail2ban/jail.local
-
然后添加规则(可根据需要修改):
[DEFAULT]
# 配置忽略检测的 IP (段),添加多个需要用空格隔开
ignoreip = 127.0.0.1/8
[sshd]
enabled = true
# ssh的端口,如果使用非默认端口 22,要修改为实际使用端口
port = 22
# 配置使用的匹配规则文件(位于 /etc/fail2ban/filter.d 目录中)
filter = sshd
# 日志文件路径
logpath = /var/log/ban_sshd.log
# 配置 IP 封禁的持续时间(years/months/weeks/days/hours/minutes/seconds)
bantime = 1h
# 是否开启增量禁止,可选
bantime.increment = true
# 如果上面为false则不生效,增量禁止的指数因子,这里设置为168的意思就是每次增加 168*(2^ban次数) (封禁时长类似这样 - 1小时 -> 7天 -> 14天 ...):
bantime.factor = 168
# 最大封禁时间,8w 表示8周,可选
bantime.maxtime = 8w
# 配置计算封禁 IP 的具体滑动窗口大小
findtime = 5m
# 配置在 findtime 时间内发生多少次失败登录然后将 IP 封禁
maxretry = 3
# 配置封禁 IP 的手段(位于 /etc/fail2ban/action.d 目录中),可通过 iptables、firewalld 或者 TCP Wrapper 等,此处设置为 hostsdeny 代表使用 TCP Wrapper
action = hostsdeny
以上配置就是针对于 22
端口的ssh
服务,在 5分钟
内,连续超过 3
次登录失败,就使用TCP Wrapper
封禁尝试登录的ip 1小时
, 1小时
解封后继续登录失败,那就增量封禁到 7天->14天 ...
,最长封禁时间为 8周
:wq
保存退出,然后重启服务生效
systemctl restart fail2ban
systemctl status fail2ban
内存节省选项(可选)
详见: maxmatches: memory saving options by sebres · Pull Request #2402 · fail2ban/fail2ban
在网站或服务器被DDoS时,由于findtime
和bantime
很长,可能导致 fail2ban 在访问量较大的网站上产生大量内存消耗,解决方式就是配置中添加类似这样:
fail2ban.local:
[DEFAULT]
dbmaxmatches = 0
dbpurgeage = 20d
jail.local:
[DEFAULT]
maxmatches = 0
验证配置是否生效
tail -f /var/log/ban_sshd.log
或者fail2ban-client status sshd
就能看到目前正在爆破你和ban掉爆破ssh的ip日志,和目前已经封禁的ip了
# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 4
| |- Total failed: 2435
| `- File list: /var/log/ban_sshd.log
`- Actions
|- Currently banned: 95
|- Total banned: 97
`- Banned IP list: 188.166.250.214 61.177.172.140 180.101.88.205 218.92.0.29 61.177.172.179 211.224.34.90 218.92.0.107 218.92.0.118 210.204.192.235 86.60.174.21 180.101.88.197 61.177.172.160 61.177.172.136 218.92.0.76 180.101.88.196 125.124.113.133 111.2.113.237 218.92.0.112 179.43.180.106 165.232.159.232 185.148.253.22 59.5.15.143 64.225.30.41 183.81.169.238 188.192.178.230 210.231.184.92 221.226.39.202 170.106.183.204 165.227.85.21 143.244.177.125 92.205.108.83 43.156.35.214 78.135.85.201 195.72.145.14 64.225.54.6 170.106.199.89 43.143.164.246 120.53.220.179 94.179.133.22 139.196.253.42 165.232.180.16 45.164.39.253 201.226.239.98 27.254.149.199 114.132.157.247 113.31.119.15 81.71.88.224 101.126.64.240 124.223.2.75 104.250.50.192 170.64.163.179 117.184.199.39 118.195.163.59 220.82.219.197 81.192.46.48 46.25.44.227 49.51.231.176 43.153.162.117 170.106.65.25 190.145.192.106 111.67.195.91 221.145.121.27 210.222.106.148 217.76.48.9 185.224.128.34 185.219.127.19 112.196.74.82 43.156.17.233 106.240.228.244 124.156.192.109 43.153.220.28 103.240.205.212 43.139.139.189 106.13.223.14 124.223.6.90 103.226.248.146 103.79.152.202 42.194.226.27 181.94.223.41 113.142.54.163 27.254.235.4 220.123.110.183 87.255.193.50 161.35.71.130 89.185.85.151 35.227.114.241 159.65.224.161 43.134.63.206 128.199.39.25 205.185.113.140 119.246.42.139 211.225.58.80 161.35.221.197 43.133.34.99 43.153.75.181
可以看到我阿里云香港的vps,就这刚刚一会已经被ssh爆破了2435次,ban掉97个ip了
通过正则来ban特定日志记录的ip
如果需要,还可以根据失败日志中的特定模式来封禁IP。例如,对于如下Speed-Test
类型的日志:
Feb 28 23:45:30 host kernel: [5140091.073466] Speed-Test IN=eno1 OUT= MAC=... SRC=192.0.2.1 DST=127.0.0.1 ...
可以在.local
文件中添加相应的failregex
规则来匹配这种模式。
在.local
文件里添加一行
failregex = ^\s*\S+\s+kernel:(?: +\[[^\]]+\])? Speed-Test (?:\b(?:IN=\w+|OUT=|(?:(?!OUT=|IN=)[A-Z]+=[^ \[]*)+) )*SRC=<ADDR> DST=\S+
这样所有触发特定失败日志的ip都会根据规则来封禁。
基于此,可以用来保护WordPress,WP登录地址为/wp-login.php
所以可以新增配置文件:
[wordpress]
enabled = true
# HTTP(80端口)和HTTPS(443端口)
port = http,https
# fail2ban 自带动作,意思是封禁,记录日志,发送邮件给管理员
action = %(action_mwl)s
maxretry = 5
findtime = 60s
bantime = 12h
logpath = /var/log/wp_access.log
failregex = ^ -.* /wp-login.php.* HTTP/1\.."
解封
# 解封所有IP
fail2ban-client unban --all
# 解封指定IP
# fail2ban-client unban <IP> ... <IP>
fail2ban-client unban 1.1.1.1
#删除特定服务的(如sshd)被ban IP
fail2ban-client set sshd delignoreip 1.1.1.1