Ryan Shang

生死看淡,不服就干

0%

使用Cloudflare实现DDNS

一、背景

在一些场景中,有时IP会发生变化,比如家庭宽带的IP、部分只提供动态IP的云服务器厂商,这时候为了方便使用,就可以使用DDNS的方式来实现当IP变化时,更新域名的解析。这里记录下使用Cloudflare来实现DDNS解析的过程。

二、简介

1. Cloudflare

Cloudflare(Cloudflare, Inc.)是一家总部位于旧金山的美国跨国科技企业,以向客户提供基于反向代理的内容分发网络(Content Delivery Network, CDN)及分布式域名解析服务(Distributed Domain Name Server)为主要业务。这家企业提供的免费计划,就足够个人建站使用。

2. DDNS

DDNS(Dynamic Domain Name Server,动态域名服务)是将用户的动态IP地址映射到一个固定的域名解析服务上,用户每次连接网络的时候客户端程序就会通过信息传递把该主机的动态IP地址传送给位于服务商主机上的服务器程序,服务器程序负责提供DNS服务并实现动态域名解析。

三、环境准备

1. Cloudflare账号

使用邮箱注册Cloudflare账号

2. 添加在Cloudflare中的域名

免费计划即可。这里不做添加域名过程的记录,操作很简单。

ddns.demo.com,解析IPv4为例。

3. crontab

定时任务,以便定期执行DDNS任务

四、过程

1. 创建API Token

  • 进入https://dash.cloudflare.com/profile/api-tokens
  • 选择Create Token
  • 选择Edit zone DNS
  • 调整Permissions,新增ZoneDNSReaD
  • 调整Zone Resources,选择includeSpecificddns.demo.com,其他不变
  • 点击Continue to summary
  • 点击Create Token
  • 保存获取到的Token,长度为40位

2. 创建一条DNS记录,获取DNS Record ID

在Cloudflare中创建一条DNS记录,域名为ddns.demo.com,对应的IP可以先随便填写一个。

登录后台后在浏览器中访问:https://dash.cloudflare.com/api/v4/zones/${ZONE_ID}/dns_records?per_page=200&order=name&direction=asc,其中ZONE_ID需要自己手动替换,是Cloudflare账号添加域名后,进入域名的Overview页面,Zone Id在页面的右侧一列的下方,长度为32位,参考

上面的链接会返回JSON数据,在其中找到需要进行DDNS的域名的DNS Record数据,获取其ID,长度为32位。

或者直接在域名DNS解析设置页面打开F12开发者工具,在请求中找到该请求获取DNS Record ID。

3. 创建脚本cloudflare-ddns.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash

echo '---------------------------------------------------------------------------------------'

API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ZONE_ID="yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
DOMAIN="ddns.demo.com"
DNS_RECORD_ID="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"

IP=`curl -4 ip.sb`

echo "ip: $IP"

curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$DOMAIN\",\"content\":\"$IP\",\"ttl\":1,\"proxied\":false}"

其中,
API_KEY为上面创建的API Token,长度40位
ZONE_ID为Cloudflare账号添加域名后,进入域名的Overview页面,Zone Id在页面的右侧一列的下方,长度为32位,参考
DOMAIN为需要使用的域名,文中例子为ddns.demo.com
DNS_RECORD_ID为上一步中获取到的ID,长度为32位

调整完成后,可是直接执行该脚本,如果返回类似以下,最外层的success返回值为true则表示参数正常:

1
{"result":{"id":"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz","name":"ddns.demo.com","type":"A","content":"1.2.3.4","proxiable":true,"proxied":false,"ttl":1,"settings":{},"meta":{"auto_added":false,"managed_by_apps":false,"managed_by_argo_tunnel":false},"comment":null,"tags":[],"created_on":"2023-12-15T13:53:42.343322Z","modified_on":"2025-01-05T22:00:07.276492Z"},"success":true,"errors":[],"messages":[]}

4. 添加计划任务

执行:

1
sudo crontab -e

添加一条定时任务:

1
*/5 * * * * /bin/bash /path/to/save/cloudflare-ddns.sh >> /tmp/cloudflare-ddns.log 2>&1

大概意思是,每5分钟执行一次cloudflare-ddns.sh脚本,把执行结果输出到/tmp/cloudflare-ddns.log中。

记得调整路径为自己保存脚本的位置。