外观
18 - 适用场景与网络环境
本文帮你快速判断"我的场景该用哪种模式"和"我的网络环境能不能部署"。每个场景都给到可直接用的配置和验证命令。
场景与模式速查
| 你的场景 | 推荐模式 | 需公网 | 需证书 | 关键特性 |
|---|---|---|---|---|
| 管理自有域名的公网权威 DNS | authoritative | 是 | 否 | Zone 文件 + DDNS |
| CDN / GSLB 动态调度 | authoritative | 是 | 否 | REST API 动态增删记录 |
| 企业出口 DNS(自己解析) | recursive | 是 | 否 | 从根开始迭代解析 |
| 内网 DNS 出口(转发到公共 DNS) | forwarder | 否 | 否 | 条件转发 + 负载均衡 |
| 安全网关 DNS(集中审计) | forwarder | 否 | 否 | 集中转发 + ACL + RRL |
| K8s / 容器集群 DNS | hybrid | 否 | 否 | 内部权威 + 外部转发 |
| 企业内网综合 DNS | hybrid | 可选 | 否 | 权威 + 递归 + 转发 |
| 家庭 / 办公网关 DNS | recursive / 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" | jqTTL 设为 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 人 | ~50 | 128MB | 2 | 转发或混合 |
| 1,000 人 | ~500 | 512MB | 4 | 混合 |
| 10,000 人 | ~5,000 | 2GB | 8 | 递归或混合 |
| 公网服务 | ~50,000+ | 4GB+ | 16+ | 权威 + DoT + DoH |
Worker = 0 表示自动检测 CPU 核心数,推荐大多数场景使用。
场景选择决策树
你的需求是什么?
│
├── 管理自己的域名?
│ ├── 仅权威 → authoritative
│ └── 权威 + 外部解析 → hybrid
│
├── 给内网做 DNS 出口?
│ ├── 能直连根服务器 → recursive
│ └── 不能直连根 → forwarder
│
├── 集群 / K8s 内部 DNS?
│ └── hybrid(内部权威 + 外部转发)
│
├── 安全网关 / 集中审计?
│ └── forwarder(集中转发 + ACL + RRL)
│
├── 隐私加密 DNS?
│ └── 任意模式 + DoT/DoH
│
└── 开发测试?
└── hybrid(一份配置全开,按需裁剪)下一步
- 05 - 部署指南 — systemd / Docker / Compose 部署步骤
- 06 - 运行模式详解 — 四种模式深度对比
- 04 - 配置参考手册 — 全部配置项速查