linux将SSH多次登录失败的IP加入黑名单

admin 2021年04月20日 3,072次浏览

最近发现有人经常尝试使用SSH登录我的服务器,但是由于种种原因,只有自己想办法来阻止非法访问,最简单的方法就是通过系统自带的黑名单机制,将登录失败次数达到设定值的主机IP加入黑名单,以此来防止非法登录。

解决思路

创建一个定时任务,定时执行脚本文件,以此来检查登录失败主机列表,并将达到登录失败次数的主机IP地址加入到黑名单

【2021-08-09 】 经过一段时间的观察,使用现有的脚本虽然能防止非法 SSH 访问,但是在阻止访问后,一方面在系统安全日志中会记录每一条访问记录,这样会导致日志中大量记录非法访问的主机的 IP 地址,将其他的信息淹没在无用的信息中,不便于查询其他日志记录;另一方面,在将非法主机写入文件后,如果该主机继续访问,那么 sshd 服务还得去查询记录文件,来一条查一次,这样会导致 sshd 服务异常繁忙,可能会影响到正常业务访问。

为了解决以上问题,现将脚本进行了优化,在原有脚本的基础上,添加了系统防火墙联动机制(仅限于使用 firewalld 防火墙,其他如:Ubuntu的UFW防火墙请参考本脚本自行修改),将登录失败次数超过限定次数的主机 IP 地址,一方面写入 hosts.deny 文件外,同时将该 IP 地址添加到防火墙策略中,将其的数据包在到达主机时,直接丢弃,这样就不需要再通过 sshd 服务处理,一方面可以减轻 sshd 服务的压力;另一方面,因为不需要 sshd 服务的干预,所以也就没有相关日志的记录,不会将其他信息覆盖。

脚本文件

最新脚本文件:ssh_login_failed_host_deny_v0.2.sh

#!/usr/bin/bash
# -*- coding:UTF-8 -*-
#
#########################################################
#                                                       #
#    file name: ssh_login_failed_host_deny              #
#  description: 将SSH多次登录失败的IP加入黑名单           #
#       author: oldyan                                  #
#      version: 0.2                                     #	
#         date: 2021-08-9                               #
#                                                       #
#########################################################


# 通过lastb获取登录失败的IP及登录失败的次数
lastb | awk '{print $3}' | grep ^[0-9] | sort | uniq -c | awk '{print $1"\t"$2}' > /tmp/host_list
list=`cat /tmp/host_list`
line=`wc -l /tmp/host_list | awk '{print $1}'`
count=1

# 如果/tmp/host_list中有数据,循环至少需要执行一次
while [[ "$line" -ge "$count" ]]; do
	ip_add=`echo $list | awk '{FS="\t"} {print $2}'`
	num=`echo $list | awk  '{FS="\t"} {print $1}'`
#   登录失败达到5次就将该IP写入文件
	if [[ "$num" -ge 5 ]]; then
		grep "$ip_add" /etc/hosts.deny &> /dev/null
		if [[ "$?" -gt 0 ]]; then
# --------> 此处添加当前系统时间,请根据实际情况定义日期格式
			echo "# $(date +%F' '%H:%M:%S)" >> /etc/hosts.deny
			echo "sshd:$ip_add" >> /etc/hosts.deny
# --------> firewalld将加入黑名单的IP的数据包直接丢弃			
			firewall-cmd --add-rich-rule="rule family="ipv4" source address="$ip_add" drop" --permanent &> /dev/null
			firewall-cmd --reload &> /dev/null
		fi
	fi
	let count+=1
#   删除已经写入文件的IP
	sed -i '1d' /tmp/host_list
#   修改$list变量
	list=`cat /tmp/host_list`
done
# 清空临时文件
echo '' > /tmp/host_list
exit 0

创建定时任务

[root@localhost ~]# crontab -e
# 每分钟执行一次
* * * * * /hone/user/ssh_login_failed_host_deny.sh