现在可以使用的DDNS工具和软件有很多,但有时候我们只需要一个简单的shell脚本就能完成任务。

1、在Cloudflare上建立一个二级域名

首先,前往Cloudflare上,建立用来作为DDNS用的A记录和AAAA记录。假设是:

A记录:            ddns.example.com    1.1.1.1

AAAA记录:    ddns.example.com   2606:4700:4700::1111

IP地址先可以随便填。

2、取得所需的ZONE_ID、API_Token和RECORD_ID

ZONE_ID就在域名概述页的右下侧,名字为区域ID。 接着,在同一页的下方点击获取API 令牌。

点击创建令牌,使用“编辑区域DNS”的模板,选择相应的域名,点击显示摘要,并创建令牌。

把生成的API_Token保存好。

接着打开一个Linux终端,执行以下代码:

1
2
3
4
5
ZONE_ID="你的 Zone ID"
API_TOKEN="你的API Token"
curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=ddns.example.com" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json"

注意替换代码中的ZONE_ID,API_Token,二级域名。

在返回的结果中,找到“name”与相应二级域名相符的RECORD_ID。

3、建立Shell脚本

在你喜欢的位置比如root目录建立一个脚本文件:

1
mkdir cfddns && cd cfddns
1
touch ddns.sh

然后用编辑器打开:

1
vim ddns.sh

复制以下代码,并保存退出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/sh
# 简单的使用Clodflare API来实现DDNS的脚本

NEW_IPv4=$(curl -s http://ipv4.icanhazip.com)
NEW_IPv6=$(curl -s http://ipv6.icanhazip.com)
CURRENT_IPv4=$(cat $(dirname "$0")/current_ipv4.txt)
CURRENT_IPv6=$(cat $(dirname "$0")/current_ipv6.txt)
CURRENT_TIME=$(date +"%F %T")

# 填入DDNS域名
DDNS="ddns.example.com"

# ZONE_ID在Clouflare域名页面上获取
ZONE_ID="1234567890abcdef1234567890abcdef"

# API_TOKEN在Clouflare个人资料页面上创建
API_TOKEN="1234567890abcdef1234567890abcdef"

# RECORD_ID获取应执行以下代码:
# ZONE_ID="你的 Zone ID"
# API_TOKEN="你的API Token"
# curl -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=example.com" \
#     -H "Authorization: Bearer $API_TOKEN" \
#     -H "Content-Type: application/json"
RECORD_ID="1234567890abcdef1234567890abcdef"

if [ -z "$NEW_IPv4" ] && [ -z "$NEW_IPv6" ]; then
  echo "[$CURRENT_TIME] Failed to get IP address" >> $(dirname "$0")/crontab_log.txt
  exit 1
elif [ "$NEW_IPv4" = "$CURRENT_IPv4" ] && [ "$NEW_IPv6" = "$CURRENT_IPv6" ]; then
  echo "[$CURRENT_TIME] No change in IP address" >> $(dirname "$0")/crontab_log.txt
else
  if [ -n "$NEW_IPv4" ] && [ "$NEW_IPv4" != "$CURRENT_IPv4" ]; then
    curl -k -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
      -H "Authorization: Bearer $API_TOKEN" \
      -H "Content-Type: application/json" \
      --data '{"type":"A","name":"'$DDNS'","content":"'$NEW_IPv4'","ttl":1,"proxied":false}' > /dev/null
    echo "$NEW_IPv4" > $(dirname "$0")/current_ipv4.txt
    echo "[$CURRENT_TIME] IPv4 address changed to $NEW_IPv4" >> $(dirname "$0")/crontab_log.txt
  fi
  if [ -n "$NEW_IPv6" ] && [ "$NEW_IPv6" != "$CURRENT_IPv6" ]; then
    curl -k -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
      -H "Authorization: Bearer $API_TOKEN" \
      -H "Content-Type: application/json" \
      --data '{"type":"AAAA","name":"'$DDNS'","content":"'$NEW_IPv6'","ttl":1,"proxied":false}' > /dev/null
    echo "$NEW_IPv6" > $(dirname "$0")/current_ipv6.txt
    echo "[$CURRENT_TIME] IPv6 address changed to $NEW_IPv6" >> $(dirname "$0")/crontab_log.txt
  fi
fi

下方是一个更简单的仅有IPV4 DDNS的脚本,有需要的自取。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#!/bin/sh
NEW_IP=`curl -s http://ipv4.ddnspod.com`
CURRENT_IP=`cat $(dirname "$0")/current_ip.txt`
CURRENT_TIME=$(date +"%F %T")
DDNS="ddns.example.com"
ZONE_ID="1234567890abcdef1234567890abcdef"
API_TOKEN="1234567890abcdef1234567890abcdef"
RECORD_ID="1234567890abcdef1234567890abcdef"
if [ "$NEW_IP" = "$CURRENT_IP" ]
then
        echo "[$CURRENT_TIME] No Change in IP Adddress" >> $(dirname "$0")/crontab_log.txt
else
curl -k -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
     -H "Authorization: Bearer $API_TOKEN" \
     -H "Content-Type: application/json" \
     --data '{"type":"A","name":"'$DDNS'","content":"'$NEW_IP'","ttl":1,"proxied":false}' > /dev/null
echo $NEW_IP > $(dirname "$0")/current_ip.txt
echo "[$CURRENT_TIME] IP changed to $NEW_IP" >> $(dirname "$0")/crontab_log.txt
fi

4、执行Shell脚本并设置定时任务

先执行一次脚本,然后检查Cloudflare解析记录和同文件夹下生成的crontab_log.txt,确认IP是否正确更新。

1
/bin/sh ddns.sh

若脚本执行无误,则可以用crontab设置定时任务。

1
crontab -e

在编辑器最下方粘贴以下代码,脚本路径不要写错了,然后保存退出,这样脚本会没30分钟执行一次。

1
*/30 * * * * sh ~/cfddns/ddns.sh

5、ChatGPT对代码的解释

下面贴一段ChatGPT 3.5 对脚本代码的解释; 这是一个使用Cloudflare API实现DDNS(动态域名解析)的shell脚本。脚本通过curl命令获取当前主机的IPv4和IPv6地址,然后与之前存储的IPv4和IPv6地址进行比较,如果当前的IP地址与之前存储的IP地址不同,则使用Cloudflare API更新DNS记录。 该脚本需要用户提供Cloudflare API的凭据信息,如ZONE_ID、API_TOKEN和RECORD_ID等。用户需要根据自己的实际情况填写这些参数。 该脚本还会将日志信息写入到crontab_log.txt文件中,记录脚本的执行情况和IP地址的变化情况。