«

(指令获取本机ip)linux精简脚本cloudflare ddns,不需要docker,支持ipv6

学长 发布于 阅读:704 软件


通过curl ipinfo.io获得

不加/ip获得更多信息

curl https://v6.ipinfo.io/ip

curl https://ipinfo.io/ip


想手撕cloudflare的api做AAAA

一开始用的docker是 https://hub.docker.com/r/oznu/cloudflare-ddns/


docker run \
--name ddns \
--restart=always \
-e API_KEY=具体API \
-e ZONE=具体域名 \
-e SUBDOMAIN=相关子域名\
-e RRTYPE=A \
-e CRON="*/15 * * * *" \
oznu/cloudflare-ddns

新版的docker会有docker address already in use
去edit中把桥接删掉改成host就好了


上面的A的IPv4跑起来没问题,只是第一次跑的话,ssh指令结束后docker也就停了,得去portainer重新运行下

但是IPv6就更新不到,在oznu/cloudflare-ddns的说明中看到得启用docker的IPv6。。。


docker run \
--name ddns_v6 \
--restart=always \
-e API_KEY=具体API \
-e ZONE=具体域名 \
-e SUBDOMAIN=相关子域名\
-e RRTYPE=AAAA \
-e CRON="*/15 * * * *" \
oznu/cloudflare-ddns

docker做AAAA解析需要docker开启ipv6支持 实际开启很麻烦,默认的桥接就很多限制而且必须是公网分配下来的ip局域网的v6没法做桥接,还得在/80以内 以上说法参考自 https://www.rectcircle.cn/posts/docker-ipv6/



最简单使用“通过 IPv6NAT 方式支持 IPv6”但是得通过robbertkl/docker-ipv6nat。

就很没效率,实际执行的只是corntab 固定时间把 IP地址更新到赛博大善人那


首先旧版本的是使用X-Auth-Email和X-Auth-Key

新版本使用的是Authorization: Bearer


第一步获得zones的ID

api=具体API


剩下的就是怎么处理json的问题了,一般选择的是python,为了做到最简洁尝试使用sed grep awk cut进行处理。。。直接字符串截取,按长度。。。

https://www.cnblogs.com/stevensfollower/p/5093001.html


zones=$(curl -sX GET "https://api.cloudflare.com/client/v4/zones" \
-H "Authorization: Bearer $api" \
-H "Content-Type:application/json")
//通过$zones查询到具体的zones的情况,然后通过awk找到对应字符的位置

p1=$(awk -v a="$zones" -v b="id" 'BEGIN{print index(a,b)}')
zones=${zones:$(expr $p1 + 4):32}

//id对应的位置再向后4个,后面的32位就是zone的ID了

或者合并一行写:

zones=${zones:$(expr $(awk -v a="$zones" -v b="id" 'BEGIN{print index(a,b)}') + 4):32}


//获得具体的dns记录

dns_records=$(curl -sX GET "https://api.cloudflare.com/client/v4/zones/$zones/dns_records" \
-H "Authorization: Bearer $api" \
-H "Content-Type:application/json")

//继续对DNS记录进行处理找到具体的记录

另外的方法就是ip v6 nat 一个简单开启 Docker IPv6 的方法

或者用我写的脚本

leejohannes/Cloudflare-IPV6-Script: DDNS auto update to Cloudflare

下面引用我项目的README

Cloudflare-IPV6-Script

DDNS auto update to Cloudflare.


Only using awk,curl.


simple not need python or jq.

JSON format is sensitive...

you may add |tr -d '\n'.


or rewrite with jq...

How to use?

download and upload to you root home.

curl https://raw.githubusercontent.com/leejohannes/Cloudflare-IPV6-Script/refs/heads/main/ddns_v6.sh -o ddns_v6.sh

set your API Token with Edit zone DNS.


only supoort this.

bash ./ddns_v6.sh

depends on your shell.


and you may add it to crontab :

  1. crontab -e
  2. shift + g
  3. insert i, input * * * * * bash /roo/tddns_v6.sh

if you wanna make running log

* * * * * bash /root/ddns_v6.sh >> /root/ddns_v6_running.log 2>&1

Force Update to Cloudflare

bash ./ddns_v6.sh -f

How it run?

check IPVP by ip addr, since ipv6 can give to each device


compare with log,same won't trigger synchronizing Data


if not same or dont have will start synchronizing:

  1. check ZONE ID
  2. check DNS recorders
  3. update DNS recorder

考虑到国内难用github,脚本代码

#!/bin/bash

#API设置
API="m7WYdaqBPaF4YKU9GAPWe813CRJ96uwLM1vI0jAD"
SUBDOMAIN="s"
TYPE="AAAA"

#获取现在的IPV6
CURRENT_IP=$(ip addr | grep inet6 \
    | grep global | grep -v 'fd' \
    | grep -v 'fc'|awk '{print $2}' \
    | awk -F '/' '{print $1}'|awk 'NR==1{print; exit}'
    )

CLOUDFLARE_DNS(){
    #获取指定域名的zone id
    local ZONE_API_URL="https://api.cloudflare.com/client/v4/zones"
    local ZONE_RESPONSE=$(curl -s -X GET "$ZONE_API_URL" \
        -H "Authorization: Bearer $API" \
        -H "Content-Type:application/json")
    local ZONE_ID=$(echo "$ZONE_RESPONSE"| awk -F'"id":' '{print $2}'| awk -F'"' '{print $2}')
    echo Zone ID : $ZONE_ID
    DOMAIN_NAME=$(echo "$ZONE_RESPONSE" | awk -F'"name":' '{print $2}' | awk -F'"' '{print $2}')
    echo Domain : $DOMAIN_NAME
    RECORD_NAME="$SUBDOMAIN"".""$DOMAIN_NAME"
    echo Recode Name : $RECORD_NAME

    #获取指定域名的DNS记录
    local RECORD_API_URL="https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records"
    local RECORD_RESPONSE=$(curl -s -X GET "$RECORD_API_URL" \
            -H "Authorization: Bearer $API" \
            -H "Content-Type: application/json")
    #awk办法,如果有问题改去JQ
    local a="awk -F'\"name\":\"$RECORD_NAME\",\"type\":\"$TYPE\"' '{print \$2}'| awk -F'\"content\":\"' '{print \$2}' | awk -F'\"' '{print \$1}'"
    local CONTENT=$(echo "$RECORD_RESPONSE" | eval "$a")
    local a="awk -F'\",\"name\":\"$RECORD_NAME\",\"type\":\"$TYPE\"' '{print \$1}'"
    local RECORD_ID=$(echo "$RECORD_RESPONSE" | eval "$a")
    local RECORD_ID=${RECORD_ID:0-32}
    #如果awk有问题用JQ临时代替下
:<<EOF
    CONTENT=$(echo "$RECORD_RESPONSE" | jq -r \
     --arg record_name "$RECORD_NAME" \
     --arg record_type "$TYPE" \
     '.result[]
     | select(.name == $record_name and .type == $record_type)
     | .content')
    RECORD_ID=$(echo "$RECORD_RESPONSE" | jq -r \
    --arg record_name "$RECORD_NAME" \
    --arg record_type "$TYPE" \
    '.result[]
    | select(.name == $record_name and .type == $record_type)
    | .id')
EOF
    echo DNS Record : $CONTENT
    echo Record ID : $RECORD_ID

    #更新指定域名的DNS记录
    local UPDATE_API_URL="https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID"
    echo -e "\e[1;91m=========================\e[0m"
    local UPDATE_RESPONSE=$(curl -X PUT $UPDATE_API_URL \
        -H "Authorization: Bearer $API" \
        -H "Content-Type: application/json" \
        --data "{
            \"type\": \"$TYPE\",
            \"name\": \"$RECORD_NAME\",
            \"content\": \"$CURRENT_IP\"
        }")
    echo -e "\e[1;91m=========================\e[0m"
    local a=$(echo $UPDATE_RESPONSE | awk -F '"success":' '{print($2)}'|awk -F',' '{print $1}')
    if [ "$a" == "true" ];then
        echo $CURRENT_IP > ddns_v6.log
        echo 1 >> ddns_v6.log
        echo "success":$a
    else
        echo "fail"
        echo $UPDATE_RESPONSE
    fi
}

#输出现在的IPV6
date
echo $CURRENT_IP -- ipv6 now
#获取以前存储的IPV6
SAVED_IP=$(awk 'NR==1{print; exit}' ddns_v6.log)
echo $SAVED_IP -- ipv6 before
#判断是否相同
if [ -z "$CURRENT_IP" ];then
    echo No WAN IPV6
else
    if [ "$SAVED_IP" == "$CURRENT_IP" ];then
        echo same
        #读取第二行查看是否同步了
        SYN_STATUS=$(awk 'NR==2{print; exit}' ddns_v6.log)
        if [ "$SYN_STATUS" == "1" ]; then
            echo -e "SYNED \nNo need update\nAdd \e[91m-f\e[0m to force update"
        else
            echo !!!not SYNED, Got prolem!!!
            CLOUDFLARE_DNS
        fi
    else
        echo not same
        CLOUDFLARE_DNS
    fi
fi
if [ "$1" == "-f" ];then
    if [ ! -z "$2" ];then
    echo Pointed IP: "$2"
    CURRENT_IP="$2"
    fi
    CLOUDFLARE_DNS
fi


扫描二维码,在手机上阅读