背景:
基于之前的文章Lastb自动邮件通知(安全,仅邮件通知)-CSDN博客
优化内容:
- 增加频次及时间的变量,方便设置。
- 脚本也简单明晰。
- 文件也减少,剩余一个。
具体展示(login.sh):
#!/bin/bash
# 设置时间范围(单位:分钟)
TIMERANGE=30
# 设置告警阈值(失败次数)
ALARM_THRESHOLD=5
# 获取当前时间并计算时间范围
END_TIME=$(date +%s)
START_TIME=$((END_TIME - TIMERANGE * 60))
#IP
IP=$(hostname -I | awk '{print$1}')
# 使用 lastb 命令获取失败登录记录并统计
lastb | awk '!/btmp/' | awk 'NF' | awk -v start="$START_TIME" -v end="$END_TIME" -v threshold="$ALARM_THRESHOLD" -v timerange="$TIMERANGE" -v Ip="$IP" '
BEGIN {
OFS="\t\t"
format="%a %b %d %H:%M:%S %Y" # 时间格式(根据系统调整)
print "用户名", "IP地址", "失败次数"
}
{
# 提取用户名(第一列)
user = $1
# 提取IP地址(第四列)
ip = $3
# 提取登录时间(Mon Jun 16 16:35)
login_time = $4 " " $5 " " $6 " " $7
# 将时间转换为Unix时间戳
cmd = sprintf("date -d \"%s\" +%%s", login_time)
cmd | getline time_stamp
close(cmd)
# 检查时间是否在范围内
if (time_stamp >= start && time_stamp <= end) {
count[user, ip]++
}
}
END {
# 输出统计结果
for (entry in count) {
split(entry, parts, SUBSEP)
user = parts[1]
ip = parts[2]
printf "%s\t\t%s\t%d\n", user, ip, count[entry]
# 如果失败次数超过阈值,发出告警
if (count[entry] >= threshold) {
alarm_msg = sprintf("告警:用户 %s 通过 %s 在最近 %d 分钟内失败登录服务器: %s 共计:%d 次!", user, ip, timerange, Ip, count[entry])
# 可选:记录到系统日志
system(sprintf("logger -p user.warning \"%s\"", alarm_msg))
# 可选:发送邮件告警(需配置 mailx)
system(sprintf("echo \"%s\" | mail -s \"SSH登录失败告警\" *****@163.com", alarm_msg))
}
}
}
'
效果展示: