用tac+awk筛选近2分钟高频ip,结合请求路径、状态码及多日志比对确认攻击;宝塔防火墙仅限http层,系统级封禁需iptables或ipset并持久化。

怎么看 Nginx access.log 里谁在疯狂刷你?
宝塔面板默认把 Nginx 访问日志存在 /www/wwwlogs/your_site_name.log,攻击者留下的最直接痕迹就是短时间大量请求——不是正常用户行为,而是扫描器、爆破脚本或 CC 攻击的节奏。
别直接打开大文件硬看,容易卡死。用命令快速筛出高频 IP:
tac /www/wwwlogs/your_site_name.log | awk -v st="$(date -d '2 minutes ago' '+%d/%b/%Y:%H:%M:%S')" '$4 ~ /\[.*\]/ && substr($4,2,15) >= st {print $2}' | sort | uniq -c | sort -nr | head -n 20-
tac是倒序读日志(新日志在最后),比cat配grep快得多;substr($4,2,15)提取时间字段前 15 位,刚好够比对分钟级精度 - 注意:日志时间格式必须是
DD/Mon/YYYY:HH:MM:SS(Nginx 默认),如果服务器时区不对,date命令输出会错位,导致漏筛 - 结果第一列是次数,第二列是 IP,比如
327 203.0.113.45就值得立刻盯住
怎么确认某个 IP 是真攻击,不是 CDN 或爬虫?
光看请求数不够,得结合请求内容和状态码交叉验证。真实攻击往往伴随大量 404、400 或 500,且路径可疑。
- 查该 IP 的全部请求记录:
grep '203.0.113.45' /www/wwwlogs/your_site_name.log | head -n 10 - 重点看
$6(HTTP 方法)和$7(URI),攻击常见特征:GET /phpmyadmin/、POST /wp-login.php、GET /shell.php、含UNION SELECT或eval(的 query 参数 - 如果 IP 来自阿里云、腾讯云的 CVM 内网段(如
100.64.0.0/10、10.0.0.0/8),大概率是同机房扫描器,不是真实用户 - 如果用了 CDN(如 Cloudflare),
$2显示的是 CDN 节点 IP,得看$http_x_forwarded_for字段——但前提是 Nginx 配置里开了log_format记录它,否则无解
封 IP 前先查它有没有扫过其他站?
单个站点日志只反映局部行为。一个恶意 IP 很可能同时打你、隔壁 WordPress、还有测试 phpMyAdmin,跨日志比对能提高判断置信度。
- 进宝塔【文件】管理器,打开所有网站的日志目录:
/www/wwwlogs/,用终端批量查:grep -h '203.0.113.45' /www/wwwlogs/*.log | awk '{print $7}' | sort | uniq -c | sort -nr - 如果发现它反复访问
/admin/、/manager/html、/cgi-bin/这类通用后台路径,基本可判为自动化扫描器 - 注意:宝塔自带防火墙的“IP 黑名单”只拦 HTTP 流量,不拦 SSH 或 MySQL 端口。若该 IP 同时出现在
/var/log/secure的失败登录记录里(grep 'Failed password' /var/log/secure | grep 203.0.113.45),说明已在尝试暴力破解系统账户,必须升级到iptables全端口封禁
为什么直接在宝塔防火墙封 IP 有时没用?
宝塔防火墙本质是 Web 层规则,依赖 Nginx 的 limit_req 或模块拦截,而真正的攻击流量可能绕过它——尤其是当攻击者伪造 Host 头、或利用 Nginx 配置漏洞(如 7.9.6 及以下版本挂马事件)时。
- 封完后立刻验证:
curl -x 203.0.113.45:80 http://your-domain.com不行,得用真实网络环境测(比如手机切流量再访问) - 更可靠的封法是走系统层:
iptables -I INPUT -s 203.0.113.45 -j DROP,但要注意:CentOS 7 默认用firewalld,直接写iptables规则重启会丢失,得先systemctl stop firewalld && systemctl disable firewalld - 如果用了
ipset批量封,记得开机自动加载:echo "ipset restore > /etc/rc.local,否则重启后全失效
日志是证据链的起点,但不是终点。同一个 IP 可能今天扫目录,明天换 UA 继续爆破,盯着它在 auth.log、nginx log、mysql error.log 里是否多点出现,比单次封禁更重要。











