Syno NAS: Cron cập nhật IP của Cloudflare

Có vài script cập nhật IP trên Cloudflare được thiết kế để thêm vào danh sách DDNS của Synology DSM. Tuy nhiên DSM chỉ cho phép cài đặt cập nhật IP một domain/DDNS. Thí dụ chúng ta có domain example.com và example.net thuộc DDNS Cloudflare thì chỉ có thể cài đặt một domain thôi.

Trong khi đó, chúng ta có script (bash + python) cập nhật IP tất cả domain/subdomain thuộc một account của Cloudflare chỉ trong một lần gọi.

Ngoài ra chúng ta còn có thể chỉ định không cập nhật domain/subdomain nào có IP tĩnh (tham số -x)

cfip.acc [-f][-e auth_email][-k auth_key][-x pattern[,pattern2]]

-f : luôn cập nhật
-e : AUTH_EMAIL, có thể ghi qua option này hay ghi trong script
-k : AUTH_KEY, có thể ghi qua option này hay ghi trong script
-x : bỏ qua không cập nhật các domain, subdomain theo mẫu regexp. 'example' thay cho domain có chữ example như example.net, example.com và các subdomain của nó, tuy nhiên '^example.com$' chỉ thay cho domain example.com vì không khớp với example.com.vn hay bất kỳ subdomain nào
# script $HOME/cfip.acc
# Thay <<your_email>> và <<your_auth_key>>
# bằng giá trị thực tế
a1="cfip.acc"
a2="© 2020 LNT <lnt@ly-le.info>"
v="version 20231001"
m="Cập nhật IP cho tất cả record A thuộc một tài khoản cloudflare.com"

function usage(){
cat >&2<<EOF
$a1, $v
$a2
$m

usage:
  $(basename $0) [-f][-e auth_email][-k auth_key][-x pattern[,pattern2]]
  mặc định cập nhật IP v4
EOF
exit 1
}
s3='~~~'
s5='-----'
E="✘ Bỏ qua!"
SHM=/dev/shm/cfip
[ ! -d "$SHM" ]&&mkdir -p $SHM
ff=0;X=();ip=''
msg="$a1, $v\n$a2\n$m\n$s3\n"$(date +'%d-%m-%Y %T')
ip=$(curl -s https://icanhazip.com)

while getopts :e:k:x:f opt;do
case $opt in
  f)ff=1;rm -rf $SHM/*;;
  e)AUTH_EMAIL="$OPTARG";;
  k)AUTH_KEY="$OPTARG";;
  x)X+=(`echo "$OPTARG" | tr ',' ' '`);;
  ?)usage
esac
done

# Default account -----
[ "$AUTH_EMAIL" ] || AUTH_EMAIL='<<auth_email>>'
[ "$AUTH_KEY" ] || AUTH_KEY='<<auth_key>>'
#----------------------
[ -e "$SHM/ip" ]&&o4=$(<$SHM/ip)||o4=''
[ ! -z "$ip" ] && printf $ip > $SHM/ip
[[ $ff == 0 && "$ip" == "$o4" ]]&&{ echo -e "$msg\n✓ Tất cả IP không thay đổi\n$s5";exit; }

BASE_URL='https://api.cloudflare.com/client/v4/zones'
H1="X-Auth-Email:$AUTH_EMAIL"
H2="X-Auth-Key:$AUTH_KEY"
H3="Content-Type:application/json"

ZID=$(curl -s -G -H "$H1" -H "$H2" -H "$H3" "$BASE_URL" \
	|jq -r '.result|.[]|select(.status=="active")|with_entries(select(.key == ("id","name")))|"\(.id)=\(.name)"')
	# |python -c "import sys,json;dIn=json.load(sys.stdin)['result']; \
	# print([d['id']+'='+d['name'] for d in dIn])"|sed "s/\(,\|'\|\[\|\]\)//g")

[ -z "$ZID" ]&&{ echo -e "$msg\n‼ Không tìm được Zone ID!\n$s5";exit 1; }
re="(`sed 's/ /|/g'<<<"${X[@]}"`)"
for z in $ZID; do
  n="${z#*=}"
  [[ ! -z "$re" && "$n" =~ $re ]]&&{ msg="$msg\n[Domain $n] $E";continue; }
  zid=${z%=*}
  rs=$(curl -s -G -H "$H1" -H "$H2" -H "$H3" "${BASE_URL}/$zid/dns_records?type=A" \
	|jq --unbuffered -r '.result|.[]|[.id+"="+.name+"="+.content]|@tsv')
	#|python -c "import sys,json; \
	#dIn=json.load(sys.stdin)['result'];print([d['id']+'='+d['name']+'='+d['content'] for d in dIn])" \
	#|sed "s/\(,\|'\|\[\|\]\)//g")

  [ -z "$rs" ]||msg="$msg\n[Domain $n]"
  s=''
  for rc in $rs; do
	IFS='=' read -r id n cIP <<<"$rc"; unset IFS
	[[ ! -z "$re" && "$n" =~ $re ]]&&{ s="${s}  ░ ${n}: $E\n";continue; }
	if [ "$ip" == "$cIP" ];then
		r="✓ IP không thay đổi"
	else
		ret=$(curl -s -X PUT -H "$H1" -H "$H2" -H "$H3" "${BASE_URL}/$zid/dns_records/$id" --data "{\"type\":\"A\",\"name\":\"$n\",\"content\":\"$ip\",\"ttl\":240,\"proxied\":false}" \
		|jq -r '.success')
		#|python -c "import sys,json;print(json.load(sys.stdin)['success'])")
		[ "$ret" = 'true' ]&&r="$cIP → $ip"||r="⛔ Lỗi!"
	fi
	[ ! -z "$r" ]&&s="$s  ░ ${n}: $r\n"
  done
  [ ! -z "$s" ]&&msg="$msg\n${s::-2}"
done
echo -e "$msg\n$s5"

Sử dụng

  1. Login vào DSM với user myusr
  2. Đặt script ở thư mục home của myusr
  3. Control Panel > Task Scheduler > Create
General Settings
Task: DDNS Cloudflare
User: root

Schedule
(x) Run on the following days
    Repeat: daily
...
[x] Continue running within the same day
    Repeat: Every 5 minutes
...

Task Settings
User-defined script:
bash /volume1/homes/myusr/cfip.acc -x example.com -x test.example.net >> /volume1/homes/myusr/cfip.log

[OK] > [x] Enable > [Apply]

Chú thích

  • DSM cài sẵn jq nên có thể dùng jq thay vì python để xử lý json object
  • >> /volume1/homes/myusr/cfip.log” log output của cfip.acc. Sau khi kiểm tra script chay ổn định thì thay bằng “&> /dev/null”
  • Có thể biên tập trực tiếp file crontab thay cho Task Scheduler
# nano /etc/crontab
# Thêm một dòng tương tự như
*/3 * * * * root /bin/bash /volume1/homes/myusr/cfip.acc &> /dev/null
# Khởi động lại crond
# systemctl restart crond
  • Task Scheduler chạy ít nhất 5 phút 1 lần, thích liệt kê các thời điểm chạy cron job như
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57

thay cho

*/3

Tuy nhiên dùng cách nào cũng được và khi soạn thảo crontab chúng ta có thể cho thời gian chạy tùy ý.

Comments Off on Syno NAS: Cron cập nhật IP của Cloudflare

Filed under Software

Comments are closed.