CoreDNS 测速插件 speedcheck

CoreDNS 测速插件 speedcheck

Name

coredns 上游可用性探测插件返回最快IP

speedcheck - 对上游返回的多个 IP 做探测并返回最快的一个 IP。

Description

speedcheck 会对上游返回的多个 A/AAAA 记录做连通性/速度探测,然后把应答收敛为“最快的一个 IP”。

speed-check-mode 包含 ping 时,排序依据使用 ping 延迟;否则使用第一个成功探测项的耗时。

Syntax

1
2
3
4
5
6
7
8
9
10
11
speedcheck {
speed-check-mode ping,tcp:80,tcp:443
speed-timeout-mode 3s
speed-check-parallel off
speed-cache-ttl 30s
speed-ip-mode ipv4,ipv6
speed-ip-parallel off
speed-host-override www.google.com|tcp:443,http:443|ipv4,ipv6
check_http_send "HEAD / HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\n\r\n"
check_http_expect_alive http_2xx http_3xx http_4xx
}
  • speed-check-mode:探测模式(none / ping / tcp:<port> / http:<port>
    • 如果包含 ping:先做一次 ping;如果 ping 成功则该 IP 成功(会继续尝试 tcp/http,但 tcp/http 全失败时仍会按 ping 成功处理);如果 ping 不通,则继续按配置顺序尝试 tcp/http,其中任意一个成功即短路;如果 ping 与所有 tcp/http 都失败则该 IP 失败
    • 如果仅配置 ping(没有任何 tcp/http):就只做 ping 探测
    • 如果不包含 ping:直接按配置顺序尝试 tcp/http,其中任意一个成功即短路
  • speed-timeout-mode:探测超时时间,默认 2s
  • speed-check-parallel:是否并发执行同一 IP 的 tcp/http 探测(on / off),默认 off;开启后会在任意一个 tcp/http 成功时短路返回
  • speed-cache-ttl:缓存探测结果的时间(按域名与查询类型缓存),默认 0(关闭)
  • speed-ip-mode:IP 家族优先级(ipv4,ipv6 / ipv6,ipv4 / ipv4 / ipv6 / 不配置默认 ipv6,ipv4
  • speed-ip-parallel:是否并发竞速 v4/v6(on / off),默认 off;开启后忽略 speed-ip-mode 的家族优先级,返回最先探测成功的 IP;当查询类型为 AAAA 且 v4 获胜时会返回空 AAAA(促使客户端回落使用 A)
  • 回落:当所有 IP 的探测都失败时,如果同时存在 IPv4/IPv6,则优先回落返回 IPv4
  • speed-host-override:按域名覆盖探测与 IP 家族选择(可配置多条,后写覆盖前写)
    • 推荐语法(避免 <check-mode> 里包含逗号导致拆分歧义):
      • speed-host-override <host>|<check-mode>|<ip-mode>
      • 示例:speed-host-override www.google.com|tcp:443,http:443|ipv4,ipv6
    • 兼容语法(不推荐用于多探测项):
      • speed-host-override <host>,<check-mode>,<ip-mode>speed-host-override <host> <check-mode> <ip-mode>
      • 示例:speed-host-override rrs04.hw.gmcc.net,tcp:8088,ipv4
    • <check-mode>:语法与 speed-check-mode 相同(none/ping/tcp:<port>/http:<port>,可用逗号组合)
    • <ip-mode>
      • 仅单一 IP 家族:ipv4 / ipv6(也支持 v4 / v6
      • 允许 v4+v6 并按顺序偏好:ipv4,ipv6ipv6,ipv4(第一个为偏好,第二个为兜底)
    • 命中后会使用该域名专属的 check-mode 与 ip 家族选择,并禁用 speed-ip-parallel 的 v4/v6 竞速与 AAAA-race
    • ipv4 时:对 AAAA 查询直接返回空 AAAA(促使客户端回落使用 A);仅 ipv6 时:对 A 查询返回空 A
    • ipv4,ipv6ipv6,ipv4 时:会先按偏好家族探测;偏好家族探测成功则返回空(促使客户端用另一查询类型拿到偏好家族结果);偏好失败但兜底成功则允许回落到兜底家族
  • check_http_send:自定义 HTTP/1.x 探测报文;其中 {host} / {HOST} 会替换为当前 DNS 查询域名;默认 GET / HTTP/1.0\r\n\r\n
  • check_http_expect_alive:HTTP 探测可接受的状态码分类(http_2xx/http_3xx/http_4xx/http_5xx/http_all

Examples

最小示例(server 可启动):

1
2
3
4
5
6
7
8
9
10
11
. {
speedcheck {
speed-check-mode ping,tcp:80,tcp:443
speed-timeout-mode 3s
speed-cache-ttl 30s
speed-ip-mode ipv6,ipv4
check_http_send "HEAD / HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\n\r\n"
check_http_expect_alive http_2xx http_3xx http_4xx
}
whoami
}

HTTP 探测(http:443 会并发尝试 HTTPS/1.x 与 HTTP/3,取更快的一个):

1
2
3
4
5
6
7
8
. {
speedcheck {
speed-check-mode ping,http:80,http:443
speed-timeout-mode 2s
check_http_expect_alive http_2xx http_3xx
}
whoami
}

Build

下面以远程仓库方式把 speedcheck 模块集成进 CoreDNS 并编译。

  1. 拉取 CoreDNS 源码:
1
2
git clone https://github.com/coredns/coredns.git
cd coredns
  1. plugin.cfg 增加一行(放在你希望的执行顺序位置;顺序会影响执行链建议放到cache:cache 前面):
1
speedcheck:github.com/qist/speedcheck
  1. 拉取 speedcheck 模块源码(两种方式任选其一):
  • 方式 A:让 Go 自动拉取(推荐)
1
2
3
go get github.com/qist/speedcheck@latest
更新到最新代码
go get -u github.com/qist/speedcheck@latest
  • 方式 B:手动 clone(用于固定版本或离线环境)
1
2
cd coredns
git clone https://github.com/qist/speedcheck.git plugin/speedcheck
  1. 重新生成插件注册代码并编译:
1
2
go generate coredns.go
make

交叉编译(Linux arm64):

1
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o coredns-linux-arm64