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 周。
- 第一阶段:若
src-address
不在 trusted
列表中,且新连接(根据 TCP 的 SYN 包判断)SSH 或 Winbox 端口,则将 IP 地址加入 bruteforce_stage1
列表,有效期 2 分钟。
- 第二阶段:若
src-address
在 bruteforce_stage1
列表中,且新连接 SSH 或 Winbox 端口,则将 IP 地址加入 bruteforce_stage2
列表,有效期 2 分钟。
- 第三阶段:若
src-address
在 bruteforce_stage2
列表中,且新连接 SSH 或 Winbox 端口,则将 IP 地址加入 bruteforce_blacklist
列表,有效期 2 周。来自该列表内的数据流将被 tarpit
或 drop
,取决于你设定的行为。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,还可以这么设计白名单:
- 开放 SSH 端口,禁用 SSH 密码登录,仅允许公钥登录。
- 每分钟检查在线用户,将其 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 施压。