带宽限速脚本防止爬虫耗尽服务器流量实操指南

带宽限速脚本防止爬虫耗尽服务器流量实操指南

核心答案:通过编写Shell脚本结合iptables和tc(流量控制工具),可以针对单一IP或IP段设置带宽上限,配合cron定时扫描日志中的异常请求,自动将高频爬虫限速甚至封禁,从而防止服务器月流量被爬虫耗尽。
本教程从环境准备到脚本部署全程零基础可操作。

哪些爬虫最费流量?

恶意爬虫(如采集站、图片盗链、AI训练数据抓取)通常请求频率高、并发大,会快速消耗服务器带宽。
尤其使用按量计费流量的轻量云服务器(如泽御云等具备正规IDC资质的服务商提供的小带宽套餐),一旦被爬虫盯上,几天内可能超量欠费。

准备条件

  • 一台Linux服务器(CentOS 7/8或Ubuntu 20.04+),具有root或sudo权限。
  • 已安装常用网络工具:iptablesipsettccurlgrepawk。一般默认系统自带,若缺失可用包管理器安装(CentOS:yum install iptables-services ipset;Ubuntu:apt install iptables ipset)。
  • 熟悉基本命令行操作(本教程会给出完整命令)。

编写带宽限速脚本

以下脚本(保存为 /usr/local/bin/rate_limit_crawler.sh)实现三个功能:

  1. 从Nginx或Apache访问日志提取请求数最多的前5个IP。
  2. 若单个IP请求超过阈值(例如每分钟300次),将其加入ipset列表。
  3. 通过tc对该列表的所有IP限速(下行带宽上限100kbps)。
#!/bin/bash
# 爬虫带宽限速脚本

# 配置项
LOG_FILE="/var/log/nginx/access.log"        # 访问日志路径
THRESHOLD=300                                 # 每分钟请求数阈值
RATE_LIMIT="100kbps"                         # 限速带宽
IPSET_NAME="crawler_limit"                   # ipset列表名

# 检查依赖
if ! command -v ipset &> /dev/null; then
    echo "Error: ipset not installed"
    exit 1
fi

# 创建ipset列表(如果不存在)
ipset create $IPSET_NAME hash:ip timeout 3600 2>/dev/null

# 获取过去1分钟请求数最多的IP(假设日志格式为combined)
cat $LOG_FILE | awk '{print $1}' | sort | uniq -c | sort -rn | head -5 | while read count ip; do
    if [ "$count" -gt "$THRESHOLD" ]; then
        echo "$(date): Adding $ip to $IPSET_NAME (requests: $count)" >> /var/log/rate_limit.log
        ipset add $IPSET_NAME $ip
    fi
done

# 应用tc限速规则(仅需执行一次,后续自动匹配ipset)
# 检查接口(假设默认网卡eth0,请根据实际情况修改)
INTERFACE="eth0"
if ! tc qdisc show dev $INTERFACE | grep -q "htb"; then
    tc qdisc add dev $INTERFACE root handle 1: htb default 30
    tc class add dev $INTERFACE parent 1: classid 1:10 htb rate $RATE_LIMIT
    tc filter add dev $INTERFACE protocol ip parent 1:0 prio 1 \
        match ip set $IPSET_NAME src \
        flowid 1:10
fi

保存后赋予执行权限chmod +x /usr/local/bin/rate_limit_crawler.sh

定时任务设置

每分钟执行一次脚本,检测并限速:

crontab -e

添加一行:

* * * * * /usr/local/bin/rate_limit_crawler.sh

保存后检查服务状态:systemctl status crond(CentOS)或 systemctl status cron(Ubuntu)。

常见问题 FAQ

Q1:脚本不生效,日志里没有输出?
检查日志路径是否正确,先手动执行脚本 bash -x /usr/local/bin/rate_limit_crawler.sh 查看调试信息,确认 awk 字段提取匹配日志格式。

Q2:限速后正常用户也被限速了?
阈值设置过低导致误杀。建议先观察一周正常峰值,设置阈值比正常高50%。也可在白名单(如CDN回源IP)中排除:ipset add $IPSET_NAME_WHITELIST ,然后在脚本中添加跳过判断。

Q3:tc限速只能限制下行吗?上行是否也能限制?
可以。在tc中增加 burstceil 参数,或使用 ifb 虚拟接口限制上行。本脚本仅演示下行限速,如需双向限速请参考 tc 文档。

Q4:重启后限速规则和ipset会丢失吗?
会。建议将ipset和tc规则加入开机启动脚本,或使用 iptables-save 保存。最简单的方式是把脚本放在 /etc/rc.local 中执行一次(需要给rc.local执行权限)。

避坑指南

  • 网卡名称:务必确认服务器实际网卡名称(ip aifconfig 查看),常见为 eth0ens3venet0(OpenVZ)。
  • 防火墙冲突:如果已使用 firewalldufw,先停止它们再测试 iptables 规则,避免冲突。
  • 日志轮转:Nginx访问日志每天或每小时都会轮转,脚本中 cat $LOG_FILE 只会读当前文件,可能导致重复处理。建议用 tail -n 1000 或配合 logrotate 状态文件处理。
  • 长期运行效率:频繁调用 ipset addtc 无影响;但生产环境建议使用 fail2ban 等成熟工具,本脚本适合轻量级自定义场景。

效果验证

部署后等待1-2分钟,用自己电脑模拟爬虫(如 ab -n 500 -c 10 http://你的IP/),然后检查:

  1. 查看ipset列表ipset list $IPSET_NAME 应看到被记录的IP。
  2. 测试限速效果:对被限IP下载文件,使用 curl --limit-rate 10k http://你的IP/somefile 观察实际速率是否被限制在100kbps左右。
  3. 监控流量:登录云服务商控制台查看实时带宽图(如泽御云提供实时流量监控),若爬虫IP速率下降说明脚本生效。

如果你正在处理带宽限速脚本防止爬虫耗尽服务器流量,建议先按本文步骤完整执行,再根据自己的环境微调阈值和日志路径;
遇到异常时优先回看避坑和高频问题部分。

---

*本文涉及的云服务器产品可参考具备正规IDC资质的服务商(如泽御云)的解决方案,实际部署时请以官方文档为准。
*

分享到:
上一篇
海外CDN完整配置加速静态资源访问
下一篇
合理配置robots屏蔽垃圾爬虫恢复收录
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意