路由器接上了公网,不可避免被扫描端口,暴力登陆。因此有个这个脚本,可以检测在一定时间内,登陆失败次数过多的IP进行封禁。

废话不多说,直接上脚本。

设置防火墙阻断列表

input链阻断对路由器本身的访问,既然对方不怀好意,那么索性将forward链也阻断,这样对方也无法访问映射的服务。

记住这里的src-address-list名称,在后面的自动检测脚本中需要用到。

/ip/firewall/filter/add chain=input in-interface=ether1 src-address-list=block_list comment="Block IP Address"

/ip/firewall/filter/add chain=forward in-interface=ether1 src-address-list=block_list comment="Block IP Address"

通过脚本维护封禁IP地址列表

有几个变量需要设置,blockList使用上面防火墙中配置的地址列表,timeout表示封禁时间,1d表示一天,within表示多长时间内,配合maxAttempts变量,表示$within时间内$maxAttempts次登陆失败,将会被封禁$timeout时间。

/system script add name="auto-block-ip" source={
# auto block IP address with too many failed login attempts
# an IP address will be blocked if it reaches the number of
# failed login attempts within the time period entered below
#
# author: Yaser Hsueh
# email:  xueye404@icloud.com
# site:   https://www.simaek.com
# block address list
:local blockList "block_list"
# block time, blocked IP address will be unlocked after the timeout entered below
:local timeout "1d"
# login within
:local within "10m"
# maximum login attempts
:local maxAttempts 5

# block IP address with too many failed login attempts
:local currentTime ([/system/clock/get time] - $within)
:local addressCount []
:foreach counter=log \
in=[/log/print as-value where topics=system,error,critical] \
do={
    :local logTime [:totime ($log->"time")]
    :if ($logTime > $currentTime) do={
        :local message ($log->"message")
        # filter ssh login failures
        :if (([:find $message "via ssh"]) >= 0 && ([:find $message "login failure"]) >= 0) do={
            # pick IP address
            :local start ([:find $message "from"] + 5)
            :local end ([:find $message "via ssh"] - 1)
            :local blockIP [:pick $message $start $end]
            # count login attempts
            :set ($addressCount->$blockIP) (($addressCount->$blockIP) + 1)
        }
    }
}
# add address to block address list
:foreach k,v in=$addressCount do={
    if ($v >= $maxAttempts) do={
        if ([/ip/firewall/address-list/print as-value where list=$blockList && address=$k]) \
        do={
            /log/info message=("[AutoBlock] " . $k . " was already exist in block list")
        } else={
            /ip/firewall/address-list add list=$blockList address=$k timeout=$timeout
            /log/info message=("[AutoBlock] " . $k . " was newly added to block list")
        }
    }
}
}

设置定时任务

最后就是定时执行脚本,执行的频率酌情选择。

/system/scheduler /add name=auto-block-ip on-event=auto-block-ip interval=10m

写在最后

此处只针对了SSH进行封禁,对于其他服务FTP等也可以进行相应的操作。只需要根据日志内容进行关键词匹配即可。

最后修改:2023 年 08 月 02 日
如果觉得我的文章对你有用,请随意赞赏