Shell实战:生产可用Web恶意IP自动检测脚本
Shell实战:生产可用Web恶意IP自动检测脚本
📌 前言
💡 运维痛点:网站突然卡顿、CPU 100%,多半是 CC/DOS 恶意IP高频访问。人工手动翻日志统计IP效率极低,攻击爆发后几小时才能发现,极易造成网站宕机。
本文提供一套直接上线生产、零第三方依赖的Shell巡检脚本,融合:文本三剑客awk/sort/uniq、if条件判断、命令替换、日志持久化、邮件告警全套语法。
全程零基础友好,复制粘贴跟着操作即可部署完成。
✅ 脚本完整实现能力
- 🟢 自动解析 Nginx/Apache 标准
access.log,提取所有客户端访问IP - 🟢 自动统计单IP当日访问总量,自动抓取访问频次最高IP
- 🟢 自定义攻击阈值(默认单IP访问超10000次判定恶意攻击)
- 🟢 攻击触发双留存:本地永久告警日志 + 自动发送邮件通知管理员
- 🟢 配合
crontab定时巡检,实现7×24小时无人值守安全监控 - 🟢 兼容 CentOS7 / Rocky Linux / RHEL 主流服务器系统
⚠️ 前置环境准备(必看,缺少任意一项脚本无法告警)
- 服务器提前部署
mailx + sendmail邮件服务 - 网站存在标准访问日志
access.log(Nginx默认路径/var/log/nginx/access.log) - 服务器外网可正常发送邮件,防火墙放行465 SMTP端口
- 基础操作:vim编辑文件、脚本赋权、crontab定时任务基础认知
一、核心前置知识点速学
1.1 日志统计流水线核心命令
执行流程文字图示(纯文本,全平台兼容)
读取access.log日志 → awk提取第一列IP → sort -n IP排序 → uniq -c 统计每个IP访问次数 → sort -rn 按访问次数倒序 → head -1 取出访问最高IP
完整流水线代码:
awk '{print $1}' /var/log/nginx/access.log | sort -n | uniq -c | sort -rn | head -1
逐段功能拆解:
awk '{print $1}' access.log:提取日志第一列客户端IPsort -n:IP数字排序,重点:uniq统计前必须排序,否则统计失效uniq -c:统计重复IP访问次数,输出格式:访问次数 IP地址sort -rn:按访问次数从高到低倒序,攻击IP排在最上方head -1:仅保留访问量最高一行数据
1.2 命令替换变量语法
核心语法:变量名=$(命令),将命令输出结果存入变量,脚本3个核心变量:
# 获取本机服务器主机名
server_name=$(cat /etc/hostname)
# 抓取最高访问次数(uniq输出第一列$1)
max_conn=$(awk流水线 | awk '{print $1}')
# 抓取攻击IP地址(uniq输出第二列$2)
attack_ip=$(awk流水线 | awk '{print $2}')
1.3 阈值判断规则
使用整数比较参数 -gt(大于),判断逻辑:if [ 最高访问次数 -gt 阈值 ] → 判定恶意攻击,触发邮件告警
- 小型站点推荐阈值:
5000 - 中型站点默认阈值:
10000 - 高并发业务阈值:
30000
1.4 配套工具功能速查表
| 命令 | 作用 | 脚本用途 |
|---|---|---|
date +%y年%m月%d日%H时%M分%S秒 |
生成中文时间戳 | 告警日志记录攻击发生时间 |
>> |
追加写入文件 | 永久保存告警记录,不覆盖历史日志 |
mail -s "标题" 邮箱 |
发送系统邮件 | 攻击时推送告警给管理员 |
二、完整生产可用脚本 anti_dos_ip.sh
📝 脚本说明:所有可修改配置统一放在顶部,零基础无需改动下方逻辑代码,直接修改顶部变量即可适配自己服务器。
#!/bin/bash
# ==============================================
# 脚本名称:anti_dos_ip.sh
# 功能:自动检测Web访问日志恶意高频IP,超阈值日志记录+邮件告警
# 适用系统:CentOS / Rocky Linux
# 编写时间:2026-07-09
# ==============================================
########################### 【可自定义配置区域】###########################
# 🔹 网站访问日志路径,Nginx/Apache按需修改
LOG_PATH="/var/log/nginx/access.log"
# 🔹 告警日志持久化保存路径
WARN_LOG="/shell/log/anti-dos.log"
# 🔹 攻击访问阈值,超过该数值判定恶意IP
LIMIT_NUM=10000
# 🔹 管理员接收告警邮箱
ADMIN_MAIL="admin@189.cn"
##########################################################################
# 1. 自动创建日志目录,不存在则新建,避免写入报错
mkdir -p /shell/log/
# 2. 捕获基础信息存入变量
now_time=$(date +%y年%m月%d日%H时%M分%S秒) # 中文时间戳
server_name=$(cat /etc/hostname) # 服务器主机名
# 3. 日志统计流水线:提取IP、统计次数、取最高访问IP
ip_stat=$(awk '{print $1}' ${LOG_PATH} | sort -n | uniq -c | sort -rn | head -1)
# 拆分访问次数、攻击IP为独立变量
max_conn=$(echo ${ip_stat} | awk '{print $1}')
attack_ip=$(echo ${ip_stat} | awk '{print $2}')
# 4. 阈值条件判断逻辑
if [ ${max_conn} -gt ${LIMIT_NUM} ]; then
# 组装完整告警文本
warn_info="【攻击告警】服务器:${server_name} | 时间:${now_time} | 恶意IP:${attack_ip} | 当日访问次数:${max_conn},单IP访问超过阈值${LIMIT_NUM},疑似DOS/CC攻击!"
# 写入本地告警日志
echo ${warn_info} >> ${WARN_LOG}
# 终端打印告警,手动执行时直观查看
echo ${warn_info}
# 发送告警邮件通知管理员
echo ${warn_info} | mail -s "【紧急】服务器遭遇高频IP攻击告警" ${ADMIN_MAIL}
else
# 无攻击时,记录正常巡检日志(不需要可删除本段)
echo "【正常巡检】${now_time} 服务器${server_name}无异常IP,最高访问IP:${attack_ip},访问次数${max_conn}" >> ${WARN_LOG}
fi
2.1 分模块代码图示讲解(纯文字标注,替代图片图示)
模块① 头部自定义配置区
作用:
#!/bin/bash:指定Bash解释器,脚本运行必备头部标识;- 全部可变参数集中放置,新手只需要修改这一块,不用改动业务逻辑;
修改示例:Apache日志只需替换LOG_PATH="/var/log/httpd/access_log"
模块② 自动创建日志目录
mkdir -p /shell/log/
✅ 运行效果:目录不存在自动创建,已存在不会抛出报错,防止日志写入失败。
模块③ 基础信息变量捕获
now_time=$(date +%y年%m月%d日%H时%M分%S秒)
server_name=$(cat /etc/hostname)
输出示例:now_time=26年07月09日16时22分30秒
多服务器集群场景,通过主机名快速区分哪台机器发生攻击。
模块④ 核心IP统计流水线
ip_stat=$(awk '{print $1}' ${LOG_PATH} | sort -n | uniq -c | sort -rn | head -1)
max_conn=$(echo ${ip_stat} | awk '{print $1}')
attack_ip=$(echo ${ip_stat} | awk '{print $2}')
执行前后对比:
- 执行前:access.log 成千上百行杂乱访问日志
- 执行后输出示例:
12650 110.23.45.67
拆分结果:max_conn=12650(访问次数),attack_ip=110.23.45.67(攻击IP)
模块⑤ if阈值判断+告警逻辑
if [ ${max_conn} -gt ${LIMIT_NUM} ]; then
# 告警逻辑
else
# 正常巡检记录
fi
⚠️ 重点避坑:[ ] 括号左右内侧必须保留空格,少空格直接脚本报错!
>>追加写入日志:历史告警永久保存,用于事后溯源;- 邮件标题带【紧急】标识,管理员可第一时间识别高危告警。
三、零基础完整部署步骤(分步图标注,新手跟着复制)
步骤1:创建脚本文件 📄
打开服务器终端,执行命令创建脚本
vim anti_dos_ip.sh
粘贴完整脚本代码,按 ESC,输入 :wq 保存退出。
步骤2:赋予脚本执行权限 🔐
Linux新建文本默认无执行权限,直接运行会报 Permission denied
chmod +x anti_dos_ip.sh
步骤3:手动测试脚本,验证功能 🧪
./anti_dos_ip.sh
两种运行结果区分:
- 🟢 正常无攻击:终端无告警输出,日志文件写入正常巡检记录;
- 🔴 存在恶意IP:终端打印告警文本,本地日志留存记录,管理员邮箱收到告警邮件。
步骤4:查看历史告警日志 📋
cat /shell/log/anti-dos.log
可查看全部巡检、攻击记录,攻击事件溯源必备。
步骤5:配置定时任务,生产自动巡检 ⏰
手动执行仅用于测试,生产环境配置定时任务,每小时自动巡检一次
- 编辑定时任务列表
crontab -e
- 写入定时规则(每小时整点执行)
0 * * * * /shell/anti_dos_ip.sh
- 查看已配置定时任务
crontab -l
定时格式说明:分 时 日 月 周,0 * * * * = 每小时0分自动运行脚本
四、生产环境避坑指南
❌ 高频踩坑点+解决方案
-
日志路径错误,无法统计IP
解决:核对Nginx/Apache真实日志路径,修改脚本顶部LOG_PATH变量 -
收不到告警邮件
解决:提前部署mailx+sendmail,邮箱开启POP3/SMTP并获取授权码,防火墙放行465端口 -
脚本执行报括号语法错误
解决:[ 变量 -gt 数值 ]括号内侧左右必须留空格,无空格直接崩溃 -
定时任务不自动执行
解决:脚本使用绝对路径,提前执行chmod +x授权,定时任务缺少终端环境变量 -
告警日志持续膨胀占满磁盘
增加日志自动清理代码,放在脚本最底部:
# 自动删除30天前告警日志
find /shell/log -name "anti-dos.log" -mtime +30 -delete
五、脚本生产升级拓展方案 🚀
二次开发扩展功能,按需添加:
- 自动防火墙拉黑恶意IP:识别攻击IP后通过firewalld/iptables永久封禁IP,阻断流量;
- 多渠道告警:新增钉钉/企业微信机器人推送,不局限邮件通知;
- 告警防抖:1小时内同一IP重复攻击仅推送1次邮件,避免消息轰炸;
- 日志按日期分割:每日生成独立告警日志,防止单文件过大;
- 服务联动监控:搭配netstat检测Nginx服务,服务宕机同步推送故障告警。
六、全文总结
本案例是一套轻量化、零成本、开箱即用的服务器安全自动化脚本,无复杂第三方组件,零基础运维、后端开发、在校学生均可快速部署落地。
脚本整合文本三剑客、变量、条件判断、输出重定向、邮件告警、定时任务全套Shell核心知识点,全部落地真实生产安全场景。学会后可直接复用在服务器巡检工作中,替代人工手动分析日志,提前拦截CC/DOS攻击,大幅降低网站宕机风险。
更多推荐

所有评论(0)