本文最后更新于 2024-07-25,文章内容可能已经过时。

一、背景

之前使用小米路由器下面自带的DDNS 服务商,但发现不是很稳定,有的限速,有的就是直接无法访问;思考下能不能自己搭建一个DDNS,上网浏览了一圈发现有很多案例,大部分都是使用自己的域名,再搭配动态的域名解析,从而实现动态DDNS 服务

本文也是基于上面的案例,使用自己的域名从而实现动态DDNS

无需安装客户端,直接一个定时任务跑shell脚本即可,快速部署,一次部署,终身使用

image-20240725133126972

二、所需环境

  • 一个域名
我的域名是在腾讯云上面购买的,如果你没有域名的话,首先要先购买一个域名;推荐使用腾讯云域名

image-20240725133648428

  • 宽带公网ip

江苏这边3大运营商里,移动和 电信 是不提供公网IP的【投诉申请都没用】,哈哈; 剩下一个 你懂的

三、实现步骤

3.1 进入dnspod官网管理控制台

官网地址

image-20240725134508547

创建一条 A记录解析,IP地址暂时随便填就行: 

主机记录名称 就是你的 动态DDNS域名,比如 我这里的 home.srebro.cn ; 记录值: 就是你家中的公网IP,可以先谁便填写一个

image-20240725134726672

3.2 创建腾讯云API 密钥

  • 创建地址: https://console.dnspod.cn/account/token/apikey

新建密钥,拿起小本本记下密钥,后面要用

image-20240725135114640

image-20240725135155297

3.3 使用腾讯云-API Explorer在线调试

3.3.1 获取域名的解析记录列表

通过接口 DescribeRecordList查到对应的解析记录列表以及对应的 RecordId

  • 在线调试地址

  • 输入:

    Domain 域名,srebro.cn

    Subdomain 解析记录的主机头, 就是你的 动态DDNS域名,比如 我这里的 home.srebro.cn ;

  • 输出:

    得到 RecordId ,记录 ID ,后面需要使用 ,小本本记下

image-20240725140715871

3.3.2 在线调试,修改域名记录值

使用得到的RecordId 来模拟修改A记录值

  • 在线调试地址

  • 输入:

    Domain 域名;srebro.cn

    RecordType ,记录类型;A 记录

    RecordLine , 记录线路; 保持默认

    Value ,记录值,如 IP : 200.200.200.200 【就是你家中的公网IP,可以先谁便填写一个】

    RecordId ,记录 ID , 刚刚我们通过接口 获取域名的解析记录列表查到解析记录 home.srebro.cn对应的 RecordId

    Subdomain 解析记录的主机头, 就是你的 动态DDNS域名,比如 我这里的 home.srebro.cn

  • 输出:

    可以看到右边的响应结果,并且可以看到域名记录的值也已经被修改了;

image-20240725141151048

image-20240725142206109

3.3.3 通过在线调试,修改域名记录值得到代码示例

还是刚刚一样的步骤,我们再修改域名记录值里,通过填写一定的参数,可以得到shell 的代码示例

image-20240725142830718

3.4 编写脚本

拿到刚刚调试的shell 脚本,稍微的改动下,把 Value ,记录值【就是你家中的公网IP】通过 https://ipv4.rehi.org/ip 获取到IPV4 的公网地址。这里用REL_IP变量表示,其次就是定义 secret_idsecret_key 【上面创建腾讯云API 密钥已经拿到了】

修改后的脚本,大致如下,各位自行调整

需要注意,脚本里需要有 RecordId,记录 ID , 就是我们通过接口 获取域名的解析记录列表查到解析记录 home.srebro.cn对应的 RecordId

vim /home/application/dnspod/dnspod.sh

#!/bin/bash
secret_id="xxxxxxxxxxxxx"
secret_key="xxxxxxxxxxxxxxxxxxxxxxxxx"
token=""
REL_IP=`curl -s https://ipv4.rehi.org/ip`

service="dnspod"
host="dnspod.tencentcloudapi.com"
region=""
action="ModifyRecord"
version="2021-03-23"
algorithm="TC3-HMAC-SHA256"
timestamp=$(date +%s)
date=$(date -u -d @$timestamp +"%Y-%m-%d")
payload="{\"Domain\":\"home.srebro.cn\",\"RecordType\":\"A\",\"RecordLine\":\"默认\",\"Value\":\"$REL_IP\",\"RecordId\":11112223333,\"SubDomain\":\"all\"}"

# ************* 步骤 1:拼接规范请求串 *************
http_request_method="POST"
canonical_uri="/"
canonical_querystring=""
canonical_headers="content-type:application/json; charset=utf-8\nhost:$host\nx-tc-action:$(echo $action | awk '{print tolower($0)}')\n"
signed_headers="content-type;host;x-tc-action"
hashed_request_payload=$(echo -n "$payload" | openssl sha256 -hex | awk '{print $2}')
canonical_request="$http_request_method\n$canonical_uri\n$canonical_querystring\n$canonical_headers\n$signed_headers\n$hashed_request_payload"
echo "$canonical_request"

# ************* 步骤 2:拼接待签名字符串 *************
credential_scope="$date/$service/tc3_request"
hashed_canonical_request=$(printf "$canonical_request" | openssl sha256 -hex | awk '{print $2}')
string_to_sign="$algorithm\n$timestamp\n$credential_scope\n$hashed_canonical_request"
echo "$string_to_sign"

# ************* 步骤 3:计算签名 *************
secret_date=$(printf "$date" | openssl sha256 -hmac "TC3$secret_key" | awk '{print $2}')
echo $secret_date
secret_service=$(printf $service | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_date" | awk '{print $2}')
echo $secret_service
secret_signing=$(printf "tc3_request" | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_service" | awk '{print $2}')
echo $secret_signing
signature=$(printf "$string_to_sign" | openssl dgst -sha256 -mac hmac -macopt hexkey:"$secret_signing" | awk '{print $2}')
echo "$signature"

# ************* 步骤 4:拼接 Authorization *************
authorization="$algorithm Credential=$secret_id/$credential_scope, SignedHeaders=$signed_headers, Signature=$signature"
echo $authorization

# ************* 步骤 5:构造并发起请求 *************
curl -XPOST "https://$host" -d "$payload" -H "Authorization: $authorization" -H "Content-Type: application/json; charset=utf-8" -H "Host: $host" -H "X-TC-Action: $action" -H "X-TC-Timestamp: $timestamp" -H "X-TC-Version: $version" -H "X-TC-Region: $region" -H "X-TC-Token: $token"
  • 测试脚本

可以看到记录值,已经修改了

bash /home/application/dnspod/dnspod.sh

image-20240725143840496

3.5 添加定时任务

定时任务如下:

每三十分钟,执行一次;可以查看DNSpod 的云平台操作日志,查看具体的记录变更日志

*/30 * * * * /home/application/dnspod/dnspod.sh

image-20240725144136393

四、后续

有了自己的DDNS ,内网路由器再配置一个端口转发,再搭配公网云服务器结合使用,代理嘎嘎发射,简直不要太舒服 哈哈,懂得都懂