应先用tail+awk分析日志识别高频IP及随机路径,再结合netstat查并发连接、宝塔拦截记录和User-Agent指纹确认是否为恶意扫描,而非仅凭404误判。

宝塔面板被恶意扫描拖垮服务器,光靠“封IP”没用,得先确认是不是真被扫——很多502、CPU飙高其实是PHP慢脚本或Redis被清库导致的假象。
怎么确认是恶意扫描不是其他问题
别一看到访问日志里一堆404就断定是扫描。先查真实攻击特征:
- 用
tail -n 1000 /www/wwwlogs/your-site.com/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -20看哪些IP请求最多;如果单个IP每秒几十次且路径随机(如/phpmyadmin/、/wp-admin/setup-config.php),基本可判为扫描 - 检查
netstat -an | grep :80 | grep ESTABLISHED | wc -l,若远超正常并发(比如 >500),但ps aux | grep 'php-fpm:' | wc -l却只有十几,说明大量连接卡在Nginx层,大概率是CC类扫描 - 看宝塔「安全 → 防火墙」里「今日拦截记录」,如果同一IP反复触发「目录遍历」「SQL注入特征」等规则,就是典型扫描行为
宝塔防火墙黑名单不生效的常见原因
很多人加了IP进黑名单却还在被扫,问题往往出在链路顺序或配置遗漏:
- 黑名单只对「经过防火墙规则的流量」生效,如果你开了CDN或反向代理(如Nginx前置负载),真实IP会被替换成CDN节点IP,此时封错对象——必须在Nginx配置里加
real_ip_header X-Forwarded-For;并配set_real_ip_from段 - 宝塔防火墙默认只拦截「未匹配白名单的请求」,如果开了「IP白名单」但漏写了自己办公IP,连后台都打不开,更别说封别人
- 黑名单规则是「内存缓存」,重启服务器或宝塔服务后会丢失——必须点「安全 → 防火墙 → 黑名单 → 导出」备份,或改用fail2ban做持久化封禁
- 部分扫描器用代理池轮换IP,封单个IP意义不大;应配合「登录失败5次自动封锁」和「CC防护阈值调低至10次/60秒」
手动加黑名单IP的正确操作流程
别直接在防火墙界面点「添加」就完事,容易漏掉关键动作:
- 从
/www/wwwlogs/your-site.com/access.log提取高频恶意IP:awk '$9 ~ /^4/ {print $1}' /www/wwwlogs/your-site.com/access.log | sort | uniq -c | sort -nr | head -10 | awk '{print $2}' > /tmp/badips.txt - 进宝塔「安全 → 防火墙 → 黑名单」,粘贴IP(每行一个),勾选「同时封禁该IP所有端口」——否则只封80/443,攻击者可能转扫SSH或Redis
- 点击「保存」后,**必须点右上角「重载防火墙规则」**,否则配置不写入
iptables或firewalld - 验证是否生效:在服务器执行
iptables -L INPUT -n | grep "你的IP",能看到对应DROP规则才算成功
为什么建议用fail2ban替代纯黑名单
宝塔自带黑名单是静态的,而fail2ban能动态响应日志行为,更适合对抗扫描:
- 它监听Nginx的
access.log,一旦检测到某IP在1分钟内触发5次404+非白名单路径,自动调用iptables封10分钟 - 支持多 jail 配置:除了Nginx,还能同时监控SSH(
auth.log)、FTP、甚至PHP错误日志里的恶意函数调用 - 封禁记录写入
/var/log/fail2ban.log,比宝塔防火墙日志更详细,含触发规则名和原始日志行 - 安装后默认只开
sshd,要防Web扫描得手动启用nginx-badbots或自定义[nginx-404]jail,路径在/etc/fail2ban/jail.local
真正难的不是封IP,而是区分「扫描流量」和「合法爬虫」——比如百度蜘蛛带 User-Agent: Baiduspider 却大量404,不该封;而 sqlmap 或 dirsearch 的请求头里通常有明显指纹。盯紧日志里 User-Agent 和 Referer 字段,比盲目拉黑更有效。











