CoreDNS 测速插件 speedcheck
CoreDNS 测速插件 speedcheck
Name
coredns 上游可用性探测插件返回最快IP
speedcheck - 对上游返回的多个 IP 做探测并返回最快的一个 IP。
Description
speedcheck 拦截包含 A/AAAA 记录的 DNS 应答,对每个候选 IP 执行连通性探测(ICMP ping / TCP 连接 / HTTP 请求),从中选出最快的一个返回给客户端。
探测流程:
- 向上游转发请求,获取原始应答
- 从应答中提取 A/AAAA 记录的 IP 列表
- 并发探测所有 IP(受并发上限控制,默认最多 32 个)
- 根据
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,ipv4(优先 IPv6)。
| 值 | 含义 |
|---|---|
ipv6,ipv4 |
优先 IPv6,IPv6 全部失败时回落到 IPv4 |
ipv4,ipv6 |
优先 IPv4,IPv4 全部失败时回落到 IPv6 |
ipv4 |
仅使用 IPv4 |
ipv6 |
仅使用 IPv6 |
speed-ip-parallel
v4/v6 并发竞速模式(off / on / winner),默认 off。
开启后忽略 speed-ip-mode 的家族优先级,将所有 A/AAAA 的 IP 合并后并发探测。
| 值 | 含义 |
|---|---|
off |
关闭竞速,按 speed-ip-mode 的家族优先级分别测速 |
on |
并发竞速,请求 A 就测速 A 记录返回最快的 A,请求 AAAA 就测速 AAAA 返回最快的 AAAA |
winner |
AAAA 查询跨家族竞速:收集 AAAA + 向上游请求 A,合并竞速;v6 赢返回 AAAA,v4 赢返回 NOERROR(drop AAAA);A 查询与 on 行为一致 |
winner 模式行为:
- TypeA 查询:与
on相同,只测速 A 记录 - TypeAAAA 查询:收集 AAAA + 向上游请求 A,合并竞速;v6 赢返回最快 AAAA,v4 赢返回 NOERROR + 非 AAAA 记录(CNAME 等)
- 全部不通:回落到匹配查询类型的首个 IP
不通的 IP 处理:探测失败的 IP 直接跳过。on 模式仅测速同家族;winner 模式对 AAAA 查询做跨家族竞速。
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 竞速(on和winner模式均不生效)
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 | . { |
真正最快 IP 模式
使用 winner 模式,v4/v6 同时测速,真正最快的 IP 获胜。若获胜 IP 的家族与查询类型不同,返回空记录促使客户端回落:
1 | . { |
例如:客户端查询 A 记录,但 IPv6 的 443 端口响应更快,则返回空 A 记录,客户端会自动尝试 AAAA 查询获取 IPv6 地址。
Notes
- ICMP ping 需要
CAP_NET_RAW权限或 root 权限;缺少权限时 ping 探测会静默失败,不影响其他探测模式 http:443探测会并发尝试 HTTPS/1.x 和 HTTP/3(QUIC),取先成功的结果- 探测连接不复用,每次探测都是新建连接,以准确测量连接建立延迟
- 缓存按
域名+查询类型存储,过期条目在访问时自动清理 - 探测并发上限为 32 个 IP;超出时排队等待,防止协程爆炸
Download
编译好的二进制文件(含 speedcheck 插件):
https://github.com/qist/coredns-plugins-suite/releases
Build
- 拉取 CoreDNS 源码:
1 | git clone https://github.com/coredns/coredns.git |
- 在
plugin.cfg增加一行(建议放到cache:cache前面):
1 | # 使用 sed 自动添加到 cache:cache 前面 |
- 拉取 speedcheck 模块源码:
1 | cd coredns |
- 重新生成插件注册代码并编译:
1 | go generate |
交叉编译(Linux arm64):
1 | make -f Makefile.release release |