博客 / Linux/ centos系统利用dnspod 动态解析域名ddns外网穿透

centos系统利用dnspod 动态解析域名ddns外网穿透

centos系统利用dnspod 动态解析域名ddns外网穿透

准备工作

在开始之前,请确保您已具备以下条件:

  • 一台运行 CentOS 系统的服务器或虚拟机。
  • 一个在 DNSPod 上托管的域名。
  • DNSPod 账户的 API Token(ID 和 Token)。您可以在 DNSPod 控制台的“API 密钥”页面创建。

创建 DDNS 脚本

首先,创建一个用于动态更新 DNS 记录的 Shell 脚本。

  1. 使用文本编辑器创建脚本文件:

    vim /root/ddns.sh
  2. 将以下脚本内容复制并粘贴到文件中。请仔细阅读注释以了解各部分功能。

    #!/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"

配置脚本参数

脚本末尾有三个关键部分需要您修改:

  1. API 凭证:将 arIDarToken 变量的值替换为您从 DNSPod 获取的实际 API ID 和 Token。
  2. 目标域名:修改 arDdnsCheck 函数的参数。第一个参数是您的主域名(如 example.com),第二个参数是子域名或主机记录(如 lab)。脚本会尝试更新 lab.example.com 的 A 记录。
  3. (可选)添加更多域名:您可以复制 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/'。如果您是从其他来源获取的脚本,请确保此行与上文一致。

脚本工作原理简述

  1. 获取公网 IP:通过访问外部服务 http://members.3322.org/dyndns/getip 获取当前服务器的公网 IP 地址。
  2. 查询当前 DNS 记录:使用 nslookup 查询指定域名当前的解析 IP。
  3. 比较 IP:如果公网 IP 与 DNS 记录 IP 不一致,则调用 DNSPod API 进行更新。
  4. 调用 API 更新:通过向 DNSPod 的 Record.Ddns 接口发送请求,更新指定域名的 A 记录值。

通过以上步骤,即可实现基于 DNSPod 的动态域名解析(DDNS),确保域名始终指向变化后的公网 IP 地址,适用于家庭宽带、动态 IP 服务器等场景。

发表评论

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