Skip to content

18 - 适用场景与网络环境 ​

本文帮你快速判断"我的场景该用哪种模式"和"我的网络环境能不能部署"。每个场景都给到可直接用的配置和验证命令。


场景与模式速查 ​

你的场景推荐模式需公网需证书关键特性
管理自有域名的公网权威 DNSauthoritative是否Zone 文件 + DDNS
CDN / GSLB 动态调度authoritative是否REST API 动态增删记录
企业出口 DNS(自己解析)recursive是否从根开始迭代解析
内网 DNS 出口(转发到公共 DNS)forwarder否否条件转发 + 负载均衡
安全网关 DNS(集中审计)forwarder否否集中转发 + ACL + RRL
K8s / 容器集群 DNShybrid否否内部权威 + 外部转发
企业内网综合 DNShybrid可选否权威 + 递归 + 转发
家庭 / 办公网关 DNSrecursive / hybrid是否递归 + 缓存
隐私加密 DNS任意是是DoT + DoH
开发测试环境hybrid否否灵活配置,按需裁剪

选不了?能直连根服务器选 recursive,不能选 forwarder,要管域名加 authoritative,又想内部权威又想外部解析用 hybrid。


场景一:公网权威 DNS ​

需求 ​

  • 管理自有域名的权威解析
  • 对全球互联网提供 DNS 服务
  • 支持动态更新记录
  • 高可用、低延迟

配置 ​

toml
[server]
mode = "authoritative"
listen-addrs = ["0.0.0.0", "::"]
listen-port = 53
workers = 0

[[zones]]
name = "example.com"
file = "/etc/tdns/zones/example.com.zone"
type = "master"
allow-transfer = ["secondary"]
allow-update = ["none"]

[access-control]
allow-query = ["any"]            # 公网可查询
allow-recursion = ["none"]       # 不提供递归
allow-transfer = ["secondary"]   # 仅允许辅 DNS 传输

[acl.secondary]
addresses = ["192.0.2.100"]      # 辅 DNS IP

部署验证 ​

bash
# 验证配置
tdns --validate --config /etc/tdns/tdns.toml

# 启动
sudo systemctl start tdns

# 从公网验证
dig @your-server-ip example.com SOA
dig @your-server-ip www.example.com A

网络要求 ​

要求说明
公网 IP至少一个公网 IPv4/IPv6 地址
53/udp + 53/tcp 开放面向公网
带宽根据查询量评估
Anycast(可选)多节点部署降低延迟

场景二:CDN / GSLB 流量分发 ​

需求 ​

  • 根据客户端来源返回不同解析结果
  • 健康检查与故障转移
  • 低延迟应答

配置 ​

toml
[server]
mode = "authoritative"

[[zones]]
name = "cdn.example.com"
file = "/etc/tdns/zones/cdn.example.com.zone"
type = "master"

# 通过 REST API 动态管理记录实现 GSLB
[api]
enabled = true
listen = "127.0.0.1:8080"
auth-token = "your-gslb-token"

GSLB 自动化脚本 ​

bash
TOKEN="your-gslb-token"
BASE="http://127.0.0.1:8080"
ZONE="cdn.example.com"

# 健康检查通过时添加节点
curl -s -X POST "$BASE/api/v1/zones/$ZONE/records" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"node1.cdn.example.com","type":"A","ttl":5,"data":"192.0.2.10"}'

# 健康检查失败时删除节点
curl -s -X DELETE "$BASE/api/v1/zones/$ZONE/records/node1.cdn.example.com/A" \
  -H "Authorization: Bearer $TOKEN"

# 列出当前所有节点
curl -s -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/v1/zones/$ZONE/records" | jq

TTL 设为 5 秒,客户端缓存快速过期,故障切换秒级生效。


场景三:企业出口 DNS(递归) ​

需求 ​

  • 直接从 DNS 根开始迭代解析,不依赖第三方
  • 完整解析链路自己掌控
  • 适合有公网出站能力的企业网络

配置 ​

toml
[server]
mode = "recursive"
listen-addrs = ["0.0.0.0", "::"]
listen-port = 53

[recursion]
enabled = true
query-timeout = "5s"
max-concurrent-queries = 10000

[cache]
max-size = "2GB"
prefetch-enabled = true
stale-ttl = 86400              # 上游故障时返回过期缓存

[access-control]
allow-query = ["trusted"]
allow-recursion = ["trusted"]

[acl.trusted]
addresses = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]

部署验证 ​

bash
# 确认能直连根服务器
dig @198.41.0.4 . NS +time=5

# 启动
sudo systemctl start tdns

# 测试递归解析
dig @127.0.0.1 www.baidu.com
dig @127.0.0.1 www.google.com

网络要求 ​

要求验证方法
公网出站dig @198.41.0.4 . NS
UDP 53 出站nc -u -w3 198.41.0.4 53
TCP 53 出站nc -z 198.41.0.4 53
无 NAT 限制实际递归测试

不能直连根服务器?用转发模式代替,见场景四。


场景四:内网 DNS 出口(转发) ​

需求 ​

  • 内网客户端 DNS 查询出口
  • 内部域名条件转发到内网 DNS
  • 不需要公网直连根服务器

配置 ​

toml
[server]
mode = "forwarder"
listen-port = 53

[recursion]
enabled = false

# 公网域名转发到公共 DNS
[[forwarders]]
addr = "8.8.8.8"
port = 53
priority = 1
weight = 1

[[forwarders]]
addr = "1.1.1.1"
port = 53
priority = 1
weight = 1

# 内部域名条件转发到内网 DNS
[[conditional-forwards]]
zone = "corp.internal."
forwarders = ["10.0.0.10", "10.0.0.11"]

[[conditional-forwards]]
zone = "ad.corp.internal."
forwarders = ["10.0.0.20"]     # 更具体,最长前缀匹配优先

[access-control]
allow-query = ["trusted"]
allow-recursion = ["trusted"]

[acl.trusted]
addresses = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]

部署验证 ​

bash
# 测试外部域名(走转发器)
dig @127.0.0.1 www.baidu.com

# 测试内部域名(走条件转发)
dig @127.0.0.1 server1.corp.internal

# 测试更具体的条件转发
dig @127.0.0.1 dc01.ad.corp.internal

网络要求 ​

要求说明
上游 DNS 可达至少一个公共或内部上游
53/udp 出站向上游发送查询
无公网直连要求不需要直连根服务器

场景五:安全网关 DNS ​

需求 ​

  • 集中审计所有 DNS 查询
  • 强制所有客户端通过受控上游
  • 访问控制和安全过滤

配置 ​

toml
[server]
mode = "forwarder"
listen-port = 53

[recursion]
enabled = false

# 仅转发到受控安全 DNS
[[forwarders]]
addr = "10.0.0.1"
port = 53
priority = 1
weight = 1

# 速率限制,防异常查询
[security.rrl]
enabled = true
responses-per-second = 10

[access-control]
allow-query = ["trusted"]       # 仅内网
allow-recursion = ["none"]      # 不提供递归
allow-transfer = ["none"]       # 禁止传输

[acl.trusted]
addresses = ["10.0.0.0/8"]

场景六:K8s 集群 DNS ​

需求 ​

  • 集群内部服务发现(权威应答)
  • 外部域名解析(转发到上游)
  • 低延迟、高可用

配置 ​

toml
[server]
mode = "hybrid"
listen-port = 53
workers = 0

[recursion]
enabled = false                # 用转发代替递归,集群环境更稳定

# 集群内部域名(权威应答)
[[zones]]
name = "cluster.local"
file = "/etc/tdns/zones/cluster.local.zone"
type = "master"

# 外部域名转发到上游
[[forwarders]]
addr = "8.8.8.8"
port = 53
priority = 1
weight = 1

[cache]
max-size = "512MB"
prefetch-enabled = true

[access-control]
allow-query = ["any"]
allow-recursion = ["any"]

部署验证 ​

bash
# 内部域名(权威应答)
dig @127.0.0.1 kubernetes.cluster.local

# 外部域名(转发)
dig @127.0.0.1 www.google.com

场景七:企业内网综合 DNS ​

需求 ​

  • 内部域名权威解析
  • 外部域名递归 / 转发
  • 反向解析
  • 动态更新(DDNS)

配置 ​

toml
[server]
mode = "hybrid"
listen-port = 53

[recursion]
enabled = true

# 内部正向区域
[[zones]]
name = "internal.example.com"
file = "/etc/tdns/zones/internal.example.com.zone"
allow-update = ["update-key."]

# 反向区域
[[zones]]
name = "168.192.in-addr.arpa"
file = "/etc/tdns/zones/rev-192.168.zone"

# 外部域名转发
[[forwarders]]
addr = "8.8.8.8"
port = 53

# TSIG 密钥(DDNS 认证)
[[keys]]
name = "update-key."
algorithm = "hmac-sha256"
secret = "<base64-secret>"

[access-control]
allow-query = ["trusted"]
allow-recursion = ["trusted"]
allow-transfer = ["management"]

[acl.trusted]
addresses = ["10.0.0.0/8"]

[acl.management]
addresses = ["10.0.0.100"]

# API 供运维自动化
[api]
enabled = true
listen = "127.0.0.1:8080"
auth-token = "secure-token"

场景八:隐私加密 DNS(DoT + DoH) ​

需求 ​

  • 加密 DNS 传输,防止中间人窥探
  • 支持 DoT(移动设备)和 DoH(浏览器)

配置 ​

toml
[server]
mode = "recursive"             # 或 hybrid / forwarder

[recursion]
enabled = true

# DNS-over-TLS
[tls]
enabled = true
listen-port = 853
cert = "/etc/tdns/tls/fullchain.pem"
key = "/etc/tdns/tls/privkey.pem"

# DNS-over-HTTPS(共享 [tls] 的证书)
[doh]
enabled = true
listen-port = 443
path = "/dns-query"

[access-control]
allow-query = ["any"]
allow-recursion = ["any"]

部署验证 ​

bash
# 测试 DoT
kdig @dns.example.com example.com +tls

# 测试 DoH(POST 方式)
curl -s -H "Content-Type: application/dns-message" \
  --data-binary @query.bin \
  https://dns.example.com/dns-query -o response.bin

# 测试 DoH(GET 方式)
# dns=<base64url 编码的 DNS 查询消息>
curl -s "https://dns.example.com/dns-query?dns=AAAB" -o response.bin

# 检查证书 ALPN
openssl s_client -connect dns.example.com:443 -alpn h2

网络要求 ​

要求验证方法
公网 IP客户端 ping 服务器
853/tcp 入站外部 nc -z server 853
443/tcp 入站外部 nc -z server 443
域名dig dns.example.com
有效 TLS 证书Let's Encrypt 或商业证书

网络环境评估 ​

我的网络能部署递归模式吗? ​

条件验证命令不满足怎么办
能访问根服务器dig @198.41.0.4 . NS用转发模式
UDP 53 出站nc -u -w3 198.41.0.4 53用转发模式
TCP 53 出站nc -z 198.41.0.4 53用转发模式
无 NAT 限制实际递归测试用转发模式

结论:以上任一不满足,就用 forwarder 代替 recursive。

我的网络能部署 DoT / DoH 吗? ​

条件验证命令
公网 IP客户端 ping 服务器
853/tcp 入站外部 nc -z server 853
443/tcp 入站外部 nc -z server 443
域名dig dns.example.com
TLS 证书Let's Encrypt 申请

各网络环境适用性 ​

网络环境权威递归转发混合DoT/DoH
公网服务器✅✅✅✅✅
云主机(有公网 IP)✅✅✅✅✅
内网服务器(有出站)✅✅✅✅⚠️
内网隔离环境✅❌✅⚠️❌
家庭网络✅✅✅✅⚠️
NAT 环境✅⚠️✅⚠️✅

⚠️ = 条件受限或有特殊要求。内网部署 DoT/DoH 需在网内可达,证书可用自签名。

NAT 环境注意事项 ​

NAT 环境可能影响递归解析:

  • 对称 NAT:出站 UDP 源端口固定,可能影响根服务器响应接收
  • 连接跟踪超时:长连接可能被 NAT 中断,递归查询超时
  • 解决方案:使用转发模式替代递归模式,避免 NAT 问题

容量规划参考 ​

用户规模QPS 估计缓存大小Worker建议模式
100 人~50128MB2转发或混合
1,000 人~500512MB4混合
10,000 人~5,0002GB8递归或混合
公网服务~50,000+4GB+16+权威 + DoT + DoH

Worker = 0 表示自动检测 CPU 核心数,推荐大多数场景使用。


场景选择决策树 ​

你的需求是什么?
│
├── 管理自己的域名?
│   ├── 仅权威 → authoritative
│   └── 权威 + 外部解析 → hybrid
│
├── 给内网做 DNS 出口?
│   ├── 能直连根服务器 → recursive
│   └── 不能直连根 → forwarder
│
├── 集群 / K8s 内部 DNS?
│   └── hybrid(内部权威 + 外部转发)
│
├── 安全网关 / 集中审计?
│   └── forwarder(集中转发 + ACL + RRL)
│
├── 隐私加密 DNS?
│   └── 任意模式 + DoT/DoH
│
└── 开发测试?
    └── hybrid(一份配置全开,按需裁剪)

下一步 ​