外观
05 - 部署指南
TDNS 支持三种部署方式:systemd 裸机部署、Docker 单容器部署、Docker Compose 编排部署。
方式一:systemd 裸机部署
1. 安装二进制
bash
tar xzf tdns-0.1.1-linux-x86_64.tar.gz
cd tdns-0.1.1-linux-x86_64
sudo cp bin/tdns bin/tdnsctl /usr/local/bin/
sudo chmod +x /usr/local/bin/tdns /usr/local/bin/tdnsctl2. 创建系统用户
bash
sudo groupadd -r tdns
sudo useradd -r -g tdns -d /var/lib/tdns -s /sbin/nologin -c "TDNS DNS Server" tdns3. 创建目录结构
bash
sudo mkdir -p /etc/tdns/zones /var/lib/tdns /var/log/tdns /var/run/tdns
sudo chown -R tdns:tdns /etc/tdns /var/lib/tdns /var/log/tdns /var/run/tdns4. 部署配置文件
bash
sudo cp etc/tdns.toml.example /etc/tdns/tdns.toml
sudo cp etc/root.hints /etc/tdns/root.hints
sudo vim /etc/tdns/tdns.toml生产环境必须调整的配置项:
toml
[server]
listen-port = 53 # systemd 通过 AmbientCapabilities 自动授权
log-format = "json" # 结构化日志便于采集
[access-control]
allow-recursion = ["trusted"] # 必填,仅允许受信任客户端
[api]
enabled = true
auth-token = "<随机密钥>" # 必填,生成方式:openssl rand -hex 32
[tls] # 启用时必须配 cert 和 key
enabled = true
cert = "/etc/tdns/cert.pem"
key = "/etc/tdns/key.pem"5. 安装 systemd 服务
bash
sudo cp deploy/tdns.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable tdns
sudo systemctl start tdns
sudo systemctl status tdns服务文件特性(deploy/tdns.service):
| 特性 | 说明 |
|---|---|
| 非 root 用户运行 | User=tdns Group=tdns |
| 特权端口授权 | AmbientCapabilities=CAP_NET_BIND_SERVICE |
| 安全加固 | NoNewPrivileges=true |
| 文件系统隔离 | ProtectSystem=strict + ProtectHome=true |
| 读写限制 | ReadWritePaths 仅限数据/日志/PID 目录 |
| 文件描述符 | LimitNOFILE=65536 |
6. 防火墙配置
bash
# firewalld
sudo firewall-cmd --permanent --add-service=dns # 53/udp+tcp
sudo firewall-cmd --permanent --add-port=853/tcp # DoT(如启用)
sudo firewall-cmd --permanent --add-port=443/tcp # DoH(如启用)
sudo firewall-cmd --permanent --add-port=8080/tcp # API(限内网)
sudo firewall-cmd --reload
# 或用 iptables
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 853 -j ACCEPT # DoT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT # DoH7. 验证
bash
# DNS 解析验证
dig @127.0.0.1 example.com A +short
# 健康检查(需启用 API)
curl http://127.0.0.1:8080/api/v1/health
# 服务状态
sudo systemctl status tdns方式二:Docker 部署
构建镜像
bash
docker build -t tdns:0.1.1 .
docker tag tdns:0.1.1 tdns:latestDockerfile 特性:
| 特性 | 说明 |
|---|---|
| 多阶段构建 | rust:1.75-slim-bookworm → debian:bookworm-slim |
| 非 root 用户 | tdns 用户运行 |
| 特权端口授权 | setcap 'cap_net_bind_service=+ep' |
| 内置健康检查 | API 优先,PID 回退 |
| 镜像大小 | 约 80 MB |
运行容器
bash
docker run -d \
--name tdns \
--restart unless-stopped \
--cap-add=NET_BIND_SERVICE \
-p 53:53/udp \
-p 53:53/tcp \
-p 853:853/tcp \
-p 443:443/tcp \
-p 8080:8080/tcp \
-v /etc/tdns:/etc/tdns:ro \
-v /var/lib/tdns:/var/lib/tdns \
-e TDNS_API_TOKEN=your-secret \
tdns:latest853/443 端口仅在
[tls]/[doh]enabled = true 时需要映射。
验证
bash
# 查看容器状态
docker ps | grep tdns
# 查看日志
docker logs -f tdns
# DNS 解析验证
dig @127.0.0.1 example.com
# 健康检查
curl http://127.0.0.1:8080/api/v1/health方式三:Docker Compose 部署
编写配置
yaml
# deploy/docker-compose.yml
version: "3.8"
services:
tdns:
build:
context: ..
dockerfile: Dockerfile
container_name: tdns
restart: unless-stopped
ports:
- "53:53/udp"
- "53:53/tcp"
- "853:853/tcp"
- "443:443/tcp"
- "8080:8080/tcp"
volumes:
- ./tdns.toml:/etc/tdns/tdns.toml:ro
- ../etc/root.hints:/etc/tdns/root.hints:ro
- tdns-data:/var/lib/tdns
healthcheck:
test: ["CMD-SHELL", "tdnsctl --api http://127.0.0.1:8080 status 2>/dev/null || kill -0 \"$$(cat /var/run/tdns/tdns.pid 2>/dev/null)\" 2>/dev/null || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
volumes:
tdns-data:操作命令
bash
cd deploy/
# 准备配置
cp ../etc/tdns.toml.example tdns.toml
vim tdns.toml
# 构建并启动
docker compose up -d --build
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f tdns
# 停止
docker compose down
# 更新(重新构建)
docker compose down
docker compose up -d --build特权端口授权说明
DNS 标准端口 53 是特权端口(< 1024),而 TDNS 以非 root 用户运行。授权方式取决于部署方式:
| 部署方式 | 授权机制 | 说明 |
|---|---|---|
| Docker | setcap 'cap_net_bind_service=+ep' | Dockerfile 中自动设置 |
| systemd | AmbientCapabilities=CAP_NET_BIND_SERVICE | service 文件中自动设置 |
| 手动部署 | sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/tdns | 需手动执行 |
| 开发测试 | listen-port = 5353 | 用非特权端口规避 |
当
NoNewPrivileges=true生效时(如 systemd 服务),setcap文件能力会被内核忽略,必须使用AmbientCapabilities代替。
目录结构参考
/etc/tdns/ # 配置目录
├── tdns.toml # 主配置文件
├── root.hints # 根服务器提示文件
├── cert.pem # TLS 证书(如启用 DoT/DoH)
├── key.pem # TLS 私钥(如启用 DoT/DoH)
└── zones/ # 区域数据文件
└── example.com.zone
/var/lib/tdns/ # 数据目录(SQLite 等)
/var/log/tdns/ # 日志目录
/var/run/tdns/ # PID 文件
/usr/local/bin/tdns # 服务器二进制
/usr/local/bin/tdnsctl # 管理工具二进制
/etc/systemd/system/tdns.service # systemd 服务文件下一步
- 了解各运行模式怎么配 → 06-运行模式详解
- 管理域名解析记录 → 07-权威DNS服务
- 配置加密传输 → 11-加密传输指南
- 日常运维操作 → 16-运维操作手册