本文目录导读:

这里为您提供几个常用的自动更新动态域名解析(DDNS)的脚本,涵盖 Linux (Bash)、Windows (PowerShell) 以及 Python(跨平台)版本,您可以根据自己的操作系统和路由器/服务器环境选择使用。
Linux / macOS (Bash 脚本 + Crontab)
适用场景: 树莓派、NAS、云服务器等运行 Linux 的主机。
-
创建脚本文件 (
update_ddns.sh)#!/bin/bash # ========== 配置区(请修改为您自己的信息) ========== # 以阿里云为例(其他服务商类似),也可以替换为DNSPod、Cloudflare等API ACCESS_KEY_ID="你的AccessKeyId" ACCESS_KEY_SECRET="你的AccessKeySecret" DOMAIN="example.com" # 根域名 RR="www" # 主机记录 (www, @, nas) # ================================================= # 获取当前公网IP # 方法1:使用 ip.sb CURRENT_IP=$(curl -s https://ip.sb) # 方法2:使用 icanhazip (备用) # CURRENT_IP=$(curl -s https://icanhazip.com) # 检查IP是否正确获取 if [ -z "$CURRENT_IP" ]; then echo "$(date): 获取IP失败,退出。" exit 1 fi echo "$(date): 检测到当前公网IP为 $CURRENT_IP" # 这里需要调用对应DNS服务商的API进行比对和更新。 # 下述代码以阿里云DNS API为例(需要计算签名,过程较为复杂)。 # 为了简化,这里使用阿里云CLI工具(假设已配置好aliyun CLI)。 # 查询当前解析记录 OLD_IP=$(aliyun alidns DescribeDomainRecords --DomainName "$DOMAIN" --RRKeyWord "$RR" --Type A --query "DomainRecords.Record[0].Value" --output cols=Value rows=Records) echo "$(date): 旧IP为 $OLD_IP" if [ "$CURRENT_IP" == "$OLD_IP" ]; then echo "$(date): IP没有变化,无需更新。" else echo "$(date): IP发生变化,正在更新DNS记录..." RECORD_ID=$(aliyun alidns DescribeDomainRecords --DomainName "$DOMAIN" --RRKeyWord "$RR" --Type A --query "DomainRecords.Record[0].RecordId" --output cols=RecordId rows=Records) # 执行更新 aliyun alidns UpdateDomainRecord --RecordId "$RECORD_ID" --RR "$RR" --Type A --Value "$CURRENT_IP" echo "$(date): DNS更新完成!" fi -
赋予执行权限:
chmod +x update_ddns.sh
-
添加定时任务 (Crontab): 每5分钟检查一次(建议最小间隔5分钟,避免API请求频繁):
crontab -e
添加以下行:
*/5 * * * * /path/to/your/update_ddns.sh >> /var/log/ddns.log 2>&1
Windows (PowerShell 脚本 + 任务计划程序)
适用场景: 运行 Windows 10/11 或 Windows Server 的主机。
-
创建脚本文件 (
update_ddns.ps1)# 以 DNSPod(腾讯云)为例(免费且API简单,兼容性好) $DNSPodToken = "你的TokenID,你的TokenKey" # "12345,abcdefghijklmn" $Domain = "example.com" $SubDomain = "www" # 如果要解析根域名,留空 "" # 获取当前公网IP $CurrentIP = Invoke-RestMethod -Uri "https://ip.sb" -Method Get | Select-Object -ExpandProperty Content # 备用获取方式: $CurrentIP = (Invoke-RestMethod -Uri "https://api.ipify.org") Write-Host "检测到当前IP: $CurrentIP" # 获取DNS记录列表(DNSPod API) $RecordApi = "https://dnsapi.cn/Record.List" $Body = @{ login_token = $DNSPodToken format = "json" domain = $Domain sub_domain = $SubDomain } $Records = Invoke-RestMethod -Uri $RecordApi -Method Post -Body $Body $Record = $Records.records | Where-Object { $_.type -eq "A" } | Select-Object -First 1 if ($nil -eq $Record) { Write-Host "未找到A记录,创建新记录..." $CreateApi = "https://dnsapi.cn/Record.Create" $CreateBody = @{ login_token = $DNSPodToken format = "json" domain = $Domain sub_domain = $SubDomain record_type = "A" record_line = "默认" value = $CurrentIP } Invoke-RestMethod -Uri $CreateApi -Method Post -Body $CreateBody | Out-Null } else { if ($Record.value -eq $CurrentIP) { Write-Host "IP未变化,跳过更新。" } else { Write-Host "IP已变化,从 $($Record.value) 更新为 $CurrentIP ..." $UpdateApi = "https://dnsapi.cn/Record.Modify" $UpdateBody = @{ login_token = $DNSPodToken format = "json" domain = $Domain record_id = $Record.id sub_domain = $SubDomain record_type = "A" record_line = "默认" value = $CurrentIP } Invoke-RestMethod -Uri $UpdateApi -Method Post -Body $UpdateBody | Out-Null } } Write-Host "脚本执行完成。" -
设置任务计划程序:
- 打开“任务计划程序”。
- 创建任务 -> 触发器 -> 新建 -> 选择“按预定计划” -> 设置为“重复任务间隔 5 分钟”。
- 操作 -> 新建 -> 程序填写
powershell.exe,参数添加:-ExecutionPolicy Bypass -File "C:\路径\update_ddns.ps1"。
跨平台 Python 脚本
适用场景: 任何安装了 Python 3 的系统,配合系统自带的任务调度器。
import requests
import time
import logging
# ========== 配置区(请修改) ==========
# 以 Cloudflare 为例(免费、稳定、API文档清晰)
API_TOKEN = "你的Cloudflare API Token" # 需要 Zone.DNS Edit 权限
ZONE_ID = "你的Zone ID" # 在Cloudflare域名概览页面
RECORD_NAME = "www.example.com" # 完整解析记录名称
# ==================================
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def get_public_ip():
"""获取公网IPv4地址"""
try:
# 使用多个备用源
for source in ['https://api.ipify.org', 'https://ip.sb', 'https://icanhazip.com']:
try:
ip = requests.get(source, timeout=10).text.strip()
if ip and '.' in ip: # 简单IPv4判断
return ip
except Exception as e:
logging.warning(f"从 {source} 获取失败: {e}")
continue
raise Exception("所有IP源均失败")
except Exception as e:
logging.error(f"获取公网IP失败: {e}")
return None
def get_dns_record(record_name, zone_id, api_token):
"""获取当前DNS解析记录"""
headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json"
}
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records"
params = {"name": record_name}
try:
response = requests.get(url, headers=headers, params=params, timeout=10)
response.raise_for_status()
data = response.json()
if data["success"] and data["result"]:
record = data["result"][0]
return record
else:
logging.warning(f"未找到记录: {data.get('errors')}")
except Exception as e:
logging.error(f"查询DNS记录失败: {e}")
return None
def update_dns_record(record, new_ip, zone_id, api_token):
"""更新DNS解析记录"""
headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json"
}
data = {
"type": "A",
"name": record["name"],
"content": new_ip,
"ttl": record["ttl"],
"proxied": record["proxied"]
}
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record['id']}"
try:
response = requests.put(url, headers=headers, json=data, timeout=10)
response.raise_for_status()
if response.json()["success"]:
logging.info(f"更新成功:{record['name']} -> {new_ip}")
else:
logging.error(f"更新失败:{response.json()['errors']}")
except Exception as e:
logging.error(f"API请求异常: {e}")
def main():
current_ip = get_public_ip()
if not current_ip:
logging.error("无法获取公网IP,退出。")
return
record = get_dns_record(RECORD_NAME, ZONE_ID, API_TOKEN)
if not record:
logging.error(f"无法获取记录 {RECORD_NAME},请检查配置。")
return
# 不强制代理 (Cloudflare Proxy)
if record["content"] != current_ip:
logging.info(f"IP变更: {record['content']} -> {current_ip}")
update_dns_record(record, current_ip, ZONE_ID, API_TOKEN)
else:
logging.info(f"IP未发生变化: {current_ip}")
if __name__ == "__main__":
main()
使用方式:
- 将上述代码保存为
ddns_update.py,安装依赖:pip install requests - 手动运行测试:
python ddns_update.py - 设置定时任务:
- Linux:
crontab -e添加*/5 * * * * /usr/bin/python3 /path/to/ddns_update.py >> /var/log/ddns.log 2>&1 - Windows:使用“任务计划程序”创建每小时或每5分钟的基本任务。
- Linux:
通用建议:
- 日志记录:无论哪个方案,建议将输出重定向到日志文件,方便排查问题。
- 双栈支持:如果同时需要使用 IPv6,需要额外获取 IPv6 地址并添加
AAAA记录,上述脚本主要以 IPv4 为例。 - API 选择:
- 国内环境:推荐使用 DnsPod(腾讯云) 或 阿里云,速度较快且 API 免费。
- 国际环境:推荐使用 Cloudflare,API 稳定,且可以免费启用 CDN 代理(但会将真实 IP 隐藏)。
- 密钥安全:脚本中的 API Token / Secret 请注意权限最小化,避免泄露牵连主账号安全。