文章最后更新时间:2025年05月27日
前言
公网环境面临频繁的暴力破解攻击威胁。为防御此类攻击,本文将介绍如何编写脚本,实现以下功能:
- 封禁登录失败超5次的IP地址
- 通过邮件通知管理员异常访问行为
提示:以下为详细操作步骤及案例参考
一、服务器环境配置准备
- 操作系统:CentOS 7
- 防火墙策略:关闭
firewalld
,启用iptables
- 辅助工具:配置邮箱服务用于告警通知
二、基础环境配置
1. 关闭 firewalld 防火墙
systemctl stop firewalld # 停止服务
systemctl disable firewalld # 禁止开机自启
2. 禁用 SELinux
# 临时关闭(立即生效)
setenforce 0
# 检查状态(应返回 Disabled)
getenforce
# 永久关闭(修改配置文件)
cat /etc/selinux/config
# 确保以下配置存在
SELINUX=disabled
3. 安装并启动 iptables
# 安装 iptables 服务
yum install iptables-services -y
# 启动服务
systemctl start iptables
# 设置开机自启
systemctl enable iptables
4. 配置邮件告警功能
(1)安装邮件客户端
yum install mailx -y # 安装 mailx
(2)配置邮箱账户
vim /etc/mail.rc # 编辑配置文件
# 添加以下内容(替换为实际邮箱信息)
set bsdcompat
set from=123456@qq.com # 发件人邮箱
set smtp=smtp.exmail.qq.com # SMTP 服务器(以腾讯企业邮箱为例)
set smtp-auth-user=123456@qq.com # 邮箱账户
set smtp-auth-password=xxx # 邮箱密码/授权码
set smtp-auth=login
(3)发送测试邮件
echo "测试内容:服务器告警" | mail -s "【测试】服务器通知" 987654@qq.com
三、防暴力破解脚本开发
1. 脚本设计逻辑
- 分析登录失败日志,提取IP并统计失败次数
- 对失败次数超过阈值(5次)的IP执行封禁
- 记录操作日志并发送邮件通知
- 自动备份和清理登录失败记录
2. 完整脚本代码
#!/bin/bash
# 脚本功能:封禁登录失败超5次的IP,发送告警邮件并管理日志
# 配置项
TMP_DIR=$(mktemp -d) # 临时目录(自动清理)
LOG_FILE="$HOME/error_login.log" # 日志文件
BTMP_BACKUP_DIR="$HOME/btmp_backups" # btmp日志备份目录
MAX_BACKUPS=10 # 最大备份数
THRESHOLD=5 # 失败次数阈值
# 创建备份目录(若不存在)
mkdir -p "$BTMP_BACKUP_DIR"
# 1. 提取并统计失败登录IP
lastb | awk '{print $3}' | grep ^[0-9] | uniq -c | awk '{print $1"="$2}' > "$TMP_DIR/host"
# 2. 遍历处理每个IP
while IFS= read -r line; do
ip=$(echo "$line" | awk -F= '{print $2}')
num=$(echo "$line" | awk -F= '{print $1}')
# 检查是否超过失败阈值
if [[ $num -gt $THRESHOLD ]]; then
# 检查IP是否已被封禁
if iptables -L INPUT -n | grep -q "$ip"; then
echo "$(date +'%F %T') [INFO] IP $ip 已封禁,跳过" >> "$LOG_FILE"
continue
fi
# 查询IP归属信息(需联网)
ip_info=$(curl -s cip.cc/"$ip" | grep -E '地址|运营商' | tr -d '\n')
# 记录日志
echo "$(date +'%F %T') [ALERT] 检测到可疑IP: $ip(失败次数: $num) - $ip_info" >> "$LOG_FILE"
# 添加防火墙规则(使用绝对路径确保执行)
if /usr/sbin/iptables -I INPUT -s "$ip" -j DROP; then
echo "$(date +'%F %T') [SUCCESS] 已封禁IP: $ip - $ip_info" >> "$LOG_FILE"
# 发送告警邮件(取消注释以启用)
# echo "$ip 企图恶意登录(失败次数: $num) - $ip_info" | mail -s "【警告】暴力破解尝试" 123456@qq.com
else
echo "$(date +'%F %T') [ERROR] 封禁IP失败: $ip" >> "$LOG_FILE"
fi
fi
done < "$TMP_DIR/host"
# 3. 管理登录失败日志(btmp)
if [[ -s /var/log/btmp ]]; then
# 备份当前btmp日志
backup_file="$BTMP_BACKUP_DIR/btmp_$(date +%Y%m%d_%H%M%S)"
cp /var/log/btmp "$backup_file"
echo "$(date +'%F %T') [INFO] 已备份btmp日志到: $backup_file" >> "$LOG_FILE"
# 清空btmp日志(避免重复统计)
cat /dev/null > /var/log/btmp
# 清理旧备份(保留最新$MAX_BACKUPS个)
find "$BTMP_BACKUP_DIR" -name "btmp_*" -type f | sort -r | tail -n +"$((MAX_BACKUPS + 1))" | xargs -r rm -f
echo "$(date +'%F %T') [INFO] 已清理过期btmp备份" >> "$LOG_FILE"
fi
# 自动清理临时目录
rm -rf "$TMP_DIR"
3. 脚本执行权限与测试
chmod +x unlogin.sh # 赋予执行权限
./unlogin.sh # 手动测试执行
4. 配置定时任务(Cron)
crontab -e # 编辑定时任务
# 添加以下内容(每5分钟执行一次)
*/5 * * * * . /etc/profile && /bin/bash /root/unlogin.sh
四、关键问题与解决方案
1. 定时任务执行失败
现象:脚本手动执行正常,但Cron中不生效
原因:Cron环境变量缺失
解决:
- 在脚本中使用命令绝对路径(如
/usr/sbin/iptables
) - 在Cron任务中添加环境变量加载语句:
*/5 * * * * . /etc/profile && /bin/bash /path/to/script.sh
2. IP归属查询功能
依赖:需服务器联网并允许访问cip.cc
作用:记录IP地理位置和运营商信息,辅助定位攻击来源
3. 日志管理
- 日志文件:
$HOME/error_login.log
记录操作详情 - 备份策略:自动保留最近10份
btmp
日志备份,避免日志过大
五、总结
本文通过结合iptables
防火墙与Shell脚本,实现了自动化的暴力破解防御机制。关键要点包括:
- 环境一致性:确保脚本在Cron中的执行环境与手动执行一致
- 日志可追溯:详细记录封禁操作和IP信息,便于安全审计
- 弹性设计:通过临时目录和备份策略避免文件残留和日志膨胀
实际部署时,建议根据业务需求调整失败次数阈值(THRESHOLD
)和定时任务频率。
文章版权声明:除非注明,否则均为柳三千运维录原创文章,转载或复制请以超链接形式并注明出处。