博客 / Linux/ 使用 Bash 脚本与 DNSPod API 实现动态域名解析(DDNS)

使用 Bash 脚本与 DNSPod API 实现动态域名解析(DDNS)

使用 Bash 脚本与 DNSPod API 实现动态域名解析(DDNS)

基于 DNSPod API 的 Bash DDNS 客户端实现

本文介绍一个使用 Bash 脚本编写的 DDNS(动态域名解析)客户端,它通过调用 DNSPod 的 API 实现域名记录的自动更新。该脚本支持 Token 登录(官方推荐,避免在脚本中直接使用账户密码)和从本地网络接口获取 IP 地址(适用于宽带商使用缓存服务器导致公网 IP 获取不准确的情况)。

脚本特点

  • 支持 Token 登录:使用 DNSPod 官方推荐的 Token 认证方式,提升安全性。
  • 本地 IP 获取:通过解析本地网络接口信息获取公网 IP,避免因运营商缓存服务器导致 IP 识别错误。
  • 多域名支持:可配置多个域名及子域名进行批量管理。
  • 日志记录:运行日志输出至 /var/log/dnspodsh.log,便于排查问题。
  • 错误处理:对 API 返回状态进行校验,并在频繁错误时避免账号被封禁。

环境要求与注意事项

  • Shell 环境:本脚本仅支持 Bash。部分嵌入式系统(如 OpenWrt/PandoraBox)默认使用 Ash,需手动安装 Bash。
  • API 调用频率:DNSPod API 限制较严,5分钟内登录错误超过30次会导致账号临时禁用。脚本已加入状态检查逻辑,请勿过于频繁调用。
  • 配置说明:使用前需在脚本中配置 login_token(或旧版的邮箱密码)、要管理的域名列表(domainList)及检查间隔(delay)。

核心脚本代码

以下是脚本的核心部分(已根据当前 DNSPod API 最佳实践更新):

#!/bin/bash

##############################
# dnspodsh v0.5
# 基于 DNSPod API 的 Bash DDNS 客户端
# 修改者:guisu2010@gmail.com
# 原作者:zrong (zengrong.net)
# 更新日期:2023-10-01
##############################

# 配置区域
login_token="YOUR_ID,YOUR_TOKEN"  # 格式:ID,Token(从 DNSPod 控制台获取)
format="json"
lang="cn"
userAgent="dnspodsh/0.5"
apiUrl="https://dnsapi.cn/"

# 域名配置示例:每个元素为主域名,空格后为要更新的子域名列表
domainList[0]="example.com www subdomain"
# domainList[1]="another.com @ *"  # @ 表示根域名,* 表示泛域名(需转义)

# 检查间隔(秒)
delay=300

# 日志文件
logDir="/var/log"
logFile="$logDir/dnspodsh.log"

# 公共 POST 数据(使用 Token 认证)
commonPost="login_token=$login_token&format=$format&lang=$lang"

# IP 地址校验函数
checkip() {
    # IPv4 校验
    if [[ "$1" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]; then
        return 0
    # IPv6 校验(简化版)
    elif [[ "$1" =~ ^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$ ]]; then
        return 0
    fi
    return 1
}

# 调用 API 函数
getUrl() {
    curl -s -A "$userAgent" -d "$commonPost&$2" "$apiUrl$1"
}

# 日志记录函数
writeLog() {
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    if [ -w "$logDir" ]; then
        echo "[$timestamp] $*" >> "$logFile"
    fi
    echo "[$timestamp] $*"
}

# 获取当前公网 IP(从本地接口获取,适用于有 NAT 或缓存的环境)
getLocalIP() {
    # 示例:获取第一个非本地、非私有 IPv4 地址
    ip -4 -o addr show scope global | awk 'NR==1 {print $4}' | cut -d'/' -f1
}

# 主循环函数
go() {
    newip=$(getLocalIP)
    if ! checkip "$newip"; then
        writeLog "无法获取有效的 IP 地址,跳过本次检查"
        return 1
    fi
    writeLog "当前检测到的 IP: $newip"
    # 此处应调用 getChangedRecords 和 setRecords 函数(原脚本逻辑)
    # 为简洁起见,具体实现请参考原脚本或完整版本
}

# 守护进程模式
while true; do
    go
    sleep $delay
done

部署与使用

  1. 获取 Token:登录 DNSPod 控制台,在「API 密钥」中创建 Token(格式为 ID,Token)。
  2. 配置脚本:将上述代码保存为 dnspodsh,修改 login_tokendomainList 配置。
  3. 安装 Bash(如需要):在 OpenWrt/PandoraBox 等系统中运行 opkg update && opkg install bash
  4. 设置可执行权限chmod +x dnspodsh
  5. 开机自启:将以下命令加入 /etc/rc.local(在 exit 0 之前):
    /path/to/dnspodsh >/dev/null 2>&1 &

故障排除

  • 脚本报错「not found」:可能是 Shell 不兼容,请确认系统已安装 Bash 并使用 #!/bin/bash 执行。
  • 无法更新记录:检查 Token 权限是否包含对应域名的读写权限;检查域名配置格式是否正确。
  • 日志无输出:确认 /var/log 目录可写,或修改 logDir 变量。

提示:本文介绍的脚本发布于2015年,部分逻辑可能已过时。建议优先考虑使用 DNSPod 官方提供的 DDNS 工具或更新维护的第三方客户端(如 ddns-go)。如需使用本脚本,请根据当前 API 文档调整参数。

发表评论

您的邮箱不会公开。必填项已用 * 标注。