cfip.sh v.20210408

Cập nhật IP cho domain, subdomain quản lý bới cloudflare.com

Cú pháp: cfip [-f] [ip] [domain [@|*|sub[,…]]]
    -f : thử cập nhật dù theo ghi chép ip chưa thay đổi
    ip : cập nhật theo ip này
   sub : thay cho sub.domain
     @ : thay cho domain
     * : tất cả subdomain, trừ @

Các giá trị mặc định khi chỉ gọi tắt cfip domain @,\* trong đó domain được trích ra rừ $(hostname) hoặc @,\* nếu có chỉ định domain như cfip domain

Script cài đặt jq nếu chưa có, jq là con dao Thụy Sĩ để xử lý các đối tượng Json.

Script này cũng cập nhật/tạo mới record SPF (nếu tìm được MX record) và PTR cũng như cập nhật /etc/hosts. Tuy nhiên phần này bị cắt đi do chỉ phục vụ cho mail server.

Trước hết script lấy thông tin về tất cả A record của domain và subdomain từ cloudflare.com Sau đó đối chiếu với tham số dòng lệnh để biết domain hay subdomain nào cần tác động. Tạo mới nếu chưa có, cập nhật IP nếu cần hoặc thông báo IP không thay đổi.

Như vậy nếu có tham số -f, script sẽ gọi API của cloudflare ít nhất 1 lần. Với n domain hay subdomain, script sẽ gọi API cloudflare tối đa n+1 lần.

#!/bin/bash
# cfip+.sh v.20210408, Ly Anh Tuan <lnt@ly-le.info>
echo "Cập nhật IP cho cloudflare.com"
( command -v jq &> /dev/null ) || apt install -y jq &> /dev/null
# cloudflare account
AUTH_EMAIL='your_email'
AUTH_KEY='your_auth_key'
ZID='your_zone_id'
#
BU="https://api.cloudflare.com/client/v4/zones/${ZID}/dns_records"
hdr='-H X-Auth-Email:'${AUTH_EMAIL}' -H X-Auth-Key:'${AUTH_KEY}' -H Content-Type:application/json'
SM=/dev/shm/cfIP
[ -d $SM ] || mkdir $SM
[ '-f' == "$1" ] && { rm -rf $SM/*; shift; }
[[ "$1" =~ ([0-9]{1,3}\.)+[0-9]{1,3} ]] && { uIP="$1"; shift; } || uIP=''
set -f
H=$(hostname)
# default: -f domain @,\*
if [ $# -eq 0 ]; then
  DM=${H#*.}
  PR="@,*"
elif [ $# -eq 1 ]; then
  DM="$1"
  PR="@,*"
elif [ $# -eq 2 ]; then
  DM="$1"
  PR="$2"
else
  echo "usage : $(basename $0) [-f] [ip] [domain [@|\*|sub[,...]]]"
  echo '   -f : luôn cập nhật'
  echo '   ip : cập nhật theo ip này'
  echo '  sub : thay cho sub.domain'
  echo '    @ : thay cho domain'
  echo '    * : tất cả subdomain, trừ @'
  exit 1
fi
zc="-► không thay đổi!"
[ ! -z "$uIP" ] && IP="$uIP" || IP=$(curl -s -S ifconfig.me/ip)
[ -e "$SM/ip" ] && oIP=$(<$SM/ip) || oIP=''
printf $IP > $SM/ip
[[ "$IP" = "$oIP" ]] && { echo "IP: $zc"; exit 0; }
#
cfr=$(curl -s -S $hdr -G "${BU}?type=A" | jq -r '.result[] | {id,name,content,type}' | jq -s '.')
A=()
[[ "$PR" == *\** ]] && A=( `echo $cfr | jq -r '.[] | select(.type == "A") | .name'` )
A+=( `echo $PR | grep -Po '([^,*]+)' | sed -e "/@/!s/\(.*\)/\1.$DM/g" -e "s/@/$DM/"` )
A=( `printf "%s\n" "${A[@]}" | sort -u` )
#IP
for n in "${A[@]}"; do
  echo "+ A: $n"
  IFS=$'\t' read id co <<<$(echo "$cfr" | jq '.[] | select(.name == "'$n'")' | jq -s . | jq -r '.[] | [.id, .content] | @tsv')
  if [ "$co" == "$IP" ]; then echo "  $zc"
  else
    [ -z "$id" ] && mt='POST' || mt='PATCH'
    m=$(curl -s -S $hdr -X $mt "${BU}/$id" -d '{"type":"A", "name":"'$n'", "content":"'$IP'", "ttl":3600, "proxied":false}' | jq -r '.errors[].message')
    [ -z "$m" ] && echo "  -► $mt: success" || echo "  -► $mt: $m"
  fi
done

Comments Off on cfip.sh v.20210408

Filed under Software

Comments are closed.