Loading... 转载自:[NAT VPS自建DDNS的几种方法](https://www.168itw.com/notes/nat-vps-ddns/)。 ### Cloudflare API 这种方法应该是用的最多的。 前提条件: - 自有域名; - 域名已接入Cloudflare。 步骤如下: 1. 获取Global API Key: 登入Cloudflare查看:[https://dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens); 2. 设置DDNS域名: 在Cloudflare DNS面板中新建A记录,例如myddns指向1.1.1.1并关闭CF代理开关让云朵灰色; 3. 下载脚本: ```bash wget -N --no-check-certificate https://raw.githubusercontent.com/yulewang/cloudflare-api-v4-ddns/master/cf-v4-ddns.sh ``` 也可以用GitHub另外2个脚本: - [https://github.com/jeessy2/ddns-go](https://github.com/jeessy2/ddns-go); - [https://github.com/NewFuture/DDNS](https://github.com/NewFuture/DDNS); 4. 编辑脚本: 将其中对应的信息进行修改: ```bash # API key, see https://www.cloudflare.com/a/account/my-account, # incorrect api-key results in E_UNAUTH error CFKEY=您的Global API Key # Username, eg: user@example.com CFUSER=您Cloudflare的帐户名称 # Zone name, eg: example.com CFZONE_NAME=您的域名 # Hostname to update, eg: homeserver.example.com CFRECORD_NAME=你的二级域名 ``` 5. 修改脚本权限: ```bash chmod +x cf-v4-ddns.sh ``` 6. 测试运行脚本: ```bash ./cf-v4-ddns.sh ``` 如果操作无误,步骤2中A记录的IP会变为VPS的公网IP; 7. 设定定时任务自动更新DDNS的IP: ```bash crontab -e ``` 插入下面行,表示每分钟更新DDNS: ```bash */1 * * * * /root/cf-v4-ddns.sh >/dev/null 2>&1 ``` 保存并退出。 备份一下这里使用到的`cf-v4-ddns.sh`脚本: ```bash #!/usr/bin/env bash set -o errexit set -o nounset set -o pipefail # Automatically update your CloudFlare DNS record to the IP, Dynamic DNS # Can retrieve cloudflare Domain id and list zone's, because, lazy # Place at: # curl https://raw.githubusercontent.com/yulewang/cloudflare-api-v4-ddns/master/cf-v4-ddns.sh > /usr/local/bin/cf-ddns.sh && chmod +x /usr/local/bin/cf-ddns.sh # run `crontab -e` and add next line: # */1 * * * * /usr/local/bin/cf-ddns.sh >/dev/null 2>&1 # or you need log: # */1 * * * * /usr/local/bin/cf-ddns.sh >> /var/log/cf-ddns.log 2>&1 # Usage: # cf-ddns.sh -k cloudflare-api-key \ # -u user@example.com \ # -h host.example.com \ # fqdn of the record you want to update # -z example.com \ # will show you all zones if forgot, but you need this # -t A|AAAA # specify ipv4/ipv6, default: ipv4 # Optional flags: # -f false|true \ # force dns update, disregard local stored ip # default config # API key, see https://www.cloudflare.com/a/account/my-account, # incorrect api-key results in E_UNAUTH error CFKEY= # Username, eg: user@example.com CFUSER= # Zone name, eg: example.com CFZONE_NAME= # Hostname to update, eg: homeserver.example.com CFRECORD_NAME= # Record type, A(IPv4)|AAAA(IPv6), default IPv4 CFRECORD_TYPE=A # Cloudflare TTL for record, between 120 and 86400 seconds CFTTL=120 # Ignore local file, update ip anyway FORCE=false WANIPSITE="http://ipv4.icanhazip.com" # Site to retrieve WAN ip, other examples are: bot.whatismyipaddress.com, https://api.ipify.org/ ... if [ "$CFRECORD_TYPE" = "A" ]; then : elif [ "$CFRECORD_TYPE" = "AAAA" ]; then WANIPSITE="http://ipv6.icanhazip.com" else echo "$CFRECORD_TYPE specified is invalid, CFRECORD_TYPE can only be A(for IPv4)|AAAA(for IPv6)" exit 2 fi # get parameter while getopts k:u:h:z:t:f: opts; do case ${opts} in k) CFKEY=${OPTARG} ;; u) CFUSER=${OPTARG} ;; h) CFRECORD_NAME=${OPTARG} ;; z) CFZONE_NAME=${OPTARG} ;; t) CFRECORD_TYPE=${OPTARG} ;; f) FORCE=${OPTARG} ;; esac done # If required settings are missing just exit if [ "$CFKEY" = "" ]; then echo "Missing api-key, get at: https://www.cloudflare.com/a/account/my-account" echo "and save in ${0} or using the -k flag" exit 2 fi if [ "$CFUSER" = "" ]; then echo "Missing username, probably your email-address" echo "and save in ${0} or using the -u flag" exit 2 fi if [ "$CFRECORD_NAME" = "" ]; then echo "Missing hostname, what host do you want to update?" echo "save in ${0} or using the -h flag" exit 2 fi # If the hostname is not a FQDN if [ "$CFRECORD_NAME" != "$CFZONE_NAME" ] && ! [ -z "${CFRECORD_NAME##*$CFZONE_NAME}" ]; then CFRECORD_NAME="$CFRECORD_NAME.$CFZONE_NAME" echo " => Hostname is not a FQDN, assuming $CFRECORD_NAME" fi # Get current and old WAN ip WAN_IP=`curl -s ${WANIPSITE}` WAN_IP_FILE=$HOME/.cf-wan_ip_$CFRECORD_NAME.txt if [ -f $WAN_IP_FILE ]; then OLD_WAN_IP=`cat $WAN_IP_FILE` else echo "No file, need IP" OLD_WAN_IP="" fi # If WAN IP is unchanged an not -f flag, exit here if [ "$WAN_IP" = "$OLD_WAN_IP" ] && [ "$FORCE" = false ]; then echo "WAN IP Unchanged, to update anyway use flag -f true" exit 0 fi # Get zone_identifier & record_identifier ID_FILE=$HOME/.cf-id_$CFRECORD_NAME.txt if [ -f $ID_FILE ] && [ $(wc -l $ID_FILE | cut -d " " -f 1) == 4 ] \ && [ "$(sed -n '3,1p' "$ID_FILE")" == "$CFZONE_NAME" ] \ && [ "$(sed -n '4,1p' "$ID_FILE")" == "$CFRECORD_NAME" ]; then CFZONE_ID=$(sed -n '1,1p' "$ID_FILE") CFRECORD_ID=$(sed -n '2,1p' "$ID_FILE") else echo "Updating 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" | grep -Po '(?<="id":")[^"]*' | head -1 ) 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" | grep -Po '(?<="id":")[^"]*' | head -1 ) echo "$CFZONE_ID" > $ID_FILE echo "$CFRECORD_ID" >> $ID_FILE echo "$CFZONE_NAME" >> $ID_FILE echo "$CFRECORD_NAME" >> $ID_FILE fi # If WAN is changed, update cloudflare 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 "Updated succesfuly!" echo $WAN_IP > $WAN_IP_FILE exit else echo 'Something went wrong :(' echo "Response: $RESPONSE" exit 1 fi ``` ### he.net DDNS he.net的DDNS非常方便,不需要任何脚本,curl请求即可,添加crontab定时任务。 具体参考:[https://dns.he.net/docs.html](https://dns.he.net/docs.html)。 crontab参考: ```bash */1 * * * * curl -4 "https://dyn.example.com:password@dyn.dns.he.net/nic/update?hostname=dyn.example.com" ``` he.net会获取当前VPS的IP地址更新到DNS记录。 ### Dynu.com、ChangeIP.com等 这种很简单,直接注册,然后根据官方提供的脚本更新DNS记录即可。 上面三种方法,都会有一个问题,DDNS生效时间和DNS缓存时间,会导致NAT更换IP后中断几分钟不等。比如Cloudflare免费用户DNS TTL是1分钟,he.net是5分钟,Dynu是30s。 所以就有了第四种方法,也是最优解决方案。 ### Cloudflare Tunnel 借助Cloudflare Tunnel实现内网穿透,不受DDNS影响,而且完全免费。 Cloudflare Tunnel功能很强大,具体参考官方教程:[https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)。 最后修改:2026 年 03 月 09 日 © 转载自他站 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏。