由于使用Nginx时就有很多需求:拦截 AI 爬虫、扫描器、CONNECT 代理、屏蔽 xmlrpc、禁止 IP 访问、屏蔽恶意 UA,那么使用Caddy如何全部原生实现呢?以下分享一下Caddy使用技巧。
一、最简通用爬虫拦截(推荐,复制即用)
1. caddyfile定义恶意爬虫匹配器(包含我之前 Nginx 拉黑列表)
# 恶意AI爬虫、采集爬虫、扫描器UA黑名单
@badBot header_regexp User-Agent (?i)(DotBot|Amazonbot|ClaudeBot|DataForSeoBot|PerplexityBot|MJ12bot|CyberConvoyScout|SemrushBot|CensysInspect|Turnitin|GPTBot|CCBot|anthropic-ai|Bytespider|scrapy|python|curl|wget|masscan|nmap)
# 拦截CONNECT代理请求(对应你日志里的 CONNECT www.baidu.com:443)
@connectReq method CONNECT
# 拦截WordPress xmlrpc暴力爆破
@xmlrpc path /xmlrpc.php
# 统一拦截,直接断开连接(等同于Nginx return 444,不返回页面、不打多余日志)
abort @badBot
abort @connectReq
abort @xmlrpc
abort:直接关闭 TCP 连接,零返回,消耗攻击者带宽,性能最优header_regexp (?i):不区分大小写匹配 UA
二、完整 WordPress 站点可直接套用模板(www.58jb.com)
以下配置可以根据自己实际情况及需求修改调试使用。
# 全局通用安全片段,可多站点复用
(safe_block) {
# 拦截垃圾爬虫
@badBot header_regexp User-Agent (?i)(DotBot|Amazonbot|ClaudeBot|DataForSeoBot|PerplexityBot|MJ12bot|CyberConvoyScout|SemrushBot|CensysInspect|Turnitin|GPTBot|CCBot|anthropic-ai|Bytespider|scrapy|python|curl|wget|masscan|nmap)
@connectReq method CONNECT
@xmlrpc path /xmlrpc.php
abort @badBot
abort @connectReq
abort @xmlrpc
# 安全响应头
header Strict-Transport-Security "max-age=31536000; includeSubDomains"
header X-XSS-Protection "1; mode=block"
header X-Content-Type-Options nosniff
header X-Frame-Options SAMEORIGIN
header -Server # 隐藏Caddy版本号
}
# 禁止IP直接访问(default站点,匹配所有未绑定域名/IP)
:80, :443 {
import safe_block
abort # 访问IP直接断连
}
# 你的主站 www.58jb.com
www.58jb.com {
import safe_block # 导入爬虫拦截规则
root * /var/www/html/wordpress
php_fastcgi unix//run/php/php8.5-fpm.sock
# HTTP跳转HTTPS
redir https://{host}{uri} permanent
# WordPress伪静态
try_files {path} {path}/ /index.php?{query}
# 静态资源缓存
@staticAssets path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.svg *.woff2 *.webp
header @staticAssets Cache-Control "public,max-age=2592000,immutable"
# 禁止访问隐藏文件 .env .git .ht
@hiddenFiles path */.*
respond @hiddenFiles 404
}
两种拦截策略对比
方案 A:abort(推荐,生产首选)
abort @badBot
- 行为:立刻断开 TCP 连接,无任何 HTTP 响应
- 优点:不产生返回包、不消耗服务器带宽、日志干净,防爬虫 / 扫描最优
- 等价 Nginx:
return 444
方案 B:respond 403(返回 403 页面)
respond @badBot 403
- 行为:返回标准 403 Forbidden 状态码
- 适用:需要明确返回错误码、统计拦截数量场景
caddyfile进阶用法
1. 区分好坏爬虫,放行正规搜索引擎
# 白名单正规爬虫
@goodBot header_regexp User-Agent (?i)(Googlebot|Bingbot|DuckDuckBot|Baiduspider)
# 先放行白名单,其余恶意爬虫拦截
route {
handle @goodBot {
# 正常访问,不拦截
}
handle {
@badBot header_regexp User-Agent (?i)(GPTBot|ClaudeBot|Bytespider|scrapy)
abort @badBot
}
}
2. 限制单 IP 请求频率(防爬虫高频抓取)
# 全局限流:单IP每秒最多10请求,突发缓冲5个
limit_req zone=ip burst=5 nodelay
3. caddyfile屏蔽指定 IP/IP 段爬虫扫描
@blockIp remote_ip 43.248.187.0/24
abort @blockIp
第三方增强插件(可选,大量站点推荐)
caddy_nobots_v2 爬虫专用模块
内置海量爬虫 UA 库,无需自己写正则,一键屏蔽,需重新编译 Caddy:
- 编译命令
xcaddy build --with github.com/mkalus/caddy_nobots_v2
- caddyfile配置示例
www.58jb.com {
nobots {
regexp "(GPTBot|ClaudeBot|Bytespider)"
show_hits true # 记录拦截日志
}
}
日志查看拦截效果
查看被拦截的爬虫请求:
# 查看caddy日志(Ubuntu默认路径)
tail -f /var/log/caddy/access.log | grep -E "abort|403"
重载配置生效
修改 Caddyfile 后执行:
sudo caddy reload
# 检查配置语法
sudo caddy validate