跳到主要内容

专用 DNS 上游

DNSForwarder 与 DNSUpstream 将 local、provider、default DNS query 路由到 UDP、TCP、DoT、DoH 和 addressFrom source 的流程

适用场景

当您希望路由器上的解析器具备以下行为时:

  • 将接入网络的内部区域(例如:ISP 的 AFTR FQDN、企业内部域)转发至动态学习到的 DNS 服务器。
  • 平时以加密 DNS 提供商(DoH / DoT)作为默认上游。
  • 加密上游异常时,回退至明文 DNS。
  • 不在共享示例中写入提供商账号 ID 或私有 endpoint。

routerd 的解决方式

DNSResolver 会启动 routerd-dns-resolver 守护进程。 守护进程监听 UDP/TCP。隶属于解析器的 DNSForwarder 表示 match 规则,DNSUpstream 表示可复用的上游 endpoint。

Scheme类别默认端口
https://DNS over HTTPS依 URL 而定
tls://DNS over TLS853
udp://明文 DNS over UDP53
tcp://明文 DNS over TCP53

DNSForwarder.spec.upstreams 的顺序即为优先级。优先尝试优先度最高且健康的上游,失败后依次往下。

使用 DNSUpstream.spec.addressFrom,可从其他资源的 status 获取上游地址列表。 这是利用 DHCPv6 information-request 获取的 DNS 服务器时所使用的机制。

条件式转发示例

- apiVersion: net.routerd.net/v1alpha1
kind: DNSResolver
metadata:
name: lan-resolver
spec:
listen:
- name: lan
addresses:
- 192.0.2.1
port: 53
sources:
- local-zone
- access-network
- provider-bootstrap
- default
cache:
enabled: true
maxEntries: 10000
minTTL: 60s
maxTTL: 24h
negativeTTL: 30s
- apiVersion: net.routerd.net/v1alpha1
kind: DNSForwarder
metadata:
name: local-zone
spec:
resolver: DNSResolver/lan-resolver
match: [lan.example.org]
zoneRefs: [DNSZone/lan]
- apiVersion: net.routerd.net/v1alpha1
kind: DNSForwarder
metadata:
name: access-network
spec:
resolver: DNSResolver/lan-resolver
match: [transix.jp, corp.example.com]
upstreams: [DNSUpstream/access-network]
- apiVersion: net.routerd.net/v1alpha1
kind: DNSUpstream
metadata:
name: access-network
spec:
protocol: udp
addressFrom:
- resource: DHCPv6Information/wan-info
field: dnsServers
- apiVersion: net.routerd.net/v1alpha1
kind: DNSForwarder
metadata:
name: provider-bootstrap
spec:
resolver: DNSResolver/lan-resolver
match: [dns.example-provider.net]
upstreams: [DNSUpstream/cloudflare-udp, DNSUpstream/google-udp]
- apiVersion: net.routerd.net/v1alpha1
kind: DNSForwarder
metadata:
name: default
spec:
resolver: DNSResolver/lan-resolver
match: ["."]
upstreams: [DNSUpstream/provider-doh, DNSUpstream/provider-dot, DNSUpstream/cloudflare-udp]
healthcheck:
interval: 15s
timeout: 3s
failThreshold: 3
passThreshold: 2
dnssecValidate: true
- apiVersion: net.routerd.net/v1alpha1
kind: DNSUpstream
metadata:
name: provider-doh
spec:
protocol: doh
address: dns.example-provider.net
path: /dns-query
sourceInterface: ens18
bootstrap: [1.1.1.1, 2606:4700:4700::1111]
- apiVersion: net.routerd.net/v1alpha1
kind: DNSUpstream
metadata:
name: provider-dot
spec:
protocol: dot
address: dns.example-provider.net
sourceInterface: ens18
bootstrap: [1.1.1.1, 2606:4700:4700::1111]
- apiVersion: net.routerd.net/v1alpha1
kind: DNSUpstream
metadata:
name: cloudflare-udp
spec:
protocol: udp
address: 1.1.1.1
- apiVersion: net.routerd.net/v1alpha1
kind: DNSUpstream
metadata:
name: google-udp
spec:
protocol: udp
address: 8.8.8.8

提供商的 bootstrap 处理

部分私有 DNS 提供商以该提供商自身的域名发布解析器 endpoint。 若主机试图「通过该提供商本身」解析其提供商名称,在解析器健全之前将会发生循环或失败。

请为该提供商的域名建立条件式 source,并将查询导向公众解析器或 access-network 的 DNS。 提供商的账号 ID(例如 profile ID)请勿写入共享示例,应仅置于主机本地的 secrets 文件或各主机专属的 YAML overlay 中。

DNSUpstream.spec.bootstrap 以更精细的方式提供相同保护。它指定在建立加密传输之前,用于解析该上游 endpoint 名称的解析器。

接口绑定

DNSUpstream.spec.sourceInterface 将对外的 DNS 查询绑定至 Linux 的接口名称。 请使用 OS 接口的实际名称(例如 ens18)。 若该接口由其他资源(如 tunnel)建立,请通过 ownerRefs 或顺序声明依赖关系,使解析器在接口建立前保持 pending 状态。

FreeBSD 没有对等的 SO_BINDTODEVICE 强制机制,因此在平台专属文档中不保证相同的行为。

相关文件