CoreDNS 测速插件 speedcheck
CoreDNS 测速插件 speedcheck
Name
coredns 上游可用性探测插件返回最快IP
speedcheck - 对上游返回的多个 IP 做探测并返回最快的一个 IP。
Description
speedcheck 拦截包含 A/AAAA 记录的 DNS 应答,对每个候选 IP 执行连通性探测(ICMP ping / TCP 连接 / HTTP 请求),从中选出最快的一个返回给客户端。
探测流程:
- 向上游转发请求,获取原始应答
- 从应答中提取 A/AAAA 记录的 IP 列表
- 并发探测所有 IP(受并发上限控制,默认最多 8 个)
- 根据
speed-ip-mode的家族偏好选择最优 IP - 将应答收敛为单个最优 IP 返回
当所有探测均失败时,优先回落到 IPv4 地址;若无 IPv4 则随机返回一个 IP。
Syntax
1 | speedcheck { |
speed-check-mode
探测模式,支持 none / ping / tcp:<port> / http:<port>,可用逗号组合多种模式。
- 包含
ping时:先做 ICMP ping;ping 成功则该 IP 视为成功(仍会继续尝试 tcp/http,但 tcp/http 全失败时仍按 ping 成功处理);ping 失败则继续尝试 tcp/http,任意一个成功即短路 - 仅配置
ping:只做 ICMP ping 探测 - 不包含
ping:按配置顺序尝试 tcp/http,任意一个成功即短路 - 配置为
none:禁用探测(仅在speed-host-override中有意义)
speed-timeout-mode
单次探测超时时间,默认 2s。
speed-check-parallel
是否并发执行同一 IP 的 tcp/http 探测(on / off),默认 off。
开启后所有 tcp/http 探测同时发起,任意一个成功即短路返回,适合目标端口响应差异较大的场景。
speed-cache-ttl
缓存探测结果的时间(按 域名+查询类型 缓存),默认 0(关闭)。过期条目在访问时自动清理。
speed-ip-mode
IP 家族优先级,默认 ipv6,ipv6(优先 IPv6)。
| 值 | 含义 |
|---|---|
ipv6,ipv6 |
优先 IPv6,IPv6 全部失败时回落到 IPv4 |
ipv4,ipv6 |
优先 IPv4,IPv4 全部失败时回落到 IPv6 |
ipv4 |
仅使用 IPv4 |
ipv6 |
仅使用 IPv6 |
speed-ip-parallel
是否并发竞速 v4/v6(on / off),默认 off。
开启后忽略 speed-ip-mode 的家族优先级,将所有 A/AAAA 的 IP 合并后并发探测,返回最先成功的 IP。当查询类型为 AAAA 且 IPv4 获胜时,返回空 AAAA(促使客户端回落使用 A 记录)。
speed-host-override
按域名覆盖探测模式与 IP 家族选择,可配置多条。支持精确匹配和泛域名匹配。
语法
推荐语法(管道分隔,避免逗号歧义):
1 | speed-host-override <host>|<check-mode>|<ip-mode> |
兼容语法(逗号或空格分隔,不推荐用于多探测项):
1 | speed-host-override <host>,<check-mode>,<ip-mode> |
泛域名
使用 * 前缀匹配所有子域名,逐级向上查找:
| 配置 | foo.example.com |
a.b.example.com |
example.com |
|---|---|---|---|
*.example.com |
匹配 | 匹配 | 不匹配 |
*.b.example.com |
不匹配 | 匹配 | 不匹配 |
精确匹配优先于泛域名匹配。
ip-mode 详解
| 值 | 行为 |
|---|---|
ipv4 / v4 |
仅保留 A 记录;AAAA 查询返回空(促使客户端回落) |
ipv6 / v6 |
仅保留 AAAA 记录;A 查询返回空 |
ipv4,ipv6 |
优先 IPv4,IPv4 失败时允许回落到 IPv6 |
ipv6,ipv4 |
优先 IPv6,IPv6 失败时允许回落到 IPv4 |
check-mode 为 none 时
不做任何探测,也不收敛多 IP 为单 IP,仅按 ip-mode 做 A/AAAA 的保留或清空。适用于强制客户端走指定协议家族的场景。
命中 override 后的行为
- 使用该域名专属的
check-mode与ip-mode - 禁用
speed-ip-parallel的 v4/v6 竞速
check_http_send
自定义 HTTP/1.x 探测报文。{host} / {HOST} 会被替换为当前 DNS 查询域名。默认值:
1 | GET / HTTP/1.0\r\n\r\n |
check_http_expect_alive
HTTP 探测可接受的状态码分类,可多选:
http_2xx/http_3xx/http_4xx/http_5xxhttp_all:接受所有状态码
默认接受所有状态码。
Examples
基础配置
1 | . { |
HTTP 探测
http:443 会并发尝试 HTTPS/1.x 与 HTTP/3,取更快的一个:
1 | . { |
泛域名覆盖
对所有 Google 域名强制 IPv4,对 CDN 域名使用 HTTP 探测:
1 | . { |
强制协议家族
对特定域名不做探测,仅强制使用 IPv4:
1 | . { |
并发竞速模式
开启 v4/v6 竞速,返回最快响应的 IP:
1 | . { |
Notes
- ICMP ping 需要
CAP_NET_RAW权限或 root 权限;缺少权限时 ping 探测会静默失败,不影响其他探测模式 http:443探测会并发尝试 HTTPS/1.x 和 HTTP/3(QUIC),取先成功的结果- 探测连接不复用,每次探测都是新建连接,以准确测量连接建立延迟
- 缓存按
域名+查询类型存储,过期条目在访问时自动清理 - 探测并发上限为 32 个 IP;超出时排队等待,防止协程爆炸
Build
- 拉取 CoreDNS 源码:
1 | git clone https://github.com/coredns/coredns.git |
- 在
plugin.cfg增加一行(建议放到cache:cache前面):
1 | speedcheck:github.com/qist/speedcheck |
- 拉取 speedcheck 模块源码(两种方式任选其一):
- 方式 A:Go 自动拉取(推荐)
1 | go get github.com/qist/speedcheck@latest |
- 方式 B:手动 clone(用于固定版本或离线环境)
1 | cd coredns |
- 重新生成插件注册代码并编译:
1 | go generate coredns.go |
交叉编译(Linux arm64):
1 | CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o coredns-linux-arm64 |