1. 适用场景
服务器因业务需要开放互联网ssh访问时,不能通过限制ip来进行防护,那我们常用的其他安全手段手段包括使用强密码、限制登录频率、使用防火墙、限制访问权限、使用第三方安全服务、使用安全协议(如sftp)等等。通常这些手段对于高频率爆破攻击行为有较好的拦截效果。但攻击者可能会使用低频率、轮换IP的方式来进行攻击、比如一个IP1个小时左右攻击一次,那我们的常规的安全手段很难把这样的行为认定为恶意攻击。
我在工作中也遇到这样的问题,我除了使用基线、防火墙等常规的防护手段之外,使用了shell脚本进行安全防护,脚本是我自己所写,已经运行了半年多,安全可靠。
2. 脚本逻辑
- 脚本会自动检查服务器系统版本:目前仅支持Centos7和Tencent2.4,其他系统暂不支持。
- 创建初始白名单:登录成功的IP自动创建为初始白名单,仅首次运行脚本时执行一次,日常防护时,会自动跳过。
- 判定友方IP:在黑名单规则内(5次内成功登录)仍能登录成功的IP判定为友方IP。
- 追加白名单:把友方IP自动追加为白名单。
- 检查黑名单:黑名单数量大于5000条时,清除已添加的黑名单。
- 判定攻击行为:非友方IP当天登录失败累计超过5次判定其存在攻击行为。
- 追加黑名单:把存在攻击行为的非友方IP自动追加为黑名单。
- 记录加黑白名单信息:追加黑白名单后,记录追加的时间与数量。
3. 说明
-
执行频率:把脚本加入定时任务中,每5分钟执行一次。
-
黑白名单规则优先级:在同一个执行周期内,若同时触发黑白名单规则,则白名单规则优先于黑名单规则。这样可以避免友方IP因输入错密码导致被拉黑。
-
手动添加/移除白名单:直接在/home/Accepted_user添加/删除相应IP即可。
-
手动添加/移除黑名单:直接在/etc/hosts.deny添加/删除相应IP即可(lastb命令根据用户名查IP)。
-
黑名单周期:黑名单从0增至5000为一个黑名单周期。自动清楚黑名单,避免黑名单过多导致访问变慢。
-
预期目标:一个黑名单周期内,恶意IP最长攻击时间控制在5分钟内或最大攻击次数限定5次内,降低SFTP服务器被攻破风险。
-
-脚本文件/home/SSHSecurityScript.sh
-
白名单文件/home/Accepted_user,白名单样例:
192.168.0.1 192.168.0.2 #sshd Wed Feb 22 14:25:01 CST 2023 新增 2 个白名单
-
黑名单文件/etc/hosts.deny,黑名单样例:
sshd:106.75.71.3 sshd:222.105.112.149 #sshd Wed Feb 22 13:55:01 CST 2023 新增 63 个黑名单 sshd:111.173.89.33 sshd:146.190.237.252 #sshd Wed Feb 22 14:10:01 CST 2023 新增 2 个黑名单 sshd:59.125.53.140 #sshd Wed Feb 22 14:15:01 CST 2023 新增 1 个黑名单
-
黑名单IP登录日志样例:
Feb 21 14:05:54 ip-10-85-2-105 sshd[9244]: refused connect from 85.152.57.60 (85.152.57.60)
4. 脚本
#! /bin/bash
#version:v1
#author:LJZe
#date:2023-2-20
#crontab -e
#5/* * * * * sh /home/SSHSecurityScript.sh
#systemctl restart crond.service
#检查系统版本
function CheckSystem() {
system_version=''
source /etc/os-release
if [[ -e /etc/os-release ]]; then
system_version=${system_version}"PRETTY_NAME: $PRETTY_NAME, "
else
system_version=${system_version}"PRETTY_NAME: `cat /etc/issue|head -n 1`, "
fi
system_v=`echo $system_version | awk '{print $2,$3,$4}'`
system_v1=`echo "$system_v"|awk '{gsub(/ /,"")}1'`
# echo "${system_v1}"
}
#创建初始白名单:统计半年内成功登录的IP,耗时久,仅执行一次
function AcceptedUser(){
date1=`date`
touch /home/Accepted_user
grep "Accepted" /var/log/secure*|perl -e 'while($_=<>){ /from(.*?) port/; print "$1\n";}'|sort -nr|uniq -c |sort -nr |awk '{print $2}' > /home/Accepted_user
echo "#sshd ${date1} 创建初始白名单" >> /home/Accepted_user
}
#新增白名单,在黑名单规则内仍能成功登录的IP,判定为白名单
function AcceptedUserNew(){
date1=`date`
Accepted_user_new=$(grep "Accepted password for" /var/log/secure|awk '{print $11}'|sort | uniq -c | sort -nr|awk '{print $2}')
i=0
for IP in $Accepted_user_new; do
Accepted_ip=`grep "$IP" /home/Accepted_user | wc -l`
if [ $Accepted_ip -le 0 ] ; then
echo "$IP" >> /home/Accepted_user
i=$(( $i + 1 ))
fi
done
#加白名单时间
if [ $i -gt 0 ];then
echo "#sshd ${date1} 新增 ${i} 个白名单" >> /home/Accepted_user
fi
}
#当黑名单大于5000条时清空规则
function delete_rule_CentOS(){
delete_rule=`cat /etc/hosts.deny|grep "sshd:"|wc -l`
if [ $delete_rule -ge 5000 ];then
sed -i '/sshd/d' /etc/hosts.deny
fi
}
#加黑名单
function hosts_deny_CentOS() {
LANG="en_US.UTF-8"
date1=`date`
day1=`date |awk '{print $3}'`
#日期格式
if [ ${day1} -lt 10 ];then
time1=`date|awk '{print $2,"",$3}'`
else
time1=`date|awk '{print $2,$3}'`
fi
#登录失败次数大于5次的IP
#ABNORMAL_IP=$(lastb |grep "${time1}" |awk '{a[$3]++}END{for(i in a)if(a[i]>5)print i}')
ABNORMAL_IP=$(grep "Failed" /var/log/secure|grep "${time1}"|awk '{a[$((NF-3))]++}END{for(i in a)if(a[i]>5)print i}')
#加黑名单
i=0
for IP in $ABNORMAL_IP; do
#验证黑名单是否已存在
insert_ip=`grep "$IP" /etc/hosts.deny | wc -l`
#过滤白名单
insert_ip1=`grep "$IP" /home/Accepted_user | wc -l`
if [ $insert_ip -le 0 ] ; then
# echo "屏蔽IP:$IP"
if [ $insert_ip1 -le 0 ];then
echo "sshd:${IP}" >> /etc/hosts.deny
i=$(( $i + 1 ))
# else
# echo "IP:$IP 可能为友方IP,不加入黑名单"
fi
# else
# echo "IP:$IP 已存在系统黑名单中"
fi
done
#加黑名单时间
if [ $i -gt 0 ];then
echo "#sshd ${date1} 新增 ${i} 个黑名单" >> /etc/hosts.deny
fi
}
main() {
CheckSystem
if [ $system_v1 = "CentOSLinux7" -o $system_v1 = "TencentOSServer2.4" ];then
#AcceptedUser初始化白名单,耗时长,仅首次执行一次
if ! [[ -e /home/Accepted_user ]]; then
AcceptedUser
fi
AcceptedUserNew
delete_rule_CentOS
hosts_deny_CentOS
else
echo "此系统为${system_v},仅支持CentOS Linux 7、TencentOS Server 2.4!"
fi
}
main