🌐 DDNS API 使用文档

代码位置: handle/ddns.go

📑 目录

📋 概述

DDNS (Dynamic DNS) API 允许用户通过 API 动态更新 DNS 记录,特别适用于家庭宽带、动态 IP 等场景。

⚠️ 重要限制:DDNS 功能仅支持子域名的动态更新(如 blog.example.com),不支持一级域名(如 example.com)。

🔗 API 端点

GET POST /api/ddns/update

📝 请求参数

参数 类型 必填 说明
domain string 完整子域名,例如:blog.example.com(️ 不支持一级域名
ip string 新的 IP 地址。如果不提供,将自动使用请求来源的 IP 地址
token string 用户API Token(登录后在个人中心首页,点击顶部导航栏的 "API Token" 标签页查看)

🔖 支持的记录类型

  • A 记录(IPv4 地址)
  • AAAA 记录(IPv6 地址)

系统会自动检测 IP 地址类型并使用相应的记录类型。

📤 响应格式

成功响应

HTTP 状态码: 200
{
  "success": true,
  "message": "DDNS 更新成功",
  "data": {
    "domain": "blog.example.com",
    "ip": "192.168.1.100",
    "record_type": "A",
    "old_ip": "192.168.1.99",
    "updated": true
  }
}

IP 未变化

{
  "success": true,
  "message": "IP 地址未变化,无需更新",
  "data": {
    "domain": "blog.example.com",
    "ip": "192.168.1.100",
    "updated": false
  }
}

错误响应

HTTP 状态码: 400/401/403/404/500
{
  "success": false,
  "error": "错误描述信息"
}

常见错误代码

HTTP 状态码 错误信息 说明
400 DDNS 功能仅支持子域名,不支持一级域名 尝试更新一级域名(如 example.com),请使用子域名格式
400 缺少 domain 参数 未提供域名参数
400 缺少 token 参数 未提供认证 token
400 无效的 IP 地址格式 提供的 IP 地址格式不正确
401 无效的 token API Token 无效或不存在
403 用户账号已被临时/永久封禁 用户账号状态异常
403 域名记录已被禁用 / 一级域名已被禁用 域名处于禁用状态
404 域名不存在或无权操作 域名不存在,或当前用户无权限操作该域名
400 IP 类型不匹配 请求的 IP 类型(IPv4/IPv6)与域名配置不匹配
500 更新 DNS 服务器失败 / 更新数据库失败 服务器内部错误

💡 使用示例

提示:使用前请确保您已获取 API Token

获取步骤:
  1. 访问 https://pwdns.org/user/dashboard 并登录
  2. 登录后会自动跳转到个人中心首页
  3. 点击页面顶部导航栏的 "API Token" 标签
  4. 即可查看您的 API Token

1. cURL 命令

自动检测当前 IP 并更新
# 自动检测当前 IP 并更新
curl -X GET "https://pwdns.org/api/ddns/update?domain=blog.example.com&token=your_api_token"

# 指定 IP 地址更新
curl -X GET "https://pwdns.org/api/ddns/update?domain=blog.example.com&ip=192.168.1.100&token=your_api_token"

# IPv6 地址更新
curl -X GET "https://pwdns.org/api/ddns/update?domain=blog.example.com&ip=2001:db8::1&token=your_api_token"

2. Linux/Mac 脚本

ddns_update.sh
#!/bin/bash

# 配置
DOMAIN="blog.example.com"
API_TOKEN="your_api_token"
DDNS_URL="https://pwdns.org/api/ddns/update"

# 获取当前公网 IP(使用多个服务以提高可靠性)
CURRENT_IP=$(curl -s https://api.ipify.org || curl -s https://ifconfig.me || curl -s https://icanhazip.com)

if [ -z "$CURRENT_IP" ]; then
    echo "错误:无法获取当前公网 IP"
    exit 1
fi

echo "当前 IP: $CURRENT_IP"

# 更新 DDNS
RESPONSE=$(curl -s -G "$DDNS_URL" \
  --data-urlencode "domain=$DOMAIN" \
  --data-urlencode "ip=$CURRENT_IP" \
  --data-urlencode "token=$API_TOKEN")

echo "响应:$RESPONSE"

# 检查是否成功
if echo "$RESPONSE" | grep -q '"success":true'; then
    echo "DDNS 更新成功!"
else
    echo "DDNS 更新失败:$RESPONSE"
    exit 1
fi

3. Windows PowerShell

ddns_update.ps1
# 配置
$Domain = "blog.example.com"
$ApiToken = "your_api_token"
$DdnsUrl = "https://pwdns.org/api/ddns/update"

# 获取当前公网 IP
try {
    $CurrentIp = Invoke-RestMethod -Uri "https://api.ipify.org?format=json" | Select-Object -ExpandProperty ip
} catch {
    Write-Error "无法获取当前公网 IP"
    exit 1
}

Write-Host "当前 IP: $CurrentIp"

# 更新 DDNS
try {
    $Response = Invoke-RestMethod -Uri "$DdnsUrl?domain=$Domain&ip=$CurrentIp&token=$ApiToken" -Method Get
    
    if ($Response.success) {
        Write-Host "DDNS 更新成功!"
        Write-Host "新 IP: $($Response.data.ip)"
        if ($Response.data.updated) {
            Write-Host "旧 IP: $($Response.data.old_ip)"
        }
        Write-Host "记录类型:$($Response.data.record_type)"
    } else {
        Write-Error "DDNS 更新失败:$($Response.error)"
        exit 1
    }
} catch {
    Write-Error "请求失败:$_"
    exit 1
}

4. Python 脚本

ddns_update.py
#!/usr/bin/env python3
import requests
import sys

# 配置
DOMAIN = "blog.example.com"
API_TOKEN = "your_api_token"
DDNS_URL = "https://pwdns.org/api/ddns/update"

def get_public_ip():
    """获取公网 IP"""
    services = [
        "https://api.ipify.org?format=json",
        "https://ifconfig.me/ip",
        "https://icanhazip.com"
    ]
    
    for service in services:
        try:
            response = requests.get(service, timeout=5)
            if service == "https://api.ipify.org?format=json":
                return response.json().get('ip')
            else:
                return response.text.strip()
        except Exception as e:
            print(f"获取 IP 失败 ({service}): {e}")
            continue
    
    return None

def update_ddns(ip):
    """更新 DDNS"""
    params = {
        'domain': DOMAIN,
        'ip': ip,
        'token': API_TOKEN
    }
    
    try:
        response = requests.get(DDNS_URL, params=params, timeout=10)
        result = response.json()
        
        if result.get('success'):
            print(f"✓ DDNS 更新成功!")
            print(f"  域名:{result['data']['domain']}")
            print(f"  IP: {result['data']['ip']}")
            print(f"  记录类型:{result['data'].get('record_type', 'N/A')}")
            if result['data'].get('old_ip'):
                print(f"  旧 IP: {result['data']['old_ip']}")
            return True
        else:
            print(f"✗ DDNS 更新失败:{result.get('error')}")
            return False
    except Exception as e:
        print(f"✗ 请求失败:{e}")
        return False

if __name__ == "__main__":
    # 获取当前 IP
    current_ip = get_public_ip()
    if not current_ip:
        print("错误:无法获取公网 IP")
        sys.exit(1)
    
    print(f"当前 IP: {current_ip}")
    
    # 更新 DDNS
    success = update_ddns(current_ip)
    sys.exit(0 if success else 1)

⏰ 定时任务配置

Linux Crontab

每 5 分钟执行一次
# 编辑 crontab
crontab -e

# 添加以下行
*/5 * * * * /path/to/ddns_script.sh >> /var/log/ddns.log 2>&1

Windows 任务计划程序

创建计划任务
# 创建计划任务(每 5 分钟执行一次)
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\path\to\ddns_script.ps1"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask -TaskName "DDNS Update" -Action $action -Trigger $trigger -User "SYSTEM"

🔒 安全建议

1. 保护 API Token

  • 不要将 token 硬编码在脚本中
  • 使用环境变量或配置文件存储 token
  • 定期更换 token

2. 使用 HTTPS

  • 建议在生产环境使用 HTTPS 协议
  • 防止 token 和 IP 地址在传输过程中被窃取

3. 限制访问频率

  • 避免过于频繁地调用 API
  • 建议设置 5-10 分钟的检查间隔

4. 监控日志

  • 定期检查 DDNS 更新日志
  • 发现异常及时更换 token

❓ 常见问题

Q: 提示"无效的 token"?

A: 请检查:
  • token 是否正确复制(包含完整 64 字符)
  • 用户账号是否被禁用
  • token 是否已过期或被重置

Q: 提示"域名不存在或无权操作"?

A: 请确认:
  • 域名是否已在该平台注册
  • 当前用户是否拥有该域名的所有权
  • 域名是否已被禁用
  • ⚠️ DDNS 功能仅支持子域名(如 blog.example.com),不支持一级域名(如 example.com

Q: 提示"DDNS 功能仅支持子域名,不支持一级域名"?

A: 这是正常限制。DDNS 功能设计为只允许更新子域名记录。
  • 错误示例example.com(一级域名)
  • 正确示例blog.example.comapi.example.com(子域名)
  • 请确保您使用的是完整的子域名格式

Q: 更新后 DNS 记录没有立即生效?

A: 这是正常的,DNS 传播需要时间:
  • 本地 DNS 缓存可能导致延迟
  • TTL 设置会影响生效时间
  • 可以使用 dignslookup 检查 DNS 传播状态

Q: 支持 IPv6 吗?

A: ✅ 是的!系统支持:
  • A 记录(IPv4 地址)
  • AAAA 记录(IPv6 地址)

系统会自动检测 IP 地址类型并使用相应的记录类型。

⚙️ 技术细节

认证流程

  1. 系统验证提供的 token 是否有效
  2. 检查用户账号状态(是否被禁用)
  3. 验证用户对域名是否有操作权限

更新流程

  1. 检查新旧 IP 是否相同(相同则跳过更新)
  2. 调用 DNS 服务器 API 更新记录
  3. 更新本地数据库记录
  4. 如果数据库更新失败,尝试回滚 DNS 服务器

错误处理

📦 版本历史

版本 日期 说明
v1.2 2026-03-08
  • ✅ 添加 IPv6(AAAA 记录)支持
  • ✅ 优化 API Token 管理界面
  • ✅ 独立 Token 管理页面
v1.1 2026-03-08
  • ✅ 添加 IPv6 支持
  • ✅ 自动检测 IP 类型
v1.0 - 初始版本,支持 A 记录动态更新

FreeDNS Go - DDNS API文档 | 最后更新:2026 年 5 月 3 日