DDNS API 使用文档

概述

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" 标签页查看)
old_value string 当前记录的 IP 值。当同一域名存在多条同类型记录时,必须提供此参数以精确指定要更新的记录(如 old_value=192.168.1.99

支持的记录类型

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

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

响应格式

成功响应

HTTP 状态码: 200
{
  "success": true,
  "message": "DDNS 更新已提交,DNS 同步异步处理中",
  "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,
    "compensated": false
  }
}

compensated 字段说明:当 IP 未变化但系统检测到 DNS 服务器与数据库不一致时,会自动触发补偿同步,此时值为 true

错误响应

业务状态码(status_code): 400/401/403/404/409/429/500(所有请求均返回 HTTP 200,业务结果通过 status_code 字段区分)
{
  "success": false,
  "status_code": 400,
  "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)与域名配置不匹配
400 域名长度超过限制(最大 253 字符) 域名总长度超出 RFC 1035 规范限制
400 域名格式无效:每个标签长度必须在 1-63 字符之间 域名中某个标签(以 . 分隔的部分)为空或超过 63 字符
409 域名存在多条记录,无法确定更新目标 同一域名存在多条同类型记录,需提供 old_value 参数精确指定。响应中会附带 existing_values 列表和 hint 提示
409 提供的 old_value 与当前记录值不匹配 old_value 参数与实际记录值不一致
409 提供的 old_value 未匹配到任何记录 old_value 参数无法匹配到已有的同类型记录
429 DDNS 请求过于频繁,请稍后再试 请求频率超出限制,请降低调用频率后重试
500 更新失败 服务器内部错误

使用示例

提示:使用前请确保您已获取 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"

# 多条同类型记录时,使用 old_value 精确指定要更新的记录
curl -X GET "https://pwdns.org/api/ddns/update?domain=blog.example.com&ip=192.168.1.200&old_value=192.168.1.100&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)

多条记录精确匹配

当同一域名存在多条同类型(A 或 AAAA)记录时,系统无法自动确定要更新哪一条记录,此时必须提供 old_value 参数。

使用场景:例如 blog.example.com 同时有两条 A 记录(192.168.1.10010.0.0.1),你想更新第一条:
精确匹配指定记录
# 通过 old_value=192.168.1.100 精确指定要更新第一条记录
curl -X GET "https://pwdns.org/api/ddns/update?domain=blog.example.com&ip=192.168.1.200&old_value=192.168.1.100&token=your_api_token"

错误处理

如果未提供 old_value,API 将返回 409 错误,并在响应中附带现有记录值列表:

{
  "success": false,
  "error": "域名 blog.example.com 存在 2 条 A 记录,无法确定更新目标。请提供 old_value 参数指定要更新的记录当前值",
  "data": {
    "existing_values": ["192.168.1.100", "10.0.0.1"],
    "hint": "在请求中添加 old_value=<当前IP> 参数来指定要更新的记录"
  }
}

提示

  • 如果域名只有一条记录,old_value 参数可省略
  • 即使只有一条记录,若提供了 old_value,系统也会校验其与实际值是否一致
  • old_value 必须是目标记录当前的实际 IP 值

定时任务配置

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,请求频率受限会返回 429 错误
  • 建议设置 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 是否相同(相同则跳过更新,同时自动检测 DNS 一致性并在不一致时触发补偿同步)
  2. 使用数据库事务原子化更新记录并投递同步事件
  3. 后台异步处理 DNS 服务器同步
  4. 事务失败时数据库和同步事件同时回滚,保持一致性

错误处理

  • 所有写操作都有数据库事务保护
  • DNS 同步通过后台异步事件管道处理
  • 事务失败时自动回滚,不会产生数据不一致
  • IP 未变化时会自动检测 DNS 服务器一致性,不一致时触发补偿同步

版本历史

版本 日期 说明
v2.0 2026-06
  • ✅ 新增 old_value 参数,支持多条同类型记录精确匹配
  • ✅ 更新采用异步事件管道模式,DNS 同步后台处理
  • ✅ IP 未变化时自动检测 DNS 一致性并触发补偿同步
  • ✅ 新增域名格式校验(RFC 1035 规范)
  • ✅ 新增请求频率限制保护
  • ✅ 完善审计日志记录
v1.2 2026-03-08
  • ✅ 添加 IPv6(AAAA 记录)支持
  • ✅ 优化 API Token 管理界面
  • ✅ 独立 Token 管理页面
v1.1 2026-01-15
  • ✅ 添加 IPv6 支持
  • ✅ 自动检测 IP 类型
v1.0 - 初始版本,支持 A 记录动态更新