后端网络云原生【免费下载链接】corednsCoreDNS is a DNS server that chains plugins项目地址https://gitcode.com/gh_mirrors/co/coredns点击查看免费下载本指南以 CoreDNS 仓库中的 plugin/forward/README.md 为主体结合 forward.go、setup.go、policy.go 等源码展开。forward 是 CoreDNS 内置的核心转发插件负责把 DNS 请求代理到上游解析器并复用已建立的连接以支撑 UDP、TCP、DNS-over-TLSDoT、DNS-over-HTTPSDoH与 DNS-over-QUICDoQ多种传输。读完本文你将掌握 forward 的完整配置语法、健康检查与故障转移原理、超时与连接管理模型以及如何组合这些参数搭建一套生产可用的递归转发配置。插件定位DNS 消息转发代理forward的功能一句话概括将 DNS 消息代理proxying到上游解析器。与简单的每次新建连接的代理不同forward 会复用已经打开的到上游的 socket并原生支持四种上游传输协议明文 DNSUDP / TCPDNS-over-TLStls://DNS-over-HTTPShttps://即 DoHDNS-over-QUICquic://即 DoQ同时它使用带内in-band健康检查来感知上游可用性。当检测到某个上游出错时会触发一轮健康检查只要上游被判定为不健康健康检查就以0.5s 的间隔循环执行直到上游恢复健康为止。健康检查使用一条递归查询. IN NS探测上游任何非网络错误的响应如 REFUSED、NOTIMPL、SERVFAIL 等都被视为上游健康探测使用的协议与TO中指定的协议一致。从源码看这些默认行为在 forward.go 的常量中定义健康检查间隔hcInterval 500 * time.Millisecond连接过期时间defaultExpire 10 * time.Second读超时defaultReadTimeout 2 * time.SecondNew() 中还将默认maxfails设为 2、默认from设为.、默认 DoH 方法设为 POST。这些默认值在下方参数说明中会反复出现。基础语法forward FROM TO...最简单的转发配置只有一行forward FROM TO...FROM是要匹配并转发的基础域名。注意使用 CIDR 表示法、且会展开为多个反向 zone 的域名不被完整支持——只有展开后的第一个 zone 会被使用。这一行为在 setup.go 中由plugin.Host(f.from).NormalizeExact()展开后取zones[0]实现若展开出多个 zone 会打印一条Unsupported CIDR notation警告日志。TO...是目标端点列表语法支持显式协议前缀tls://9.9.9.9DoTquic://94.140.14.14DoQhttps://9.9.9.9DoH默认使用/dns-query路径不支持自定义路径——setup.go 会直接拒绝带路径的 HTTPS 上游地址dns://或省略协议明文 DNS上游数量上限为15常量max定义于 setup.go除了 IP 地址和文件如/etc/resolv.confTO 还可以是主机名如my-dns.svc.cluster.local。主机名在启动时解析为 IP 地址即使不带尾点也按绝对 DNS 名处理不会套用解析器的 search domain相关逻辑见下方resolver参数与 resolve.go 的实现。多个上游在首次使用时按policy默认random随机排序当一个健康的上游在交互中返回错误时会尝试列表中的下一个上游。扩展语法总览所有可选调优项都写在块内forward FROM TO... { except IGNORED_NAMES... force_tcp prefer_udp expire DURATION max_age DURATION max_idle_conns INTEGER read_timeout DURATION max_fails INTEGER max_connect_attempts INTEGER doh_method GET|POST tls CERT KEY CA tls_servername NAME policy random|round_robin|sequential health_check DURATION [no_rec] [domain FQDN] max_concurrent MAX next RCODE_1 [RCODE_2] [RCODE_3...] failfast_all_unhealthy_upstreams failover RCODE_1 [RCODE_2] [RCODE_3...] source_address IP resolver IP[:PORT] [IP[:PORT]...] }所有块内选项的解析集中在 setup.go 的parseBlock函数中遇到未知属性会直接返回配置错误。关键参数详解except排除不需要转发的域名except后跟空格分隔的排除域名列表请求若匹配其中任何一个则不转发由后续插件链继续处理。匹配逻辑实现在 forward.go 的isAllowedDomain中请求名与 FROM 完全相等时直接放行否则只要命中了任一忽略域就返回 false。force_tcp / prefer_udp传输偏好force_tcp即使请求从 UDP 进入也强制使用 TCP 与上游通信。prefer_udp即使请求从 TCP 进入也先尝试 UDP若响应被截断响应中 TC 标志置位则改用 TCP 再试一次。两者同时指定时force_tcp优先。这两个选项不会改变显式配置的 DoT、DoQ、DoH 上游传输。对应实现在 forward.goprefer_udp模式下若ret.Truncated !opts.ForceTCP opts.PreferUDP会置opts.ForceTCP true后重试。同时注意 setup.go开启force_tcp时明文 DNS/TCP 上游的健康检查也会被设置为 TCP 传输而 DoT/DoQ 健康检查本来就用各自的传输。max_fails判定上游宕机的失败阈值max_fails是连续健康检查失败多少次之后才把上游标记为 down。为 0 时上游永远不会被标记为 down也不会执行健康检查。默认值是 2。对应判断逻辑在 proxy.go 的Down(maxfails)maxfails 0时恒返回 false否则fails maxfails才视为 down。max_connect_attempts单请求的连接尝试上限max_connect_attempts限制单个传入 DNS 请求所执行的上游连接尝试总数。默认上限是配置上游数量的两倍即所有上游健康时可完整遍历两轮设为 0 表示取消按请求计数的上限。相关默认逻辑见 forward.go未显式设置时maxConnectAttempts defaultConnectAttemptsPerUpstream * len(list)defaultConnectAttemptsPerUpstream为 2见同文件常量区。expire / max_age / max_idle_conns连接复用管理expire缓存的连接在此时间后过期默认 10sforward.go。max_age连接的总生命周期到期后停止复用并替换连接。默认 0 表示不限制最大连接寿命若设置非 0 值则不得小于expire——setup.go 会在违反时直接报错max_age (...) must not be less than expire (...)。max_idle_conns每个上游按传输类型缓存的最大空闲连接数用于复用。默认 0 表示不限DoQ 会在每个上游的一条缓存连接上多路复用多个流。该值通过 proxy.go 下发到传输层同时也会设置 DoH HTTP Transport 的MaxIdleConns与MaxIdleConnsPerHost。read_timeout逐上游读超时read_timeout是等待每个上游响应的逐查询读超时默认 2s。如果上游合法响应时间可能超过 2s例如慢速递归解析否则会表现为 SERVFAIL/超时可调大该值。注意该超时按上游逐个生效过大的值会压缩单查询内重试其他上游的时间窗口。常量定义于 forward.go且解析时强制要求read_timeout为正数setup.go。tls客户端 TLS 配置tls CERT KEY CA定义 TLS 连接的属性可提供 0 到 3 个参数含义如下参数个数含义tls0 参不使用客户端认证用系统 CA校验服务器证书tls CA1 参不使用客户端认证用指定的 CA 文件校验服务器证书tls CERT KEY2 参使用指定 cert/key 对做客户端认证服务器证书用系统 CA 校验tls CERT KEY CA3 参客户端认证 用指定 CA 文件校验服务器证书CoreDNS 将 DoT 与 DoH 的最低 TLS 版本设置为TLS 1.2DoQ 按 QUIC 规范要求使用TLS 1.3。最高 TLS 版本、TLS 1.2 密码套件与密钥交换机制沿用 Gocrypto/tls默认值。解析逻辑在 setup.go通过pkgtls.NewTLSConfigFromArgs构建且相对路径会基于 Corefile 的 root 目录拼接。tls_servername 与按端点 SNItls_servername NAME用于在 TLS 配置中设置服务器名。例如 9.9.9.9 必须设为dns.quad9.net。使用 DoT、DoQ、DoH 且上游是 IP 地址、而其证书标识的是 DNS 名时强烈建议设置此项。还支持按目标端点指定 TLS SNI形式为tls://9.9.9.9%dns.quad9.net或quic://9.9.9.9%dns.quad9.net一旦使用端点级 SNI就不得再指定tls_servername否则会冲突——setup.go 会在两个层级的 servername 同时存在时直接报错。若端点需要非 853 端口端口要追加在端点说明符末尾如tls://9.9.9.9%dns.quad9.net:10853。端点级 SNI 的解析由 setup.go 的splitZone完成%之后为 zone冒号后为端口每个 SNI 会生成独立的tls.Config并配套tls.NewLRUClientSessionCache(proxyCount)以加速同服务器后续握手的会话复用。policy上游选择策略默认策略为random。可选random随机选择上游。实现在 policy.go对 1 个上游原样返回、2 个上游按随机奇偶交换、多个上游用随机排列rn.Perm打乱。round_robin轮询选择。实现见 policy.go用原子计数器取模轮转并把轮到的上游放到列表头部。sequential按配置顺序选择。实现见 policy.go直接原序返回。health_check健康检查行为health_check的完整语法为health_check DURATION [no_rec] [domain FQDN]duration自定义健康检查间隔默认 0.5s。例如设为5s可以避免高频探测把服务打爆README 的 DoT/DoQ/DoH 示例中均采用health_check 5s。no_rec可选参数将健康检查 DNS 查询的 RecursionDesired 标志置为false默认true。domain FQDN设置健康检查使用的域名未配置时默认使用.。默认健康检查查询即. IN NSRecursionDesiredtrue见 forward.go 的Options初值。按传输类型分派健康检查器的逻辑在 health.goDNS/DoT 用dnsHc、DoH 用dohHc、DoQ 用doqHc三种检查器构造探测报文的核心代码都类似ping.SetQuestion(h.domain, dns.TypeNS)与ping.RecursionDesired h.recursionDesired如 health.go并且只要拿到响应头m.Response || m.Opcode dns.OpcodeQuery就视为健康只有 I/O 类错误才会计入失败。max_concurrent并发上限与限流拒绝max_concurrent MAX限制并发查询数。任何会使并发数超过MAX的新查询都会收到REFUSED响应该拒绝不计入健康失败。取值建议至少大于预期的上游查询速率 × 上游延迟作为上限参考每个并发查询大约占用2kb 内存。实现位于 forward.go用原子计数器atomic.AddInt64(f.concurrent, 1)计数超限时返回dns.RcodeRefused并累加指标coredns_forward_max_concurrent_rejects_total见 metrics.go。next / next_on_nodata链式转发next当远程返回指定的 RCODE如NXDOMAIN时执行下一个插件。如果下一个插件不是 forward 插件或没有定义下一个插件该设置会被忽略。next_on_nodata当远程返回NOERROR但 Answer 区为空NODATA时若配置了下一个 forward 插件则继续执行。对应实现见 forward.gonext只在f.Next存在且其类型为*Forward时生效next_on_nodata则额外要求响应码为dns.RcodeSuccess且isEmpty(ret)Answer 区为空或全为 nil见 forward.go。配置解析时 RCODE 通过dns.StringToRcode校验setup.go。failfast_all_unhealthy_upstreams全灭时的快速失败决定所有上游都不健康且对健康检查无响应时如何处理请求。开启后所有请求会立即返回 SERVFAIL默认行为则是把请求发往一个随机上游可能成功也可能失败。默认的随机喷洒逻辑见 forward.go当fails len(f.proxies)时累加指标coredns_forward_healthcheck_broken_total若未开启 failfast 则r.List(f.proxies)[0]随机选一个上游连接注意这里总是使用random策略。failover按 RCODE 故障转移默认情况下当一次 DNS 查找没有返回 DNS 响应如超时时forward 会尝试下一个上游。failover选项让这一行为同样适用于返回了指定 RCODE 的响应如SERVFAIL、REFUSED。NOERROR不能用于 failover若所有上游都已尝试则返回最后一次尝试的响应。实现见 forward.go命中failoverRcodes且failoverAttempts len(f.proxies)时continue继续下一上游解析时NOERROR会被拒绝setup.go。source_address出站源地址source_address IP设置所有出站请求包括健康检查查询使用的源地址。当上游服务器可从该地址触达时可靠但若上游属于不同网络则需谨慎——所选源地址可能对部分上游无效且返回路由配置不当会导致响应丢失。此时应确保上游有回到该源地址的路由。设置逻辑见 setup.go会同时下发到代理连接与健康检查器setup.go。resolver自定义主机名解析resolver IP[:PORT] [IP[:PORT]...]指定一个或多个用于在启动时解析主机名型 TO 端点的 DNS 解析器地址。未指定时使用系统解析器/etc/resolv.conf。每个地址可以是裸 IPIPv4/IPv6默认端口 53或IP:port可配置多个做冗余。解析实现见 resolve.go按顺序尝试每个解析器分别查询 A 与 AAAA 记录任一解析器给出结果即返回解析器地址会被校验必须是合法 IPsetup.go。超时模型每个端点的三层时间约束README 明确给出每个端点上的通信超时设定按层拆解如下拨号dial超时DNS 与 DoT 的拨号超时默认30s可根据早期结果自动下调到最低1sDoQ 握手超时为5s。DoT 连接建立TCP 拨号 TLS 握手额外受剩余 5s 转发重试窗口或更早的请求 deadline约束。开启重试时每次建立尝试被限制为转发开始时可用窗口的一半最多 2.5s避免握手卡死耗尽整个窗口使用max_connect_attempts 1时建立连接可用满整个剩余窗口。失败握手会关闭连接成功连接保持可复用。这些建立限制不改变DNS 交换的读超时。对应代码见 forward.godefaultTimeout 5 * time.Second非单次尝试场景下tlsConnectTimeout / 2。读超时固定为2s即上文read_timeout默认值。Metadata暴露给 metadata 插件的键当metadata插件同时启用时forward 会发布以下元数据forward/upstream处理该请求所用到的上游地址。实现见 forward.go在每次连接上游前调用metadata.SetValueFunc(ctx, forward/upstream, ...)动态写入。Metrics可观测性指标启用prometheus插件后可导出以下指标to为配置中的上游rcode为上游返回的响应码proto为传输类型如udp、tcp、tcp-tls、quic、httpscoredns_forward_healthcheck_broken_total{}所有上游都不健康、开始按random策略随机喷洒的计数。coredns_forward_max_concurrent_rejects_total{}因并发查询达到上限而被拒绝的查询计数。coredns_proxy_request_duration_seconds{proxy_nameforward, to, rcode}按上游、RCODE 的直方图。coredns_proxy_healthcheck_failures_total{proxy_nameforward, to, rcode}按上游的健康检查失败计数。coredns_proxy_conn_cache_hits_total{proxy_nameforward, to, proto}按上游与协议的连接缓存命中计数。coredns_proxy_conn_cache_misses_total{proxy_nameforward, to, proto}按上游与协议的连接缓存未命中计数。其中coredns_forward_healthcheck_broken_total与coredns_forward_max_concurrent_rejects_total的声明见 metrics.gohealthcheck_broken在 forward.go 触发max_concurrent_rejects在 forward.go 触发其余coredns_proxy_*系列来自底层 plugin/pkg/proxy 的公共指标。以下指标近期已废弃请按给出的替代方案迁移废弃指标替代方案coredns_forward_healthcheck_failures_total{to, rcode}coredns_proxy_healthcheck_failures_total{proxy_nameforward, to, rcode}coredns_forward_requests_total{to}sum(coredns_proxy_request_duration_seconds_count{proxy_nameforward, to})coredns_forward_responses_total{to, rcode}coredns_proxy_request_duration_seconds_count{proxy_nameforward, to, rcode}coredns_forward_request_duration_seconds{to, rcode}coredns_proxy_request_duration_seconds{proxy_nameforward, to, rcode}完整配置示例1. 将example.org.内所有请求代理到另一个端口上的 nameserverexample.org { forward . 127.0.0.1:9005 }2. 按子域分区转发 缓存。将lab.example.local.交给10.20.0.1example.local.不含lab.example.local.交给10.0.0.1其余请求交给/etc/resolv.conf中的服务器并缓存结果。注意同一 server block 内配置多个 forward 插件时会按列出顺序依次处理请求因此子域必须放在父域之前否则子域请求会被父域上游接管。本例顺序为lab.example.local→example.local→.. { cache forward lab.example.local 10.20.0.1 forward example.local 10.0.0.1 forward . /etc/resolv.conf }3. 等价的三 zone 分离写法区别下面的写法定义了三条独立插件链因而会有 3 个独立的cache实例lab.example.local { cache forward . 10.20.0.1 } example.local { cache forward . 10.0.0.1 } . { cache forward . /etc/resolv.conf }4. 三个解析器间负载均衡其中一个为 IPv6 地址. { forward . 10.0.0.10:53 10.0.0.11:1053 [2003::1]:53 }5. 除example.org外全部转发. { forward . 10.0.0.10:1234 { except example.org } }6. 使用宿主机resolv.conf的 nameserver 代理除example.org外的所有请求. { forward . /etc/resolv.conf { except example.org } }7. DoT 示例。将请求代理到 9.9.9.9DNS-over-TLS并缓存答案最长 30s。注意tls_servername是可用配置的必需项9.9.9.9 无法参与 TLS 协商同时把健康检查间隔设为 5s 以免高频探测淹没服务. { forward . tls://9.9.9.9 { tls_servername dns.quad9.net health_check 5s } cache 30 }8. DoQ 示例。DoQ 默认使用 UDP 853 端口并在一条 QUIC 连接上以独立流多路复用并发查询。注意forward 的单消息交互路径不支持通过 DoQ 传输 AXFR/IXFR这类请求会返回NOTIMP该行为有 doq_test.go 的测试用例佐证. { forward . quic://94.140.14.14 { tls_servername dns.adguard-dns.com health_check 5s } cache 30 }9. DoH 示例。实现固定使用默认/dns-query路径自定义路径不受支持. { forward . https://9.9.9.9 { tls_servername dns.quad9.net health_check 5s } cache 30 }10. 自定义健康检查域名. { forward . tls://9.9.9.9 { tls_servername dns.quad9.net health_check 5s domain example.org } cache 30 }11. 同一提供商的多个上游. { forward . tls://1.1.1.1 tls://1.0.0.1 { tls_servername cloudflare-dns.com health_check 5s } cache 30 }12. 多个 DoT 上游使用不同tls_servername时的端口分区方案本地 5301/5302 分别代理到两组 DoT 上游. { forward . 127.0.0.1:5301 127.0.0.1:5302 } .:5301 { forward . tls://8.8.8.8 tls://8.8.4.4 { tls_servername dns.google } } .:5302 { forward . tls://1.1.1.1 tls://1.0.0.1 { tls_servername cloudflare-dns.com } }13.next链式转发。以下配置先试 1.2.3.4若返回NXDOMAIN则试 5.6.7.85.6.7.8 返回NXDOMAIN则试 9.0.1.2. { forward . 1.2.3.4 { next NXDOMAIN } forward . 5.6.7.8 { next NXDOMAIN } forward . 9.0.1.2 { } }14.failover故障转移。以下配置中 1.2.3.4 返回SERVFAIL或REFUSED时尝试 5.6.7.85.6.7.8 同样失败时再尝试 9.0.1.2配合policy sequential保证顺序. { forward . 1.2.3.4 5.6.7.8 9.0.1.2 { policy sequential failover SERVFAIL REFUSED } }15. 主机名上游 自定义解析器。使用10.0.0.1解析dns.example.local主机名. { forward . dns.example.local { resolver 10.0.0.1 } }深入阅读路径如需进一步钻研实现细节建议按以下路径阅读源码plugin/forward/forward.goServeDNS主流程、上游遍历与重试、max_concurrent 限流、next/failover 判断、forward/upstream元数据。plugin/forward/setup.goCorefile 解析、15 上游上限、TLS 配置与 SNI 冲突校验、全部块内选项的默认值与合法性校验。plugin/forward/policy.gorandom / round_robin / sequential 三种选择策略实现。plugin/forward/resolve.go主机名 TO 端点的解析、去重与resolver选项实现。plugin/forward/metrics.goforward 专属指标声明。plugin/pkg/proxy/health.goDNS/DoT、DoH、DoQ 三种健康检查器实现与no_rec、domain的落点。plugin/pkg/proxy/proxy.goDown(maxfails)判定、连接缓存/寿命设置与健康检查调度。plugin/pkg/transport/transport.go各传输默认端口DNS 53、DoT/DoQ 853、DoH 443。协议层面DoT、DoH、DoQ 分别对应 IETF 规范 RFC 7858、RFC 8484 与 RFC 9250可作为理解各传输行为的外部参考。赞分享后端网络云原生【免费下载链接】corednsCoreDNS is a DNS server that chains plugins项目地址https://gitcode.com/gh_mirrors/co/coredns点击查看免费下载相关推荐Hickory DNS多协议支持DoH、DoT、DoQ全面指南Hickory DNS是一个基于Rust语言开发的高性能DNS客户端、服务器和解析器。该项目全面支持现代DNS安全协议包括DNS over HTTPS DoH网络通信后端CoreDNS tls 插件完全指南为 DoT / gRPC / DoH 服务器配置 TLS 与 ACME 自动证书CoreDNS tls 插件完全指南为 DoT / gRPC / DoH 服务器配置 TLS 与 ACME 自动证书 导读 tls 插件是 CoreDNS 中后端网络云原生conda doctor 健康检查命令完全指南用法、内置检查与插件修复机制conda doctor 健康检查命令完全指南用法、内置检查与插件修复机制 conda doctor 是 conda 内置的环境诊断命令通过运行一组可插拔的包管理器CLI上一篇baidupankey技术实现深度剖析从资源获取瓶颈到自动化解决方案下一篇SGLang MMLU 基准测试指南数据准备、服务部署与 few-shot 精度评测创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考