10 KiB
DDNS 真实操作功能实现报告
📋 实现概述
本次实现完成了 DDNS 真实 DNS 记录操作 的核心功能,集成了 libdns 库,支持多个主流 DNS 服务商的 API 调用。
✅ 已完成的工作
1. 安装 libdns 库
已安装的库
✅ github.com/libdns/cloudflare v0.2.2
✅ github.com/libdns/tencentcloud v1.4.3
✅ github.com/libdns/libdns v1.1.0
待安装的库(网络问题)
⏳ github.com/libdns/aliyun - 网络超时,暂时使用占位实现
2. 创建 DNS Provider 抽象层
文件结构
internal/dnsprovider/
├── provider.go # 核心接口和类型定义
├── cloudflare.go # Cloudflare 实现
├── tencentcloud.go # 腾讯云实现
└── aliyun.go # 阿里云实现(占位)
核心接口设计
DNSProvider 接口:
type DNSProvider interface {
AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
SetRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
GetRecords(ctx context.Context, zone string) ([]libdns.Record, error)
DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
}
统一工厂方法:
func NewDNSProvider(config ProviderConfig) (DNSProvider, error) {
switch config.Provider {
case ProviderCloudflare:
return NewCloudflareProvider(config)
case ProviderAliyun:
return NewAliyunProvider(config)
case ProviderTencentCloud:
return NewTencentCloudProvider(config)
}
}
3. 各服务商实现详情
Cloudflare 实现 ✅
文件: internal/dnsprovider/cloudflare.go
配置要求:
- API Token(必需)
- 根域名
实现状态:
- ✅ AppendRecords - 添加记录
- ✅ SetRecords - 设置记录(覆盖)
- ✅ GetRecords - 获取记录
- ✅ DeleteRecords - 删除记录
代码示例:
provider := &cloudflare.Provider{
APIToken: "YOUR_API_TOKEN",
}
腾讯云实现 ✅
文件: internal/dnsprovider/tencentcloud.go
配置要求:
- SecretId(必需)
- SecretKey(必需)
实现状态:
- ✅ AppendRecords - 添加记录
- ✅ SetRecords - 设置记录(覆盖)
- ✅ GetRecords - 获取记录
- ✅ DeleteRecords - 删除记录
代码示例:
provider := &tencentcloud.Provider{
SecretId: "AKIDxxxx",
SecretKey: "SECRET_KEY",
}
阿里云实现 ⏳(占位)
文件: internal/dnsprovider/aliyun.go
配置要求:
- AccessKey ID(必需)
- AccessKey Secret(必需)
实现状态:
- ⏳ 暂时返回错误提示"暂未支持"
- ⏳ 待网络恢复后安装 libdns/aliyun 并实现
TODO 代码:
// TODO: 安装 github.com/libdns/aliyun 后,替换为真实实现
provider := &aliyun.Provider{
AccessKeyID: config.AccessKeyID,
AccessKeySecret: config.AccessKeySecret,
}
4. DDNS 操作服务封装
文件
internal/service/ddns_operation.go
核心功能
CreateDNSRecord - 创建 DNS 记录:
func (s *DDNSOperationService) CreateDNSRecord(
config *model.Service, // DDNS 全功能服务配置
recordType string, // A/AAAA/TXT/CNAME
name string, // 主机记录
value string, // 记录值
ttl int // TTL
) error
UpdateDNSRecord - 更新 DNS 记录:
func (s *DDNSOperationService) UpdateDNSRecord(...) error
DeleteDNSRecord - 删除 DNS 记录:
func (s *DDNSOperationService) DeleteDNSRecord(...) error
操作流程
1. 获取关联的 DDNS 配置
↓
2. 创建对应的 DNS Provider
↓
3. 构建 DNS 记录
↓
4. 调用 Provider API
↓
5. 记录日志
🎯 使用示例
场景 1: 创建 A 记录(内网穿透)
// 假设用户在前端填写了:
// - 选择 DDNS 配置:Cloudflare (example.com)
// - 记录类型:A
// - 主机记录:nas
// - 目标 IP: 192.168.1.100
// - TTL: 600
service := &model.Service{
DDNSConfigID: "xxx-xxx-xxx", // 关联的 DDNS 配置 ID
RecordType: "A",
Subdomain: "nas",
TargetIP: "192.168.1.100",
TTL: 600,
}
// 创建记录
err := ddnsOpService.CreateDNSRecord(service, "A", "nas", "192.168.1.100", 600)
if err != nil {
log.Error("创建失败", err)
}
// 结果:创建了 nas.example.com 的 A 记录,指向 192.168.1.100
场景 2: 更新 TXT 记录(MeshSeed 同步)
// 当检测到本地 IP 变化时,自动更新记录
service := &model.Service{
DDNSConfigID: "xxx-xxx-xxx",
RecordType: "TXT",
TXTRecordName: "_meshray.abc123",
TXTValue: "new_mesh_seed_config",
TTL: 600,
}
// 更新记录
err := ddnsOpService.UpdateDNSRecord(service, "TXT", "_meshray.abc123", "new_mesh_seed_config", 600)
if err != nil {
log.Error("更新失败", err)
}
// 结果:更新了 _meshray.abc123.example.com 的 TXT 记录
场景 3: 删除 CNAME 记录
service := &model.Service{
DDNSConfigID: "xxx-xxx-xxx",
RecordType: "CNAME",
Subdomain: "www",
}
// 删除记录
err := ddnsOpService.DeleteDNSRecord(service, "CNAME", "www")
if err != nil {
log.Error("删除失败", err)
}
// 结果:删除了 www.example.com 的 CNAME 记录
📊 技术架构
分层架构
API Handler 层
↓
Service 层(业务逻辑)
↓
DDNSOperationService
↓
DNS Provider 抽象层
↓
libdns 库实现
↓
DNS 服务商 API
设计模式
工厂模式:
NewDNSProvider(config) → DNSProvider
├─ CloudflareProvider
├─ TencentCloudProvider
└─ AliyunProvider(待实现)
适配器模式:
DNSRecord (内部模型)
↓ ToLibdnsRecord()
libdns.Record (第三方库模型)
🔧 依赖管理
go.mod 新增依赖
require (
github.com/libdns/cloudflare v0.2.2
github.com/libdns/libdns v1.1.0
github.com/libdns/tencentcloud v1.4.3
)
待添加依赖
// 网络恢复后执行:
go get github.com/libdns/aliyun
✅ 验证清单
编译验证
- 代码编译成功
- 无语法错误
- 依赖安装正确
- 导入路径正确
功能验证(待测试)
- Cloudflare API 调用成功
- 腾讯云 API 调用成功
- 阿里云 API 调用(等待安装)
- 创建 A 记录成功
- 更新 TXT 记录成功
- 删除记录成功
🚀 下一步计划
P0 - 完善阿里云支持
任务: 安装 libdns/aliyun 并完成实现
预计工时: 0.5 天
依赖: 网络环境
步骤:
- 执行
go get github.com/libdns/aliyun - 修改
aliyun.go使用真实实现 - 测试 API 调用
P0 - 集成到 Service 创建流程
任务: 在创建 DDNS 全功能服务时自动创建 DNS 记录
预计工时: 0.5 天
依赖: 无
修改文件:
internal/service/service.go- CreateService 方法
伪代码:
func (s *ServiceService) CreateService(req *model.Service) (*model.Service, error) {
// ... 现有校验逻辑 ...
// 如果是 DDNS 全功能模式,创建 DNS 记录
if req.Type == "DDNS" && req.ConfigMode == "fullservice" {
ddnsOpService := NewDDNSOperationService(s.logger)
var recordType string
var name string
var value string
switch req.RecordType {
case "A", "AAAA":
recordType = req.RecordType
name = req.Subdomain
value = req.TargetIP
case "TXT":
recordType = req.RecordType
name = req.TXTRecordName
value = req.TXTValue
case "CNAME":
recordType = req.RecordType
name = req.Subdomain
value = req.CNAMETarget
}
err := ddnsOpService.CreateDNSRecord(req, recordType, name, value, req.TTL)
if err != nil {
return nil, fmt.Errorf("创建 DNS 记录失败:%w", err)
}
}
// ... 保存到数据库 ...
}
P1 - IP 检测与自动更新
任务: 实现本地 IP 检测和自动更新 DNS 记录
预计工时: 1 天
依赖: DDNS 操作服务完成
子任务:
- 实现 IPv4 地址检测(调用外部 API)
- 实现 IPv6 地址检测(读取本地网络接口)
- 实现 IP 变化监控(定时比对)
- 实现自动更新 DNS 记录
- 实现失败重试机制
P1 - 后台任务调度
任务: 实现定时任务调度器
预计工时: 1 天
依赖: IP 检测完成
子任务:
- 实现定时器框架(goroutine + ticker)
- 批量检测所有启用的 DDNS 服务
- 批量更新 DNS 记录
- 记录操作日志
- 发送告警通知(可选)
P2 - 前后端联调测试
任务: 完整的集成测试
预计工时: 1 天
依赖: 所有功能完成
测试项:
- 创建真实的 Cloudflare DNS 记录
- 创建真实的腾讯云 DNS 记录
- 测试 IP 检测和自动更新
- 性能测试(批量创建/更新)
- 错误处理和恢复
📝 注意事项
安全性
- ⚠️ API Token/Secret 需要加密存储
- ⚠️ 日志中需要脱敏处理
- ⚠️ 避免在错误信息中泄露敏感数据
性能优化
- ⚠️ 使用连接池复用 HTTP 客户端
- ⚠️ 批量操作时使用并发(注意限流)
- ⚠️ 缓存 DNS Provider 实例
错误处理
- ⚠️ DNS API 调用失败需要有重试机制
- ⚠️ 网络异常需要友好提示用户
- ⚠️ 记录详细的操作日志便于排查
🎉 总结
本次实现完成了 DDNS 真实 DNS 记录操作的核心框架:
✅ libdns 库集成 - Cloudflare、腾讯云已支持
✅ Provider 抽象层 - 统一的接口设计
✅ 操作服务封装 - Create/Update/Delete 完整功能
✅ 编译验证通过 - 无错误
当前状态: 可以开始测试真实的 DNS 服务商 API 调用。
下一步重点:
- 集成到 Service 创建流程
- 实现 IP 检测和自动更新
- 后台任务调度
实现日期: 2026-03-20
实现人员: AI Assistant
实现状态: ✅ 核心框架完成,等待集成和测试
文档版本: v1.0