Cloudflare DDNS 업데이트 방법(feat. shell script)

IT 등/리눅스 관련 2022. 11. 12. 15:52

거의 10년동안 DNSEVER를 써 오다가, http 인증서를 domain 인증 방식으로 받으려고 Cloudflare 로 옮겼다.
그때 딱 드는 생각이, 이렇게 기능이 좋은 클라우드플레어도 프리 플랜이 있는데, DNSEVER는 무슨 생각으로 DNS 쿼리당 돈을 받지? 였다. 사실 DNSEVER의 요금제가 비싼건 아니지만 재수없이 bot에 걸리면 유료과금되는 경우가 있었다.

그런데 클라우드 플레어로 옮기니 DNS 조작을 앱으로도 할 수 있고, TTL 변경도 엄청 쉽다.

뭐랄까, DNS를 변경하면 늘 허들이었던게, 변경사항이 반영되는걸 기다리는 것이었는데, 클라우드플레어 DNS는 변경사항이 생기면 바로바로 반영된다는 느낌이 든다.

단 하나 귀찮은게, Proxy가 디폴트로 적용된다는 건데, DNS를 조작해서 가지고 노는 사람의 입장에서는 참 불편하다. 왜냐, 웹브라우저에서 REDIRECTION 이 너무 많다는 오류를 불러오기도 하고, DNS가 클라우드 플레어를 가리키고 있으니 디버그가 안된다.

까짓거, 대형서비스도 아닌데, DNSOnly로 쓰지 뭐.
일단 VM들의 전체 레코드를 옮겼는데 그것들은 평범하니 상관없다. IP가 변하지 않을테니까.

집에서 운영하는 것들이 문제다. 집에 할당하는 IP는 이사를 가거나 통신사를 바꾸지 않는한 몇년동안 변동되지 않았다. 그래도 모르니 DDNS를 설정해야 겠다.
워낙 유명한 회사라 DDNS 설정하는 방법만 해도 여러가지였다.

1. shell script를 이용하는 방법
2. docker를 이용하는 방법
3. ddns client를 이용하는 방법 등.

이전에도 shell script를 이용하는 방법을 써서, 이번에도 그리 했다.

아래 코드에서 CLOUD_FLARE_LOGIN_EMAIL, CLOUD_FLARE_TOKEN 을 바꿔주고 Doamin, A_Record 값을 원하는 것으로 바꿔주면 된다.

인터넷에서 주워온 소스에서는 Proxied=true 였다. 그러나 하루 후 DNS 레코드가 날아가는 것을 겪은 후 Proxied=false 로 바꿨다.

그런데, 이 사항을 발견하기 전에 수동으로 Proxied를 꺼줬는데, 저 스크립트로 true로 변하지는 않았다.

#!/bin/bash

### CloudFlare A Recoard Updater
### A_Record : Separate the contents with commas (,)
### Proxied : true or false
### TTL : Between 120 and 2147483647 seconds, or 1 for automatic
### To force updating, run with -f

Login_Email=CLOUD_FLARE_LOGIN_EMAIL
Global_API_Key=CLOUD_FLARE_TOKEN
Domain=inbox.kr
A_Record=ras.inbox.kr
Proxied=false
TTL=1

[ ! -f /var/tmp/ip.txt ] && touch /var/tmp/ip.txt
CIP=$(curl -s "https://ipv4.icanhazip.com/")
PIP=$(cat /var/tmp/ip.txt)
echo -e "CloudFlare A Recoard Updater v1.0.9"
echo -e "Current IP: $CIP"
echo -e "Previous IP: $PIP"

if [ "$CIP" == "$PIP" ] && [[ $1 != "-f" ]]; then
  echo "No need to update"; exit 0
elif [[ $1 == "-f" ]]; then
  echo "Force updating A recoard......"
elif [ "$CIP" != "$PIP" ]; then
  echo "Updating A recoard......"
fi

echo $CIP > /var/tmp/ip.txt

V4="https://api.cloudflare.com/client/v4/zones"
H1="-HX-Auth-Email:$Login_Email"
H2="-HX-Auth-Key:$Global_API_Key"
H3="-HContent-Type:application/json"
ZN=$(curl -s -X GET "$V4?name=$Domain" \
    $H1 $H2 $H3 | grep -Po '(?<="id":")[^"]*' | head -1)

string=$A_Record
IFS=',' ARARY=(${string})

function AID() {
  for AREC in "${ARARY[@]}"
    do
      (curl -s -X GET "$V4/$ZN/dns_records?name=$AREC" \
      $H1 $H2 $H3 | grep -Po '(?<="id":")[^"]*' | head -1)
    done
}

IFS=$'\n' AIDARY=($(AID))

ATOTAL=${#ARARY[*]}

for ((i=0; i<$ATOTAL; i++))
  do
    (curl -s -X PUT "$V4/$ZN/dns_records/${AIDARY[$i]}" $H1 $H2 $H3 \
    --data "{\"type\":\"A\",\"name\":\"${ARARY[$i]}\",\"content\":\"$CIP\",\"proxied\":$Proxied,\"ttl\":$TTL}" \
    | grep -Po '(?<="name":")[^"]*|(?<="content":")[^"]*|(?<=Z"},)[^}]*|(?<="success":false,)[^$]*|(?<=\s\s)[^$]*' | xargs)
  done

주기적으로 갱신하는 것의 등록은 Crontab을 응용하면 되는데, DNSEVER는 하루에 한번만 해도 아무 이상이 없었는데, 클라우드 플레어는 24시간 주기로 했더니 다음날 해당 서브도메인 데이터가 날아가버렸다. 아마 TTL이 극히 짧은가보다.

인터넷을 검색해보니 1시간이네.

일단 갱신 주기를 5분으로 세팅하니 아직까지는 이상이 없다. 웬지 인터넷에 ddns 클라이언트 세팅에 5분 주기로 설정하는 설명이 있더라니...

암튼, cloudflare DNS 문제가 생기면 대부분 Proxy 설정을 풀어주면 해결된다.

설정

트랙백

댓글