外观
13 - REST API 参考
概述
TDNS 提供基于 HTTP/JSON 的 REST API,用于服务器管理、区域记录操作、缓存管理和配置热重载。API 基于 axum 框架实现,所有请求使用 Bearer Token 认证。
快速上手
1. 开启 API
toml
# /etc/tdns/tdns.toml
[api]
enabled = true
listen = "127.0.0.1:8080" # 单个 IP:Port 字符串
auth-token = "your-secret-token" # 启用 API 时必填2. 设置环境变量(可选)
bash
export TDNS_API_TOKEN="your-secret-token"3. 使用 curl 管理记录
bash
TOKEN="your-secret-token"
BASE="http://127.0.0.1:8080"
# 健康检查
curl -s $BASE/api/v1/health
# 查看服务器状态
curl -s -H "Authorization: Bearer $TOKEN" $BASE/api/v1/server | jq
# 添加 A 记录(区域不存在会自动创建)
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"www.example.com","type":"A","ttl":300,"data":"192.0.2.10"}' \
$BASE/api/v1/zones/example.com/records | jq
# 验证
dig @127.0.0.1 www.example.com A认证
所有 API 请求必须在 HTTP 头中携带 Bearer Token:
Authorization: Bearer <token>Token 在配置文件中设置:
toml
[api]
enabled = true
listen = "127.0.0.1:8080"
auth-token = "your-secure-token" # 必填未携带或 Token 不匹配的请求返回 401 Unauthorized。
API 端点总览
| 方法 | 路径 | 功能 |
|---|---|---|
| GET | /api/v1/health | 健康检查 |
| GET | /api/v1/server | 服务器信息 |
| GET | /api/v1/cache/stats | 缓存统计 |
| POST | /api/v1/cache/flush | 清空全部缓存 |
| POST | /api/v1/cache/flush/:name | 清空指定域名缓存 |
| GET | /api/v1/zones | 列出所有区域 |
| GET | /api/v1/zones/:zone/records | 列出区域记录 |
| POST | /api/v1/zones/:zone/records | 添加记录(区域不存在自动创建) |
| DELETE | /api/v1/zones/:zone/records/:name/:type | 删除记录 |
| POST | /api/v1/reload | 热重载配置和区域 |
| GET | /metrics | Prometheus 指标 |
健康检查
GET /api/v1/health
检查服务器是否正常运行(无需认证)。
bash
curl -s http://127.0.0.1:8080/api/v1/health响应:
json
{
"status": "ok"
}服务器信息
GET /api/v1/server
获取服务器运行状态和配置摘要。
bash
curl -s -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/server | jq响应:
json
{
"version": "0.1.1",
"mode": "Hybrid",
"listen_port": 53,
"listen_addrs": ["0.0.0.0", "::"],
"uptime_secs": 86400,
"cache_enabled": true,
"recursion_enabled": true,
"forwarders": ["8.8.8.8", "1.1.1.1"],
"zones": 3
}缓存管理
GET /api/v1/cache/stats
bash
curl -s -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/cache/stats | jq响应:
json
{
"hits": 85234,
"misses": 14766,
"inserts": 15000,
"evictions": 234,
"hit_rate": 0.8523,
"positive_entries": 12000,
"negative_entries": 3000
}POST /api/v1/cache/flush
清空全部缓存(正向缓存 + 负缓存)。
bash
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/cache/flush | jq响应:
json
{
"status": "ok",
"flushed_positive": 12000,
"flushed_negative": 3000
}POST /api/v1/cache/flush/:name
清空指定域名的缓存条目。
bash
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/cache/flush/www.example.com | jq响应:
json
{
"status": "ok",
"flushed_name": "www.example.com"
}区域管理
GET /api/v1/zones
列出所有已加载的区域。
bash
curl -s -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/zones | jq响应:
json
{
"zones": [
{
"origin": "example.com.",
"record_count": 25
},
{
"origin": "internal.corp.",
"record_count": 10
}
],
"count": 2
}GET /api/v1/zones/:zone/records
列出指定区域的所有记录。
bash
curl -s -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/zones/example.com/records | jq响应:
json
{
"zone": "example.com.",
"records": [
{
"name": "example.com.",
"type": "SOA",
"ttl": 3600,
"rdata": "ns1.example.com. admin.example.com. 2026071401 3600 1800 604800 86400"
},
{
"name": "www.example.com.",
"type": "A",
"ttl": 300,
"rdata": "192.0.2.10"
}
],
"count": 2
}POST /api/v1/zones/:zone/records
向区域添加 DNS 记录。如果区域不存在,自动创建。
bash
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"www.example.com","type":"A","ttl":300,"data":"192.0.2.10"}' \
http://127.0.0.1:8080/api/v1/zones/example.com/records | jq请求体字段:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name | string | 是 | 记录名称(相对或绝对域名) |
type | string | 是 | 记录类型(见下表) |
ttl | number | 是 | TTL(秒) |
data | string | 是 | RDATA(记录值,格式取决于类型) |
响应:
json
{
"status": "ok",
"record": {
"name": "www.example.com.",
"type": "A",
"ttl": 300,
"data": "192.0.2.10"
}
}DELETE /api/v1/zones/:zone/records/:name/:type
删除指定区域的记录。
bash
curl -s -X DELETE \
-H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/zones/example.com/records/www.example.com/A | jq响应:
json
{
"status": "ok",
"deleted": 1
}deleted 字段表示删除的记录数。0 表示记录不存在。
记录类型与 RDATA 格式
| 类型 | data 格式 | API 支持 | 示例 |
|---|---|---|---|
| A | IPv4 地址 | ✅ | "192.0.2.10" |
| AAAA | IPv6 地址 | ✅ | "2001:db8::10" |
| CNAME | 目标域名 | ✅ | "example.com." |
| NS | 名称服务器 | ✅ | "ns1.example.com." |
| PTR | 指针域名 | ✅ | "host.example.com." |
| TXT | 文本字符串 | ✅ | "v=spf1 include:_spf.example.com ~all" |
| SVCB/HTTPS | SVCB 参数 | ✅ | — |
| MX | 优先级 + 邮件交换 | ❌ | 需通过 Zone 文件添加 |
| SOA | SOA 字段 | ❌ | 需通过 Zone 文件添加 |
| SRV | 优先级 权重 端口 目标 | ❌ | 需通过 Zone 文件添加 |
| CAA | CA 授权 | ❌ | 需通过 Zone 文件添加 |
TXT 类型支持单字符串和多引号格式:
"hello world"或"hello" "world"
配置热重载
POST /api/v1/reload
重新加载配置文件和所有 Zone 文件,原子替换区域目录。
bash
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
http://127.0.0.1:8080/api/v1/reload | jq行为:
- 读取并解析配置文件(
tdns.toml) - 验证配置
- 从配置中的 Zone 文件路径重新构建区域目录
- 原子替换共享状态中的配置和区域目录
- 缓存和 ACL 等运行时状态保持不变
响应:
json
{
"status": "ok",
"zones_reloaded": 3
}错误响应:
json
{
"error": "failed to load config: <error message>"
}配置加载或验证失败时返回 500,不影响当前运行的配置。
错误响应格式
所有 API 错误使用统一的 JSON 格式:
json
{
"error": "错误描述"
}| HTTP 状态码 | 含义 |
|---|---|
| 400 | 请求参数错误(不支持的记录类型、无效的 RDATA) |
| 401 | 未认证或 Token 无效 |
| 404 | 资源不存在(区域或记录未找到) |
| 413 | 请求体过大(DoH 专用) |
| 500 | 内部错误(配置加载失败、区域目录构建失败) |
完整使用示例
记录管理流程
bash
TOKEN="your-secret-token"
BASE="http://127.0.0.1:8080"
# 查看服务器状态
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/api/v1/server" | jq
# 列出区域
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/api/v1/zones" | jq
# 添加 A 记录
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"www.example.com","type":"A","ttl":300,"data":"192.0.2.10"}' \
"$BASE/api/v1/zones/example.com/records" | jq
# 添加 AAAA 记录
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"www.example.com","type":"AAAA","ttl":300,"data":"2001:db8::10"}' \
"$BASE/api/v1/zones/example.com/records" | jq
# 添加 TXT 记录
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"example.com","type":"TXT","ttl":3600,"data":"v=spf1 -all"}' \
"$BASE/api/v1/zones/example.com/records" | jq
# 列出区域所有记录
curl -s -H "Authorization: Bearer $TOKEN" \
"$BASE/api/v1/zones/example.com/records" | jq
# 验证
dig @127.0.0.1 www.example.com A
dig @127.0.0.1 www.example.com AAAA
dig @127.0.0.1 example.com TXT
# 删除记录
curl -s -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"$BASE/api/v1/zones/example.com/records/www.example.com/A" | jq
# 热重载
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
"$BASE/api/v1/reload" | jq
# 清空全部缓存
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
"$BASE/api/v1/cache/flush" | jq
# 清空特定域名缓存
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
"$BASE/api/v1/cache/flush/www.example.com" | jqGSLB 动态调度示例
bash
# 健康检查通过时添加节点
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"node1.cdn.example.com","type":"A","ttl":5,"data":"192.0.2.10"}' \
"$BASE/api/v1/zones/cdn.example.com/records" | jq
# 健康检查失败时删除节点
curl -s -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"$BASE/api/v1/zones/cdn.example.com/records/node1.cdn.example.com/A" | jqCORS
REST API 启用了 CORS(CorsLayer::permissive),允许浏览器跨域请求。Web 管理面板可直接调用 API。需要限制跨域来源时配置:
toml
[api]
cors-origins = ["https://admin.example.com"]API 本身不设速率限制。建议在生产环境中通过反向代理(如 Nginx)添加 API 速率限制和 IP 白名单。