Skip to content

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/metricsPrometheus 指标

健康检查 ​

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

请求体字段:

字段类型必填说明
namestring是记录名称(相对或绝对域名)
typestring是记录类型(见下表)
ttlnumber是TTL(秒)
datastring是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 支持示例
AIPv4 地址✅"192.0.2.10"
AAAAIPv6 地址✅"2001:db8::10"
CNAME目标域名✅"example.com."
NS名称服务器✅"ns1.example.com."
PTR指针域名✅"host.example.com."
TXT文本字符串✅"v=spf1 include:_spf.example.com ~all"
SVCB/HTTPSSVCB 参数✅—
MX优先级 + 邮件交换❌需通过 Zone 文件添加
SOASOA 字段❌需通过 Zone 文件添加
SRV优先级 权重 端口 目标❌需通过 Zone 文件添加
CAACA 授权❌需通过 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

行为:

  1. 读取并解析配置文件(tdns.toml)
  2. 验证配置
  3. 从配置中的 Zone 文件路径重新构建区域目录
  4. 原子替换共享状态中的配置和区域目录
  5. 缓存和 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" | jq

GSLB 动态调度示例 ​

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" | jq

CORS ​

REST API 启用了 CORS(CorsLayer::permissive),允许浏览器跨域请求。Web 管理面板可直接调用 API。需要限制跨域来源时配置:

toml
[api]
cors-origins = ["https://admin.example.com"]

API 本身不设速率限制。建议在生产环境中通过反向代理(如 Nginx)添加 API 速率限制和 IP 白名单。