Featured image of post 在OpenWrt上配置Fail2Ban

在OpenWrt上配置Fail2Ban

拒绝烦人的端口扫描

封面PID=112536466

前段时间为了排查路由器的一些服务问题,去翻系统日志,发现自己的路由器因为有在公网上被扫了几百次(好家伙,我都换端口了还能扫😅),整个系统日志全是各种ssh连接失败的报错。虽然禁用了密码登录,但是整个日志被刷的太乱,导致正常运维都成问题,属实是伤害不高侮辱性极强了。于是为了保证我的路由器不被这些脚本小子搭讪,开始研究如何使用Fail2Ban来自动拉黑这些扫描的脚本机。

安装

这块没什么好说的,不管是官方源还是目前国内普及的lean lede源都有fail2ban的包,直接opkg就行

1
opkg install fail2ban

安装好后在终端中输入which fail2ban-client,验证下是否安装成功,正常的话会输出对应的执行文件路径。

配置

默认配置文件目录在/etc/fail2ban。Fail2Ban需要配置两个地方,一个是过滤规则,或者说是正则匹配逻辑;一个是配置具体封禁策略,包含hit次数,日志位置等。

过滤规则

/etc/fail2ban/filter.d下是项目自带的默认过滤规则,而官方本身OpenWrt的dropbaer规则不能直接使用,不知道是不是因为迭代没跟上还是怎么的,dropbear的日志匹配逻辑对不上,因此需要我们自己修改过滤规则。下面给出我自己配置的规则供参考,把官方的dropbear.conf改了即可:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# The standard Dropbear output doesn't provide enough information to
# ban all types of attack.  The Dropbear patch adds IP address
# information to the 'exit before auth' message which is always
# produced for any form of non-successful login. It is that message
# which this file matches.
#
# More information: http://bugs.debian.org/546913

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = common.conf

[Definition]

_daemon = dropbear

datepattern = ^%%a %%b %%d %%H:%%M:%%S %%Y

prefregex = ^%(__prefix_line)s<F-CONTENT>(?:[Ll]ogin|[Bb]ad|[Ee]xit).+</F-CONTENT>$

failregex = ^[Ee]xit before auth from <<HOST>:\d+>:\s.*$

ignoreregex = 

# DEV Notes:
#
# The first two regexs here match the unmodified dropbear messages. It isn't
# possible to match the source of the 'exit before auth' messages from dropbear
# as they don't include the "from <HOST>" bit.
#
# The second last failregex line we need to match with the modified dropbear.
#
# For the second regex the following apply:
#
# http://www.netmite.com/android/mydroid/external/dropbear/svr-authpam.c
# http://svn.dd-wrt.com/changeset/16642#file64
#
# http://svn.dd-wrt.com/changeset/16642/src/router/dropbear/svr-authpasswd.c
#
# Author: Francis Russell
#         Zak B. Elep

接下来,我们需要把系统日志重定向到系统文件中,使用以下命令操作:

1
2
3
4
mkdir -p /tmp/log
touch /tmp/log/system.log
uci set system.@system[0].log_file='/tmp/log/system.log'
uci commit

这套过滤规则可以过滤出登录失败的主机ip。fail2ban也有专门的命令可以测试配置有效性,可以使用fail2ban-regex /tmp/log/system.log /etc/fail2ban/filter.d/dropbear.conf命令测试过滤匹配是否正确。

验证规则

封禁策略

随后我们还需要配置封禁策略,这个策略一般是放在/etc/fail2ban/jail.d目录下,我们可以在这个目录下面新建一个策略名为dropbear.local的文件,在其中配置命中策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[dropbear]

enabled = true
filter = dropbear
# port为你对应的ssh端口
action = iptables[port=22, protocol=tcp]
# 上一步创建的日志文件路径
logpath = /tmp/log/system.log
maxretry = 3
bantime = 604800
findtime = 86400

这个封禁策略会将在一天内ssh登录失败3次的ip封禁一个星期。

最后,我们使用命令fail2ban-client start启动Fail2Ban。

效果

使用命令fail2ban-client status dropbear,查看当前dropbear规则的封禁情况

规则状态

可以看到,这封禁ip的数量还真不少,用ipip查了下,国内国外的都有。

进阶

luci登录封禁

既然我们都把dropbear配了登录封禁,那么就顺道给web登录页面也配一个吧😉

具体步骤和dropbear一样,由于我用的是nginx作为luci的服务器,而且修改了日志格式,因此以下配置仅供参考。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
[INCLUDES]
 
# Read common prefixes.If any customizations available -- read them from
# common.local
before = common.conf
 
 
[Definition]
 
 
_daemon = luci
 
datepattern = ^\[%%d/%%b/%%Y:%%H:%%M:%%S \+0800\]


prefregex = ^.*POST.*<F-CONTENT>(?:403).+</F-CONTENT>$
 
failregex = ^403.*from <HOST>$
 
ignoreregex = ^403.*from 127.0.0.1$

其中过滤规则的ignore是因为luci在第一次进入主页时会触发本地反代403,因此需要忽略。日期格式匹配可能需要自行根据自己的nginx日志进行调整。

最后加上封禁策略:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# luci web
[luci]

enabled  = true
filter   = luci
action   = iptables[port=https, protocol=tcp]
logpath  = /tmp/log/nginx/access.log
maxretry = 5
bantime  = 604800
findtime = 1800

重启Fail2Ban,收工!