国内动态IP自动更新到Cloudflare DNS

by CUNOE, March 31, 2024

由于国内网络环境的特殊性,动态IP的情况比较常见。如果你有一个动态IP,但又想通过域名访问你的服务器,那么你需要一个动态DNS服务。本文将介绍如何使用Cloudflare的API实现动态IP自动更新到Cloudflare的DNS记录。

Cloudflare为我们提供了非常丰富的API,我们可以通过API实现对DNS记录的增删改查。这里我们使用Cloudflare的API来实现动态IP的更新。

首先,我们需要一个Cloudflare的账号,并且在Cloudflare上添加一个域名。

访问 https://dash.cloudflare.com/profile/api-tokens 获取你的API Key,注意给予该API Key适当的权限(区域资源)。

然后,我们需要一个脚本来实现动态IP的更新。这里我们使用bash脚本来实现,脚本如下:

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
# 配置
CFKEY=<请修改为你的CFKEY>
CFUSER=<请修改为你的CFUSER>
CFZONE_NAME=<请修改为你的CFZONE_NAME 如cunoe.com>
CFRECORD_NAME=<请修改为你的CFRECORD_NAME 如blog.cunoe.com>
CFRECORD_TYPE=<根据你的DNS类型修改 A or AAAA>
CFTTL=120
# 通过该网站获取WAN IP
WANIPSITE="http://ipv4.icanhazip.com"
if [ "$CFRECORD_TYPE" = "A" ]; then
  :
elif [ "$CFRECORD_TYPE" = "AAAA" ]; then
  WANIPSITE="http://ipv6.icanhazip.com"
else
  echo "$CFRECORD_TYPE DNS类型无效(只支持 A or AAAA)"
  exit 2
fi
# 检查是否有必要的配置
if [ "$CFKEY" = "" ]; then
  echo "ApiKey无效,请查看: https://dash.cloudflare.com/profile/api-tokens"
  exit 2
fi
if [ "$CFUSER" = "" ]; then
  echo "用户名无效"
  exit 2
fi
if [ "$CFRECORD_NAME" = "" ]; then
  echo "记录名无效"
  exit 2
fi
# 域名不合法
if [ "$CFRECORD_NAME" != "$CFZONE_NAME" ] && ! [ -z "${CFRECORD_NAME##*$CFZONE_NAME}" ]; then
  CFRECORD_NAME="$CFRECORD_NAME.$CFZONE_NAME"
  echo " => 域名不合法 $CFRECORD_NAME"
fi
# 获取WAN IP
WAN_IP=`curl -s ${WANIPSITE}`
# 获取 Cloudflare 的 zone_identifier & record_identifier
CFZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$CFZONE_NAME" -H "X-Auth-Email: $CFUSER" -H "X-Auth-Key: $CFKEY" -H "Content-Type: application/json" | jq -r ".result[0].id" )
CFRECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records?name=$CFRECORD_NAME" -H "X-Auth-Email: $CFUSER" -H "X-Auth-Key: $CFKEY" -H "Content-Type: application/json"  | jq -r ".result[0].id" )
echo "CFZONE_ID=$CFZONE_ID"
echo "CFRECORD_ID=$CFRECORD_ID"

echo "Updating DNS to $WAN_IP"
RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records/$CFRECORD_ID" \
  -H "X-Auth-Email: $CFUSER" \
  -H "X-Auth-Key: $CFKEY" \
  -H "Content-Type: application/json" \
  --data "{\"id\":\"$CFZONE_ID\",\"type\":\"$CFRECORD_TYPE\",\"name\":\"$CFRECORD_NAME\",\"content\":\"$WAN_IP\", \"ttl\":$CFTTL}")
if [ "$RESPONSE" != "${RESPONSE%success*}" ] && [ "$(echo $RESPONSE | grep "\"success\":true")" != "" ]; then
  echo "成功更新"
  exit
else
  echo '响应错误'
  echo "Response: $RESPONSE"
  exit 1
fi

你可能需要安装jq来解析JSON数据。

sudo apt install jq

填入相关信息,保存为cf-ddns.sh,并添加执行权限。

chmod +x cf-ddns.sh
./cf-ddns.sh

这样,你的DNS记录就会自动更新到你的动态IP了。

通过 crontab 定时执行该脚本,实现动态IP的自动更新。

crontab -e

添加一行:

0 4 * * * /path/to/cf-ddns.sh

这样,每天凌晨4点,你的DNS记录就会自动更新到你的动态IP了。