handle/ddns.go
DDNS (Dynamic DNS) API 允许用户通过 API 动态更新 DNS 记录,特别适用于家庭宽带、动态 IP 等场景。
blog.example.com),不支持一级域名(如 example.com)。
/api/ddns/update
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
domain |
string | 是 | 完整子域名,例如:blog.example.com(️ 不支持一级域名) |
ip |
string | 否 | 新的 IP 地址。如果不提供,将自动使用请求来源的 IP 地址 |
token |
string | 是 | 用户API Token(登录后在个人中心首页,点击顶部导航栏的 "API Token" 标签页查看) |
系统会自动检测 IP 地址类型并使用相应的记录类型。
{
"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
}
}
{
"success": true,
"message": "IP 地址未变化,无需更新",
"data": {
"domain": "blog.example.com",
"ip": "192.168.1.100",
"updated": false
}
}
{
"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 服务器失败 / 更新数据库失败 | 服务器内部错误 |
# 自动检测当前 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"
#!/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
# 配置
$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
}
#!/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)
# 编辑 crontab
crontab -e
# 添加以下行
*/5 * * * * /path/to/ddns_script.sh >> /var/log/ddns.log 2>&1
# 创建计划任务(每 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"
blog.example.com),不支持一级域名(如 example.com)example.com(一级域名)blog.example.com、api.example.com(子域名)dig 或 nslookup 检查 DNS 传播状态系统会自动检测 IP 地址类型并使用相应的记录类型。
| 版本 | 日期 | 说明 |
|---|---|---|
| v1.2 | 2026-03-08 |
|
| v1.1 | 2026-03-08 |
|
| v1.0 | - | 初始版本,支持 A 记录动态更新 |
FreeDNS Go - DDNS API文档 | 最后更新:2026 年 5 月 3 日