外观
04 - 配置参考手册
TDNS 使用 TOML 格式配置文件(默认路径 /etc/tdns/tdns.toml)。本文档逐段说明所有配置项,每个配置块都给出完整可复制的示例。
完整示例文件见随包发布的 etc/tdns.toml.example。
配置文件位置
| 文件 | 默认路径 | 说明 |
|---|---|---|
tdns.toml | /etc/tdns/tdns.toml | 主配置文件 |
root.hints | /var/lib/tdns/root.hints | DNS 根服务器提示文件(递归模式必需) |
| Zone 文件 | /etc/tdns/zones/*.zone | 权威区域数据文件(BIND 格式) |
root.hints 查找顺序:
--root-hintsCLI 参数 ><working-directory>/root.hints>etc/root.hints(相对路径)
[server] 服务器配置
toml
[server]
# 运行用户/组(Unix,留空 = 当前用户)
# user = "tdns"
# group = "tdns"
pid-file = "/var/run/tdns/tdns.pid"
working-directory = "/var/lib/tdns"
# 监听地址(支持 IPv4 + IPv6 双栈)
listen-addrs = ["0.0.0.0", "::"]
# DNS 监听端口(标准 53,开发可用非特权端口如 10053)
listen-port = 53
# 运行模式: recursive | authoritative | forwarder | hybrid
mode = "hybrid"
# 工作线程数(0 = 自动检测 CPU 核心数)
workers = 0
# 日志级别: trace | debug | info | warn | error
log-level = "info"
# 日志文件(留空 = 输出到 stdout)
# log-file = "/var/log/tdns/tdns.log"
# 日志格式: json | text
log-format = "json"| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
user | string | 当前用户 | 运行用户(仅 Unix) |
group | string | 当前组 | 运行组(仅 Unix) |
pid-file | path | /var/run/tdns/tdns.pid | PID 文件路径 |
working-directory | path | /var/lib/tdns | 工作目录(相对路径基准) |
listen-addrs | array | ["0.0.0.0", "::"] | 监听地址列表 |
listen-port | u16 | 53 | DNS 监听端口 |
mode | enum | hybrid | 运行模式 |
workers | usize | 0 | Tokio 线程数(0=自动) |
log-level | string | info | 日志级别 |
log-file | path | 无 | 日志文件路径 |
log-format | enum | json | 日志格式 |
DoT/DoH 监听地址:加密传输复用
server.listen-addrs绑定 IP,各自通过[tls].listen-port和[doh].listen-port指定端口。
[cache] 缓存配置
toml
[cache]
enabled = true
max-size = "1GB" # 支持 KB / MB / GB 后缀
min-ttl = 60 # 最小缓存 TTL(秒)
max-ttl = 86400 # 最大缓存 TTL(24 小时)
negative-ttl = 300 # NXDOMAIN/NODATA 缓存 TTL(5 分钟)
stale-ttl = 86400 # Serving Stale 过期上限(RFC 8767,默认 24 小时)
prefetch-enabled = false # 缓存预热
prefetch-threshold = 0.8 # 预热触发阈值(TTL 剩余比例)
max-negative-entries = 50000 # 负缓存最大条目数| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | true | 是否启用缓存 |
max-size | string | "1GB" | 缓存最大容量(按条目数估算) |
min-ttl | u32 | 60 | 最小缓存 TTL,防短 TTL 放大攻击 |
max-ttl | u32 | 86400 | 最大缓存 TTL,保证数据新鲜度 |
negative-ttl | u32 | 300 | 负缓存 TTL |
stale-ttl | u32 | 86400 | 上游故障时过期缓存可用时长 |
prefetch-enabled | bool | false | 到期前自动刷新热门记录 |
prefetch-threshold | f64 | 0.8 | TTL 剩余比例低于此值时预热 |
max-negative-entries | usize | 50000 | 负缓存上限,防 OOM 攻击 |
常见调优场景:
toml
# 高 QPS 公网递归:大缓存 + 预热
[cache]
max-size = "4GB"
prefetch-enabled = true
prefetch-threshold = 0.9
# 内网 DNS:适中即可
[cache]
max-size = "512MB"
# 权威 DNS(无递归):可关闭或缩小
[cache]
enabled = false[recursion] 递归配置
toml
[recursion]
enabled = true
max-concurrent-queries = 10000
query-timeout = "5s" # 支持 s / ms 后缀
max-depth = 16 # CNAME 跟踪最大深度| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | true | 是否启用递归解析 |
max-concurrent-queries | usize | 10000 | 最大并发递归查询数 |
query-timeout | string | "5s" | 单次递归查询超时 |
max-depth | u32 | 16 | CNAME 链追踪最大深度 |
安全要求:当
recursion.enabled = true时,access-control.allow-recursion必须配置,否则服务器拒绝启动(防开放递归)。
[[forwarders]] 上游转发器
toml
# 主用上游(priority=1,高权重优先)
[[forwarders]]
addr = "8.8.8.8"
port = 53
protocol = "udp" # udp | tcp
priority = 1 # 优先级(越小越优先)
weight = 2 # 负载均衡权重
# 备用上游(priority=2,仅在主用全部失败后使用)
[[forwarders]]
addr = "8.8.4.4"
port = 53
protocol = "udp"
priority = 2
weight = 1| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
addr | string | 必填 | 上游服务器 IP 地址 |
port | u16 | 53 | 上游服务器端口 |
protocol | string | "udp" | 传输协议(udp/tcp) |
priority | u32 | 1 | 优先级(小 = 高优先) |
weight | u32 | 1 | 同优先级内的负载均衡权重 |
转发策略:按 priority 分组,同组内按 weight 加权轮询。优先级低的组在高级组全部不可用时才使用。
[[conditional-forwards]] 条件转发
toml
# 内网 corp 域名转发到内网 DNS
[[conditional-forwards]]
zone = "internal.corp."
forwarders = ["10.0.0.10", "10.0.0.11"]
# Active Directory 域转发到域控 DNS
[[conditional-forwards]]
zone = "ad.example.com."
forwarders = ["10.0.0.20", "10.0.0.21"]| 配置项 | 类型 | 说明 |
|---|---|---|
zone | string | 域名后缀(匹配时转发到指定上游) |
forwarders | array | 上游服务器 IP 列表 |
匹配规则:最长前缀匹配。查询 a.b.internal.corp. 时,优先匹配 internal.corp. 而非全局转发器。
[acl.*] ACL 定义
toml
# 定义命名 ACL 组
[acl.trusted]
addresses = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
[acl.management]
addresses = ["127.0.0.1", "::1"]
[acl.blocked]
addresses = ["203.0.113.0/24"]支持的特殊关键字:any(所有)、none(无)、localhost(本机)。支持 CIDR 表示法:192.168.1.0/24、::1/128。
[access-control] 访问控制
toml
[access-control]
allow-query = ["trusted", "management"]
allow-recursion = ["trusted"]
allow-transfer = ["management"]| 配置项 | 说明 | 安全要求 |
|---|---|---|
allow-query | 允许查询的 ACL | 建议配置 |
allow-recursion | 允许递归的 ACL | 必填(递归启用时) |
allow-transfer | 允许区域传输的 ACL | 建议限制 |
也支持内联 CIDR,无需单独定义 ACL 组:
toml
[access-control]
allow-query = ["any"] # 全部允许
allow-recursion = ["10.0.0.0/8", "::1/128"] # 内联 CIDR
allow-transfer = ["none"] # 全部禁止空规则行为:
allow-query = []允许所有查询;allow-recursion = []允许所有递归(危险!)。启用递归时强制要求配置allow-recursion,否则拒绝启动。
[[zones]] 权威区域
toml
[[zones]]
name = "example.com"
file = "/etc/tdns/zones/example.com.zone"
type = "master"
allow-transfer = ["management"]
allow-update = ["none"]| 配置项 | 类型 | 说明 |
|---|---|---|
name | string | 区域名称 |
file | path | BIND 格式 Zone 文件路径 |
type | string | 区域类型(master) |
allow-transfer | array | 允许 AXFR 的 ACL |
allow-update | array | 允许 DDNS 更新的 ACL(可填 TSIG 密钥名) |
[api] REST API
toml
[api]
enabled = false
listen = "127.0.0.1:8080"
# auth-token = "your-secret-token" # 必填(enabled=true 时)
# cors-origins = ["https://admin.example.com"]| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | false | 是否启用 API |
listen | string | "127.0.0.1:8080" | API 监听地址(IP:Port) |
auth-token | string | 无 | Bearer Token(必填) |
cors-origins | array | [] | CORS 允许来源(空=禁止跨域) |
安全要求:
api.enabled = true时auth-token必须配置,否则拒绝启动。
注意:
listen是单个IP:Port字符串,不是分开的listen-addr+listen-port。
[metrics] Prometheus 指标
toml
[metrics]
enabled = false
listen = "127.0.0.1:9090"
path = "/metrics"| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | false | 是否启用指标导出 |
listen | string | "127.0.0.1:9090" | 监听地址(默认仅本地) |
path | string | "/metrics" | 指标路径 |
注意:
listen是单个IP:Port字符串。默认仅监听 127.0.0.1,生产环境如需外部抓取请改为内网管理口地址。
[tls] DNS-over-TLS
toml
[tls]
enabled = false
listen-port = 853
# cert = "/etc/tdns/cert.pem" # 必填(enabled=true 时)
# key = "/etc/tdns/key.pem" # 必填(enabled=true 时)| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | false | 是否启用 DoT |
listen-port | u16 | 853 | DoT 监听端口 |
cert | path | 无 | PEM 证书链(必填) |
key | path | 无 | PEM 私钥(必填) |
安全要求:
tls.enabled或doh.enabled为 true 时,cert和key必须配置。
注意:DoT 的监听 IP 复用
server.listen-addrs,仅端口通过tls.listen-port单独指定。字段名是cert和key(不是cert-file/key-file)。
[doh] DNS-over-HTTPS
toml
[doh]
enabled = false
listen-port = 443
path = "/dns-query"| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | false | 是否启用 DoH |
listen-port | u16 | 443 | DoH 监听端口 |
path | string | "/dns-query" | DoH 查询路径 |
DoH 复用
[tls]的证书和私钥,通过 HTTP/2(ALPN h2)提供服务,支持 POST 和 GET 方法。监听 IP 同样复用server.listen-addrs。
[security.rrl] 响应速率限制
toml
[security.rrl]
enabled = true
responses-per-second = 10
slip = 2
window = 5| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | true | 是否启用 RRL |
responses-per-second | u32 | 10 | 每个(前缀, qname)每秒最大响应数 |
slip | u32 | 2 | 每 N 个限速响应中 1 个返回 TC |
window | u32 | 5 | 空闲桶生命周期(秒) |
[[keys]] TSIG 密钥
toml
[[keys]]
name = "update-key."
algorithm = "hmac-sha256"
secret = "<base64-encoded-secret>"| 配置项 | 类型 | 说明 |
|---|---|---|
name | string | 密钥名称 |
algorithm | string | 算法(当前仅支持 hmac-sha256) |
secret | string | Base64 编码的密钥 |
用于认证 DDNS 动态更新请求(RFC 2136)。生成密钥:
bash
# 使用 tsig-keygen(BIND 工具)
tsig-keygen -a HMAC-SHA256 update-key
# 或手动生成
echo -n "your-secret" | base64[dnssec] DNSSEC
toml
[dnssec]
enabled = false| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | bool | false | DNSSEC 框架占位(尚未完整实现) |
完整配置示例
最小开发配置
toml
[server]
listen-addrs = ["127.0.0.1"]
listen-port = 10053
mode = "hybrid"
log-level = "debug"
log-format = "text"
[cache]
enabled = true
max-size = "256MB"
[recursion]
enabled = true
[[forwarders]]
addr = "8.8.8.8"
port = 53
[access-control]
allow-query = ["any"]
allow-recursion = ["any"]
[api]
enabled = true
listen = "127.0.0.1:8080"
auth-token = "dev-token"开发环境中的
allow-recursion = ["any"]和auth-token = "dev-token"仅适用于本机测试,生产环境必须使用具体的 ACL 规则和强密码 Token。
生产转发配置
toml
[server]
listen-addrs = ["0.0.0.0", "::"]
listen-port = 53
mode = "forwarder"
workers = 0
log-level = "info"
log-format = "json"
[[forwarders]]
addr = "8.8.8.8"
port = 53
priority = 1
weight = 1
[[forwarders]]
addr = "1.1.1.1"
port = 53
priority = 1
weight = 1
[acl.trusted]
addresses = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
[access-control]
allow-query = ["trusted"]
allow-recursion = ["trusted"]
[security.rrl]
enabled = true
responses-per-second = 20
[api]
enabled = true
listen = "127.0.0.1:8080"
auth-token = "change-me-to-a-long-random-string"
[metrics]
enabled = true
listen = "127.0.0.1:9090"完整加密传输配置
toml
[server]
mode = "recursive"
listen-addrs = ["0.0.0.0", "::"]
listen-port = 53
[recursion]
enabled = true
[access-control]
allow-query = ["any"]
allow-recursion = ["any"]
[tls]
enabled = true
listen-port = 853
cert = "/etc/tdns/cert.pem"
key = "/etc/tdns/key.pem"
[doh]
enabled = true
listen-port = 443
path = "/dns-query"
[api]
enabled = true
listen = "127.0.0.1:8080"
auth-token = "your-secret-token"
[metrics]
enabled = true
listen = "127.0.0.1:9090"完整配置项参考随包发布的
etc/tdns.toml.example。