在 RouterOS 上实现 Fail2ban 策略

2024-10-19 23:37:16
This post is also available in English and alternative languages.

fail2ban 策略

在前文中,我们介绍了在 VPS 上使用 dd 命令安装 RouterOS。当路由暴露在公网环境时,不可避免地会受到扫描和爆破攻击。对于常规的 Linux 服务器,我们可以使用名为 fail2ban 的工具自动拉黑攻击者的 IP 地址,并上报到公共黑名单服务(例如 AbuseIPDB)。RouterOS 自身没有为用户验证成功和失败提供 callback,我们可以使用防火墙的 address-list 功能实现类似的功能。

下列规则会在 RouterOS 上实现类似 fail2ban 的策略:2 分钟内连接 3 次 SSH 或 Winbox 端口的 IP 地址会被拉黑 2 周。

  1. 第一阶段:若 src-address 不在 trusted 列表中,且新连接根据 TCP 的 SYN 包判断)SSH 或 Winbox 端口,则将 IP 地址加入 bruteforce_stage1 列表,有效期 2 分钟。
  2. 第二阶段:若 src-addressbruteforce_stage1 列表中,且新连接 SSH 或 Winbox 端口,则将 IP 地址加入 bruteforce_stage2 列表,有效期 2 分钟。
  3. 第三阶段:若 src-addressbruteforce_stage2 列表中,且新连接 SSH 或 Winbox 端口,则将 IP 地址加入 bruteforce_blacklist 列表,有效期 2 周。来自该列表内的数据流将被 tarpitdrop,取决于你设定的行为。tarpit 只能用于 TCP 连接。
1
2
3
4
5
/ip firewall filter
add action=tarpit chain=input comment="block bruteforcer" protocol=tcp src-address-list=bruteforce_blacklist
add action=add-src-to-address-list address-list=bruteforce_blacklist address-list-timeout=2w chain=input comment="bruteforcer stage 3" connection-state=new dst-port=22,8291 protocol=tcp src-address-list=bruteforce_stage2
add action=add-src-to-address-list address-list=bruteforce_stage2 address-list-timeout=2m chain=input comment="bruteforcer stage 2" connection-state=new dst-port=22,8291 protocol=tcp src-address-list=bruteforce_stage1
add action=add-src-to-address-list address-list=bruteforce_stage1 address-list-timeout=2m chain=input comment="bruteforcer stage 1" connection-state=new dst-port=22,8291 protocol=tcp src-address-list=!trusted

这还不够 —— 当管理员的网络出现波动时,Winbox 会自动重连,导致被误判为攻击者。除此之外,短时间合法用户同时连接 SSH 和 Winbox,也会命中该规则。因此,当第一次登录成功时,我们需要将管理员 session 的 IP 地址加入 trusted 列表,并保持一段时间。

这段脚本会检查当前活跃的 RouterOS 用户,并将其 IP 地址加入 trusted 列表,有效期 1 天。

1
2
3
4
5
6
7
8
9
10
11
12
13
/system script
add dont-require-permissions=no name=add-active-users-to-trusted owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":local users [/user/active/print as-value]\
\n:local listname \"trusted\"\
\n:foreach user in=\$users do={\
\n \
\n :if ([:len [/ip/firewall/address-list/find address=(\$user->\"address\") list=\$listname]] > 0) do={\
\n :log info (\$user->\"address\" . \" is already in \" . \$listname . \" list\")\
\n /ip/firewall/address-list set [find address=(\$user->\"address\") list=trusted] timeout=1h comment=(\"Updated by script for \" . (\$user->\"name\"))\
\n } else={\
\n :log info (\"Added \" . (\$user->\"name\") . \" \" . \$user->\"address\" . \" to \" . \$listname)\
\n /ip/firewall/address-list add address=(\$user->\"address\") list=\$listname timeout=1d comment=(\"Added by script for \" . (\$user->\"name\"))\
\n }\
\n}"

最后,设置定时任务每分钟执行一次该脚本。

1
2
/system scheduler
add interval=1m name=add-active-users-to-trusted on-event="/system/script/run add-active-users-to-trusted" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon

短短半天时间,黑名单列表就塞下了上百个 IP 地址,

1
2
3
4
5
6
7
8
9
10
11
12
13
[admin@MikroTik] /ip/firewall/address-list> :put [:len [find where list=bruteforce_blacklist ]]
135
[admin@MikroTik] /ip/firewall/filter> print stats
Columns: CHAIN, ACTION, BYTES, PACKETS
# CHAIN ACTION BYTES PACKETS
;;; block bruteforcer
0 input tarpit 922 328 21 325
;;; bruteforcer stage 3
1 input add-src-to-address-list 8 232 137
;;; bruteforcer stage 2
2 input add-src-to-address-list 17 839 296
;;; bruteforcer stage 1
3 input add-src-to-address-list 46 123 815

白名单策略

除了 fail2ban 策略和 Port Knocking,还可以这么设计白名单:

  1. 开放 SSH 端口,禁用 SSH 密码登录,仅允许公钥登录。
  2. 每分钟检查在线用户,将其 IP 地址加入 trusted 列表,允许 Winbox TCP 8291 端口连接。

这样,若是想使用 Winbox 连接 RouterOS,只需先 SSH 登录一次即可。相对端口敲门和 fail2ban 策略来说,这个方案更加简单。

此外,还可以为 SSH 和 Winbox 服务设置 connection limit。

投诉

可以先用 whois 工具查询 IP 所属的 AS,向对应的 abuse mailbox 或 NOC 投诉。如果是国内的 IP,发邮件时可以抄送 [email protected] 一份。

根据 Hostloc 和 V2EX 论坛的帖子,AWS、Hetnzer 和 Vultr 算是比较重视 abuse 的。对于国内的 IP,可以向上级运营商和 CNNIC 施压。

Prev
2024-10-19 23:37:16