基于 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
部署与使用
- 获取 Token:登录 DNSPod 控制台,在「API 密钥」中创建 Token(格式为
ID,Token)。 - 配置脚本:将上述代码保存为
dnspodsh,修改login_token和domainList配置。 - 安装 Bash(如需要):在 OpenWrt/PandoraBox 等系统中运行
opkg update && opkg install bash。 - 设置可执行权限:
chmod +x dnspodsh。 - 开机自启:将以下命令加入
/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 文档调整参数。