Skip to content

Instantly share code, notes, and snippets.

@shellexy
Created November 18, 2018 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shellexy/4e916a35c9662a25c0e7c3fd91414a47 to your computer and use it in GitHub Desktop.
Save shellexy/4e916a35c9662a25c0e7c3fd91414a47 to your computer and use it in GitHub Desktop.
利用 cloudflare dns 做 ddns
#!/bin/bash
## 利用 cloudflare dns 做 ddns
## 不再用 tp 路由器后,就要在手机或笔电服务器来检测自身公网 ip 了
## curl ifconfig 可以用来获取公网 ip
##
## 使用:
## 可以把本文件保存为 /home/您的用户/cfddns_self_ip.sh
## 然后执行 crontab -e
## 在出来的文件编辑里添加一行
## */5 * * * * bash /home/您的用户/cfddns_self_ip.sh
## 来每隔 5 分钟自动运行一次更新 ddns
# can be A or AAAA
do_record=A
# the interface to get ipv6 address
iface=eth0
# the static suffix we should add to
v6_suf=53
mail="填入您在 cf 注册的邮箱"
authkey="填入您在 cf 申请的 api key"
record="填入您要修改的域名"
cachef=~/.cfddns-$record
cfupdate () {
_type=$1
_addr=$2
echo "Update $_type record for $record to $_addr"
ret=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$recordid" \
-H "X-Auth-Email: $mail" \
-H "X-Auth-Key: $authkey" \
-H "Content-Type: application/json" \
--data '{"type":"'$_type'","name":"'$record'","content":"'$_addr'"}')
if [[ -z $(echo $ret|grep -oP "success\":[^\"]+"|grep true) ]]; then
echo $ret
else
echo "OK."
fi
}
if [[ ! -e $cachef ]]; then
touch $cachef
fi
if [[ $(cat $cachef|grep "id,"|wc -l) -ne 2 ]]; then
domain=$(echo $record |grep -oP "[^.]+\.[^.]+$")
ret=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$domain" \
-H "X-Auth-Email: $mail" \
-H "X-Auth-Key: $authkey" \
-H "Content-Type: application/json")
zoneid=$(echo $ret|grep -oP "\"id\":\"[a-f\d]{32}"|grep -oP "[a-f\d]{32}"|head -n1)
ret=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?name=$record&type=$do_record" \
-H "X-Auth-Email: $mail" \
-H "X-Auth-Key: $authkey" \
-H "Content-Type: application/json")
recordid=$(echo $ret|grep -oP "\"id\":\"[a-f\d]{32}"|grep -oP "[a-f\d]{32}"|head -n1)
echo "recordid,$do_record,$recordid" >> $cachef
echo "zoneid,$zoneid" >> $cachef
else
recordid=$(cat $cachef|grep "recordid,$do_record"|grep -oP "[a-f\d]{32}")
zoneid=$(cat $cachef|grep zoneid|grep -oP "[a-f\d]{32}")
fi
if [[ -z $recordid || -z $zoneid ]]; then
echo "Unable to get recordid or zoneid"
rm -f $cachef
exit 0
fi
if [[ $do_record = "A" ]]; then
#addr_v4=$(curl ipip.tk/ip -4s)
#addr_v4='131.213.206.199'
## 利用 nslookup 来解析域名的 ip 记录
## 不再用 tp 路由器后,就要在手机或笔电服务器来检测自身公网 ip 了
## ifconfig.me 有点慢,改用 ip.sb 好了;debian 默认安装了 wget 而没有 curl,所以用 wget -q -O- ip.sb 代替了
#addr_v4=$(curl ifconfig.me)
addr_v4=$(wget -q -O- ip.sb)
last_addr_v4=$( nslookup "$record" | grep -oP '\d+\.\d+\.\d+\.\d+' | sed 1,2d | head -1 )
## 域名 ip 记录没变化则退出
#if [[ -z $(cat $cachef|grep $addr_v4) ]]; then
## [ xxx -a ooo ] 表示同时满足 xxx 并且 bbb
if [ -n "$last_addr_v4" -a "$last_addr_v4" != "$addr_v4" -a "$addr_v4" != "0.0.0.0" ]; then
sed -i "/v4,/d" $cachef
echo "v4,$addr_v4" >> $cachef
cfupdate "A" $addr_v4
echo "Update A record for $record from $last_addr_v4 to $addr_v4"
fi
else
# check if we have ipv6 address
if [[ -z $(ifconfig $iface|grep inet6|grep -P "2[\da-f:]{4,}") ]]; then exit; fi
addr_v6_prefix=$(curl ipip.tk/ip -6s|grep -oP "[\da-f]+:[\da-f]+:[\da-f]+:[\da-f]+"|cut -f1|head -n1 )
# check if we really can use ipv6
if [[ -z $addr_v6_prefix ]]; then exit; fi
addr_v6="$addr_v6_prefix::$v6_suf"
if [[ -z $(ifconfig $iface|grep $addr_v6) ]]; then
echo "Adding $addr_v6 to $iface"
ip -6 addr add $addr_v6/64 dev $iface
fi
if [[ -z $(cat $cachef|grep $addr_v6) ]]; then
sed -i "/v6,/d" $cachef
echo "v6,$addr_v6" >> $cachef
cfupdate "AAAA" $addr_v6
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment