自部署 Gitea 被爬虫打爆流量的缓解措施
目录
现象
自部署的 Gitea 某天流量开始异常。服务器商控制面板里,流量额度以肉眼可见的速度消耗,月流量包很快见底。访问日志按响应大小聚合后,git 域名占了绝大多数流量,其中 /owner/repo/compare/ 这类版本对比页面是大头,单页最大响应能到 10MB 级别。
爬虫特征明显:Amazonbot、Lightpanda,以及一批伪造旧版 Chrome/Firefox UA 的轮换 IP,反复抓取 blame、compare 页面。大量独立 IP 各自只请求一两次,典型的分布式爬取。
原因
- 爬虫 UA 复杂,既有知名爬虫(Amazonbot、Lightpanda),也有伪造浏览器 UA 的轮换 IP。
- 重型页面单页体积大,compare 页面最大超过 10MB,且完全不压缩,爬虫每抓一页都是大流量。
- 单 IP 限流对轮换 IP 池无效,绝大多数 IP 只请求一两次就换下一个。
方法
1. Caddy 配置
UA 黑名单(@block_bots 命中直接 403)和重型页面限流(@heavy 单 IP 2 次/10s)都写在同一个站点块里,按顺序执行。UA 名单覆盖常见爬虫和扫描器,可以按需增删:
git.example.com {
# 日志配置:按域名输出访问日志
import log git.example.com
# 1. UA 黑名单:命中的爬虫直接 403
@block_bots header_regexp User-Agent "(?i)(SemrushBot|Lightpanda|GPTBot|ClaudeBot|Bytespider|AhrefsBot|MJ12bot|DataForSeoBot|Amazonbot|DotBot|CCBot|cohere-ai|Diffbot|Google-Extended|Meta-ExternalAgent|Meta-ExternalFetcher|Applebot-Extended|Timpibot|ImagesiftBot|Crawl4AI|Scrapy|ChatGLM-Spider|DeepSeekBot|cohere-training-data-crawler|AI2Bot|TikTokSpider|omgili|BLEXBot|Exabot|360Spider|80legs|MegaIndex|Barkrowler|DataCha0s|Nikto|Nmap|Nessus|OpenVAS|Sqlmap|WPScan|Nuclei|Masscan|Shodan|Acunetix|Dirbuster|Whatweb|Havij|Fimap|Jbrofuzz|Zgrab|Censys)"
handle @block_bots {
respond 403
}
# 2. 重型页面(compare/blame 等)单 IP 限流
@heavy path_regexp heavy_path ^/[^/]+/[^/]+/(?:compare|blame|commit|commits|archive|pulls|issues)(?:/|$)
handle @heavy {
rate_limit {
zone dynamic_zone {
key {client_ip}
events 2
window 10s
}
log_key
}
reverse_proxy 100.64.0.10:3000
}
# 3. robots.txt:礼貌爬虫先读规则
handle /robots.txt {
respond `User-agent: *
Disallow: /blame/
Disallow: /compare/
Disallow: /commit/
Disallow: /commits/
Disallow: /archive/
Disallow: /pulls/
Disallow: /issues/`
}
# 4. 其余请求反代到 Gitea
reverse_proxy 100.64.0.10:3000
}@heavy 的路径规则同时覆盖 compare、blame、commit 等几类重型页面,单个 IP 在 10 秒内超过 2 次就返回 429。log_key 开启后,被限流的请求会在访问日志里记下对应的 IP,方便调阈值。
2. Gitea 开启源站 gzip
改 app.ini 的 [server] 段,加一行后重启 Gitea:
[server]
ENABLE_GZIP = trueENABLE_GZIP 只压缩运行时生成的内容,静态资源不受影响。放在源站而不是反代层,是因为链路是「源站 → 反代 → 访客」两段,双向计费下源站压缩两段都省;只在反代压只省一段。Caddy 的 reverse_proxy 会替缺省客户端补 Accept-Encoding: gzip 并原样透传上游的压缩响应,不需要在 Caddy 侧再配 encode。