双运营商下的 DDNS (Cloudflare)

说在前面

首先说一下我目前的网络情况,长久以来家里一直用的都是电信的网络,前段时间听朋友提到联通有 10 元宽带的业务,恰好名下有个没地方安装的固话,那就一起装了吧。

之前自认为电信的网络还是不错的,直到用上联通后测试到本地阿里云的延迟基本不超过 10ms 才发现原来天外有天,现在测试不知道为什么也 20ms+ 了,怪。

另外联通申请公网 IP 的体验也是好的一批,第一天下午 5 点多给 10010 打电话反应需要公网 IP,客服人员给转到当地宽带技术部门后,第二天上午 9 点左右重新拨号就变成公网 IP了,后面还打了 3 通电话回访问题是否解决及满意度。想当时找电信要公网 IP 那叫一个波折,自己找了电信好几次怎么都不给开,说没有这个业务,后来还是咸鱼上付费找人搞得,还得去营业厅签承诺书拍照,属实心累。

网络环境

画了个简图,目前我这边的网络接入情况:

  • 域名 DNS 服务商:Cloudflare
  • 网络接入:
    • 联通:300M,动态公网 IP,解析到 cu.example.com
    • 电信:300M,动态公网 IP,解析到 ct.example.com

开始配置

预先建立域名解析记录

首先需要先在 CLoudflare 上建立两条 A 记录,记录值随意,后续执行 DDNS 脚本后会自动变更为联通和电信的出口公网 IP 地址。

获取账户信息配置信息

获取 ZONE ID 和 API TOKEN

在域名的概述页面可以直接获取到 ZONE ID,API TOKEN 需要在同一页面的下方进入管理页面创建:

创建 API TOKEN 按图示操作,安全起见限制该 TOKEN 可以编辑的域名,其他如无特殊需求保持默认即可:

获取 RECORD ID

在终端执行如下命令分别获取第一步创建的两条解析记录的 RECORD ID,注意替换自己的信息:

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=cu.example.com" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json"

创建 Shell 脚本

创建两个 Shell 脚本,分别用以获取联通和电信的出口地址,在防火墙上做好策略路由,设置两个接口的流量走不同的运营商线路:

我这里所有流量默认是走联通线路的,所以只需要在上面指定一个走电信线路的路由即可

联通线路获取 IP 使用的接口为:ipv4.ddnspod.com

电信线路获取 IP 使用的接口为:4.ipw.cn (119.28.5.105)

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_cu_ip.txt`
CURRENT_TIME=$(date +"%F %T")
DDNS="cu.example.com"
ZONE_ID="ZONE_ID"
API_TOKEN="API_TOKEN"
RECORD_ID="RECORD_ID"
if [ "$NEW_IP" = "$CURRENT_IP" ]
then
echo "[$CURRENT_TIME] No Change in IP Adddress" >> $(dirname "$0")/crontab_cu_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_cu_ip.txt
echo "[$CURRENT_TIME] IP changed to $NEW_IP" >> $(dirname "$0")/crontab_cu_log.txt
fi
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://4.ipw.cn`
CURRENT_IP=`cat $(dirname "$0")/current_cu_ip.txt`
CURRENT_TIME=$(date +"%F %T")
DDNS="cu.example.com"
ZONE_ID="ZONE_ID"
API_TOKEN="API_TOKEN"
RECORD_ID="RECORD_ID"
if [ "$NEW_IP" = "$CURRENT_IP" ]
then
echo "[$CURRENT_TIME] No Change in IP Adddress" >> $(dirname "$0")/crontab_cu_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_cu_ip.txt
echo "[$CURRENT_TIME] IP changed to $NEW_IP" >> $(dirname "$0")/crontab_cu_log.txt
fi

设置计划任务

我这里设置每 10 分钟执行一次:

每次执行完会生成日志:

至此已设置完成。


参考


双运营商下的 DDNS (Cloudflare)
https://blog.tddt.cc/posts/10.DDNS-For-Two-ISP.html
作者
TechPANG
发布于
2024年9月29日
许可协议