说明
forward 外挂插件可重复使用已打开的上游套接字。它支持 UDP、TCP 及 DNS-over-TLS 并使用带内健康检查。
当检测到错误时,将执行健康检查。此检查会以循环方式运行,在报告上游状态不佳的情况下,以间隔0.5 秒执行每次检查,直到其状态恢复正常。一旦正常后,我们将停止健康检查(直到下一个错误出现)。健康检查使用递归 DNS 查询(. IN NS
)获取上游状态信息。任何不是网络错误(拒绝、未实现、服务器故障等)的响应都视为上游状态正常。健康检查使用与TO 中所指定的相同协议。如果将max_fails
设置为 0,则不执行检查且上游会被始终视为正常。
当所有上游都宕机时,它预设健康检查机制已失效,并将尝试连接到随机上游(可能存在连接成功或失败的情况)。
语法
最基本形式中,简单转发器使用此语法
forward FROM TO...
- FROM 是用于匹配需要转发的请求的基础域。使用展开为多个反向区域的 CIDR 表示法的域不受完全支持;仅使用第一个展开的区域。
- TO… 是转发到的目标端点。TO 语法允许你指定协议、
tls://9.9.9.9
或dns://
(或不指定协议)以获取纯 DNS。上游数量限制为 15 个。
首次使用时,多个上游会被随机化(请参阅policy
)。当健康代理在交换期间返回错误时,会尝试使用列表中的下一个上游。
使用扩展语法可提供更多控制。
forward FROM TO... {
except IGNORED_NAMES...
force_tcp
prefer_udp
expire DURATION
max_fails INTEGER
tls CERT KEY CA
tls_servername NAME
policy random|round_robin|sequential
health_check DURATION [no_rec] [domain FQDN]
max_concurrent MAX
}
-
FROM 和 TO… 如上所述。
-
except
中的IGNORED_NAMES 是空间分隔的域列表,用于排除在转发之外。请求与这些名称均不匹配,将被传递。 -
force_tcp
,即使请求通过 UDP 发送,仍使用 TCP。 -
prefer_udp
,即使请求通过 TCP 发送,也首先尝试使用 UDP。如果响应被截断(响应中设置 TC 标志),则通过 TCP 再次尝试。如果指定了force_tcp
和prefer_udp
选项,则force_tcp
优先。 -
max_fails
是在将上游视为宕机之前所需的后续健康检查的失败次数。如果为 0,则不会将上游标记为宕机(也不会进行健康检查)。默认为 2。 -
expire
持续时间,(缓存的)连接在此时间之后过期,默认值为 10 秒。 -
tls
证书 密钥 CA 为 TLS 连接定义 TLS 属性。可提供 0 到 3 个参数,具体含义如下tls
- 不使用客户端身份验证,并且使用系统 CA 来验证服务器证书tls
CA - 不使用客户端身份验证,并且使用文件 CA 来验证服务器证书tls
CERT KEY - 使用指定的证书/密钥对进行客户端身份验证。服务器证书通过系统 CA 验证tls
CERT KEY CA - 使用指定的证书/密钥对进行客户端身份验证。服务器证书使用指定的 CA 文件验证
-
tls_servername
名称 允许您在 TLS 配置中设置服务器名称;例如,9.9.9.9 需要将其设置为dns.quad9.net
。在这种情况下仍允许使用多个上游,但它们必须使用相同的tls_servername
。例如,将 9.9.9.9(QuadDNS)与 1.1.1.1(Cloudflare)混合使用则不起作用。使用 TLS 转发但不设置tls_servername
会导致任何人都可以中间人攻击您与所转发的 DNS 服务器之间的连接。因此,在使用 TLS 转发时强烈建议设置此值。 -
策略
指定用于选择上游服务器的策略。默认值为random
。random
是实施随机上游选择的策略。round_robin
是根据循环排序选择主机的策略。sequential
是根据顺序排序选择主机的策略。
-
health_check
配置上游服务器的健康检查行为<duration>
- 对健康检查使用不同的持续时间,默认持续时间为 0.5 秒。no_rec
- 可选参数,将健康检查中使用的 dns 查询的 RecursionDesired 标志设置为false
。该标志默认为true
。domain FQDN
- 设置用于健康检查的域名,设置为 FQDN。如果未配置,用于健康检查的域名是.
。
-
max_concurrent
MAX 将并发查询的数量限制为 MAX。任何可能会将并发查询数量提高到 MAX 之上的新查询都会导致 REFUSED 响应。此响应不会算作健康故障。在为 MAX 选择一个值时,选择一个至少大于预期的上游查询速率 * 上游服务器的延迟的数字。作为 MAX 的上限,请考虑每个并发查询将使用大约 2kb 的内存。
另外请注意,如果不同的上游需要不同的 tls_servername
,则 TLS 配置对于整个转发代理是“全局”的。
在每个端点上,通信的超时设置如下
- 拨号超时默认值为 30 秒,可以根据早期结果自动降至 1 秒。
- 读取超时固定为 2 秒。
元数据
如果已启用元数据插件,向前插件会发布以下元数据
forward/upstream
:用于转发请求的上游
指标
如果启用了监控(通过prometheus插件),则导出以下指标
coredns_forward_healthcheck_broken_total{}
- 所有上游都不健康,我们正在随机(始终使用random
策略)将请求分发到上游时的计数。coredns_forward_max_concurrent_rejects_total{}
- 由于并发查询数达到最大值而拒绝的查询计数。coredns_proxy_request_duration_seconds{proxy_name="forward", to, rcode}
- 按上游、RCODE 的直方图coredns_proxy_healthcheck_failures_total{proxy_name="forward", to, rcode}
- 按上游计算的健康检查失败计数。coredns_proxy_conn_cache_hits_total{proxy_name="forward", to, proto}
- 按上游和协议计算的连接缓存点击数。coredns_proxy_conn_cache_misses_total{proxy_name="forward", to, proto}
- 按上游和协议计算的连接缓存未命中数。
其中to
是某个上游服务器(配置中的TO),rcode
是上游返回的 RCODE,proto
是传输协议,如udp
、tcp
、tcp-tls
。
以下指标最近已被弃用
coredns_forward_healthcheck_failures_total{to, rcode}
- 可以用
coredns_proxy_healthcheck_failures_total{proxy_name="forward", to, rcode}
替换
- 可以用
coredns_forward_requests_total{to}
- 可以用
sum(coredns_proxy_request_duration_seconds_count{proxy_name="forward", to})
替换
- 可以用
coredns_forward_responses_total{to, rcode}
- 可以用
coredns_proxy_request_duration_seconds_count{proxy_name="forward", to, rcode}
替换
- 可以用
coredns_forward_request_duration_seconds{to, rcode}
- 可以用
coredns_proxy_request_duration_seconds{proxy_name="forward", to, rcode}
替换
- 可以用
示例
在example.org
中将所有请求代理到不同端口上运行的名称服务器
example.org {
forward . 127.0.0.1:9005
}
将lab.example.local.
中所有请求发送到10.20.0.1
,将example.local.
中所有请求(不在lab.example.local.
中)发送到10.0.0.1
,将所有其他请求发送到/etc/resolv.conf
中定义的服务器,并缓存结果。请注意,在服务器块中配置了多个forward插件的 CoreDNS 服务器将在为请求提供服务时,按照列出的顺序评估这些 forward 插件。因此,子域必须位于父域之前,否则子域请求将被转发到父域的上游。因此,在此示例中,lab.example.local
在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 个cache的单独实例)。
lab.example.local {
cache
forward . 10.20.0.1
}
example.local {
cache
forward . 10.0.0.1
}
. {
cache
forward . /etc/resolv.conf
}
在三个解析程序之间负载均衡所有请求,其中一个解析程序具有 IPv6 地址。
. {
forward . 10.0.0.10:53 10.0.0.11:1053 [2003::1]:53
}
转发除发往example.org
的请求之外的所有请求
. {
forward . 10.0.0.10:1234 {
except example.org
}
}
除发往example.org
的请求外,使用主机的resolv.conf
中的名称服务器代理所有请求
. {
forward . /etc/resolv.conf {
except example.org
}
}
使用 DNS-over-TLS (DoT) 协议将所有请求代理到 9.9.9.9,并缓存每个答案最长 30 秒。请注意,如果想让设置正常运行,tls_servername
是必须的,因为无法在 TLS 协商中使用 9.9.9.9。还要将运行状况检查的持续时间设置为 5 秒,以免运行状况检查完全使服务瘫痪。
. {
forward . tls://9.9.9.9 {
tls_servername dns.quad9.net
health_check 5s
}
cache 30
}
或为运行状况检查请求配置其他域名
. {
forward . tls://9.9.9.9 {
tls_servername dns.quad9.net
health_check 5s domain example.org
}
cache 30
}
或使用来自同一提供商的多路复用上行连接
. {
forward . tls://1.1.1.1 tls://1.0.0.1 {
tls_servername cloudflare-dns.com
health_check 5s
}
cache 30
}
或当你在不同的 tls_servername
上有多个 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
}
}
另请参阅
RFC 7858,了解 DNS over TLS。