准备工作
在开始之前,请确保您已具备以下条件:
- 一台运行 CentOS 系统的服务器或虚拟机。
- 一个在 DNSPod 上托管的域名。
- DNSPod 账户的 API Token(ID 和 Token)。您可以在 DNSPod 控制台的“API 密钥”页面创建。
创建 DDNS 脚本
首先,创建一个用于动态更新 DNS 记录的 Shell 脚本。
-
使用文本编辑器创建脚本文件:
vim /root/ddns.sh -
将以下脚本内容复制并粘贴到文件中。请仔细阅读注释以了解各部分功能。
#!/bin/sh # 全局变量表 arPass=arMail="" # 获得外网地址 arIpAdress() { local inter="http://members.3322.org/dyndns/getip" wget --quiet --no-check-certificate --output-document=- $inter } # 查询域名地址 # 参数: 待查询域名 arNslookup() { local dnsvr="114.114.114.114" nslookup ${1} $dnsvr | tr -d 'n[:blank:]' | awk -F':' '{print $6}' } # 读取接口数据 # 参数: 接口类型 待提交数据 arApiPost() { local agent="Ddns/3.08" local inter="https://dnsapi.cn/${1:?'Info.Version'}" local param="login_token=${arID},${arToken}&format=json&${2}" wget --quiet --no-check-certificate --output-document=- --user-agent=$agent --post-data $param $inter } # 更新记录信息 # 参数: 主域名 子域名 arDdnsUpdate() { local domainID recordID recordRS recordCD # 获得域名ID domainID=$(arApiPost "Domain.Info" "domain=${1}") domainID=$(echo $domainID | sed 's/.*"id":"([0-9]*)".*/1/') # 获得记录ID recordID=$(arApiPost "Record.List" "domain_id=${domainID}&sub_domain=${2}") recordID=$(echo $recordID | sed 's/.+[{"id":"([0-9]+)".+/1/') # 更新记录IP recordRS=$(arApiPost "Record.Ddns" "domain_id=${domainID}&record_id=${recordID}&sub_domain=${2}&record_line=默认") recordCD=$(echo $recordRS | sed 's/.+{"code":"([0-9]+)".+/1/') # 输出记录IP if [ "$recordCD" == "1" ]; then echo $recordRS | sed 's/.+,"value":"([0-9.]+)".+/1/' return 1 fi # 输出错误信息 echo $recordRS | sed 's/.+,"message":"([^"]+)".+/1/' } # 动态检查更新 # 参数: 主域名 子域名 arDdnsCheck() { local postRS local hostIP=$(arIpAdress) local lastIP=$(arNslookup "${2}.${1}") echo "hostIP: ${hostIP}" echo "lastIP: ${lastIP}" if [ "$lastIP" != "$hostIP" ]; then postRS=$(arDdnsUpdate $1 $2) echo "postRS: ${postRS}" if [ $? -ne 1 ]; then return 0 fi fi return 1 } ################################################### # 设置用户参数 arID="YOUR_API_ID" arToken="YOUR_API_TOKEN" # 请将 YOUR_API_ID 和 YOUR_API_TOKEN 替换为您的 DNSPod API 凭证 # 检查更新域名 # 格式:arDdnsCheck "主域名" "子域名" # 示例:更新 lab.example.com arDdnsCheck "example.com" "lab"
配置脚本参数
脚本末尾有三个关键部分需要您修改:
- API 凭证:将
arID和arToken变量的值替换为您从 DNSPod 获取的实际 API ID 和 Token。 - 目标域名:修改
arDdnsCheck函数的参数。第一个参数是您的主域名(如example.com),第二个参数是子域名或主机记录(如lab)。脚本会尝试更新lab.example.com的 A 记录。 - (可选)添加更多域名:您可以复制
arDdnsCheck行来为多个子域名或不同域名设置 DDNS。
设置脚本权限与定时任务
1. 赋予执行权限
保存脚本后,需要使其可执行:
chmod +x /root/ddns.sh
2. 添加到定时任务(Cron)
为了让脚本定期检查并更新 IP,我们将其加入系统计划任务。以下命令设置每 5 分钟执行一次:
echo "*/5 * * * * root /root/ddns.sh" >> /etc/crontab
注意:请确保脚本路径 /root/ddns.sh 与您实际存放的位置一致。
添加后,计划任务服务(crond)会自动加载新配置。您可以通过查看日志文件来监控执行情况:
tail -f /var/log/cron
常见问题与解决方法
问题 1:提示 “nslookup: command not found”
现象:执行脚本时出现类似以下错误:
./ddns.sh: line 24: nslookup: command not found
原因:系统中未安装 DNS 查询工具。
解决:根据您的系统安装对应的软件包。
- CentOS / RHEL / Fedora:
yum -y install bind-utils - Ubuntu / Debian:
sudo apt-get install dnsutils
问题 2:提示 “Domain id invalid”
现象:脚本返回错误信息 postRS: Domain id invalid。
原因:早期脚本中用于提取域名 ID 的正则表达式可能不匹配 DNSPod API 返回的 JSON 格式。
解决:本文提供的脚本已使用修正后的表达式:sed 's/.*"id":"([0-9]*)".*/1/'。如果您是从其他来源获取的脚本,请确保此行与上文一致。
脚本工作原理简述
- 获取公网 IP:通过访问外部服务
http://members.3322.org/dyndns/getip获取当前服务器的公网 IP 地址。 - 查询当前 DNS 记录:使用
nslookup查询指定域名当前的解析 IP。 - 比较 IP:如果公网 IP 与 DNS 记录 IP 不一致,则调用 DNSPod API 进行更新。
- 调用 API 更新:通过向 DNSPod 的
Record.Ddns接口发送请求,更新指定域名的 A 记录值。
通过以上步骤,即可实现基于 DNSPod 的动态域名解析(DDNS),确保域名始终指向变化后的公网 IP 地址,适用于家庭宽带、动态 IP 服务器等场景。