Cú pháp
cfip.acc [-f] [ip] [-sub.domain[,sub2 ...]]
-f : buộc cập nhật
ip : dùng ip/WAN IP
-sub.domain: ngoại trừ sub.domain
Người dùng điền thông tin tài khoản cloudflare.com của mình vào trong script
AUTH_EMAIL='...'
AUTH_KEY='...'
Cú pháp cập nhật IP cho tất cả domain/subdomain thuộc tài khoản trên như sau
# cfip.acc
… trừ subdomain sub.example.com và sub.domain.org
# cfip.acc -sub.example.com,sub.example.org
… trừ domain example.com và tất cả subdomain
# cfip.acc -example.com,*.example.com
hoặc nếu không có gì nhầm lẫn
# cfip.acc -*example.com
Script
#!/bin/bash
# cfip.acc
# Update dynamic IP for all DNS record A on cloudflare
# © 2020 LNT <lnt@ly-le.info>
# version 20220102
#
[ ! command -v jq &> /dev/null ] && sudo apt install -y jq
AUTH_EMAIL=''
AUTH_KEY=''
[[ ! "$AUTH_EMAIL" || ! "$AUTH_KEY" ]] && { echo ">>> Thiếu AUTH_EMAIL/AUTH_KEY! <<<"; exit 1; }
SHM=/dev/shm/cfIP
[ -d $SHM ] || mkdir $SHM
[ '-f' = "$1" ] && { rm -rf $SHM/*; ff=1; shift; } || ff=0
[[ "$1" =~ ([0-9]{1,3}\.)+[0-9]{1,3} ]] && { uIP="$1"; shift; } || uIP=''
[ -z "$uIP" ] && uIP=`dig +short @1.1.1.1 whoami.cloudflare ch txt | sed 's/"//g'`
[ -e "$SHM/ip" ] && oIP=$(<$SHM/ip) || oIP=''
[ "$uIP" == "$oIP" ] && { echo ">>> IP không thay đổi! <<<"; exit 1; } || printf $uIP > $SHM/ip
BASE_URL='https://api.cloudflare.com/client/v4/zones'
if [ $# -eq 0 ]; then
EXCLUDE='';
elif [ $# -eq 1 ] && [[ "$1" =~ -* ]]; then
EXCLUDE="$1";
else
echo
echo 'Cập nhật IP cho tất cả domain/subdomain cùng tài khoản ở cloudflare.com'
echo
echo "Cú pháp: $(basename $0) [-f] [ip] [-sub.domain[,sub2 ...]]"
echo ' -f : buộc cập nhật'
echo ' ip : dùng ip/WAN IP'
echo ' -sub.domain: ngoại trừ sub.domain'
exit 1
fi
[ "$EXCLUDE" ] && { EXCLUDE=`sed -e 's/,-/,/g' -e 's/^-//' <<< "$EXCLUDE"`;IFS="," read -a EXCLUDE <<< "$EXCLUDE"; }
c='null'
for s in "${EXCLUDE[@]}"; do
[[ $s == '*'* ]] && p="(.name|endswith(\"${s#*'*'}\"))" || p=".name==\"$s\""
c="$c or $p"
done
ZONES=`curl -s -X GET "$BASE_URL" \
-H "Content-Type:application/json" \
-H "X-Auth-Key:$AUTH_KEY" \
-H "X-Auth-Email:$AUTH_EMAIL" | jq -r '.result | .[] | with_entries(select(.key == ("id","name"))) | "\(.id)=\(.name)\r"'`
for zone in $ZONES; do
echo "+ Domain ${zone#*=}"
zid=${zone%=*}
tmp=$(curl -s -X GET "${BASE_URL}/$zid/dns_records?type=A" \
-H "X-Auth-Email: ${AUTH_EMAIL}" \
-H "X-Auth-Key: ${AUTH_KEY}" \
-H "Content-Type: application/json" | jq -r '.result[] | {id,name,content}' | jq -s .)
# loại trừ các sub thuộc EXCLUDE
[ "$c" ] && hosts=$(echo "$tmp" | jq ".[] | del(select($c)) | select(. != null)" | jq -s .) || hosts=$(echo "$tmp" | jq -s ".[]")
echo "$hosts" | jq -r '.[] | [.id, .name, .content] | @tsv' |
while IPS=$'\t' read id name cIP; do
if [[ "$uIP" == "$cIP" ]]; then
ret='IP không đổi!'
else
ret=$(curl -s -X PUT "${BASE_URL}/$zid/dns_records/$id" \
-H "X-Auth-Email: ${AUTH_EMAIL}" \
-H "X-Auth-Key: ${AUTH_KEY}" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$name\",\"content\":\"${uIP}\",\"ttl\":3600,\"proxied\":false}" | jq -r '.success')
fi
echo " $name =-> $ret"
done
done