背景

服务器只要对外暴露端口,就会引来各种扫描。今天登录服务器,查看 /var/log/auth.log 日志,发现有几乎一直有人尝试用 ssh 登录服务器。虽然没有成功的,但是让人一直暴力破解也有些安全隐患。 本文也记录一下本次操作的方法,便于以后再有新的服务器,也能快速做自动封禁。

封禁 IP

创建一个脚本 /root/scripts/ban_auth_failed_ip.sh ,读取日志 /var/log/auth.log,提取登录失败次数过多的 IP。有的系统没有这个文件,可以通过 systemctl -u ssh -n 500 或者 systemctl -u sshd -n 500 获取最近的 500 条日志。 这里首先提前登录失败的 IP,并统计次数,只有被封禁的 IP 不在 /etc/hosts.deny 的时候才新增封禁。 脚本里把阈值设定为 6 次了,如果有需要可以自行修改。

1
2
3
4
5
6
7
8
9
10
11
12
#! /usr/bin/bash

BLACKS=`tail -500 /var/log/auth.log | grep Failed | sed "s/^.*from \(.*\) port.*$/\1/g" | sort | uniq -c | awk '{if ($1 >= 6) {printf "sshd:%s:deny\n",$2}}'`
for line in $BLACKS
do
cnt=`fgrep $line /etc/hosts.deny | wc -l`
if [ $cnt -ne 0 ]
then
continue
fi
echo $line >> /etc/hosts.deny
done

解封 IP

防止封禁的 IP 列表过长,创建一个脚本 /root/scripts/recover_host_deny.sh,自动清空 /etc/hosts.deny

1
2
#! /usr/bin/bash
sed -ni '/^#.*$/p; /^$/p' /etc/hosts.deny

同时为了防止把自己的 IP 封禁了,可以修改 /etc/hosts.allow,把常用的 IP 添加进去。hosts.allow 的优先级是高于 hosts.deny 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
# /etc/hosts.allow: list of hosts that are allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: LOCAL @some_netgroup
# ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#

sshd: 192.168.10.0/24
sshd: 10.28.13.12
sshd: 10.28.12.15

定时任务

为了实现自动封禁和解封,可以使用 crontab 设置定时任务,自动执行脚本。由于脚本需要有权限修改 /etc/hosts.deny 文件,可以设置 root 的 crontab,执行 crontab -e

1
2
*/2 * * * * /root/scripts/ban_auth_failed_ip.sh > /dev/null
1 23 * * * /root/scripts/recover_host_deny.sh > /dev/null

设置每隔 2 分钟自动执行 /root/scripts/ban_auth_failed_ip.sh 封禁 IP。

每天的 23:01 分,自动执行 /root/scripts/recover_host_deny.sh 解封全部 IP。