summaryrefslogtreecommitdiff
path: root/dns.sh
diff options
context:
space:
mode:
Diffstat (limited to 'dns.sh')
-rwxr-xr-xdns.sh167
1 files changed, 167 insertions, 0 deletions
diff --git a/dns.sh b/dns.sh
new file mode 100755
index 0000000..210ff7f
--- /dev/null
+++ b/dns.sh
@@ -0,0 +1,167 @@
+API_TOKEN="${API_TOKEN:-ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcd}"
+ZONE="${ZONE:-example.com}"
+DOMAIN="${DOMAIN:-example.com}"
+
+EVENT() {
+ printf "\x1b[95m>>> \x1b[0m\x1b[98m$1\n"
+}
+
+LOG() {
+ printf "\x1b[98m$1\n"
+}
+
+ERROR() {
+ >&2 printf "\x1b[91mError: \x1b[0m\x1b[98m$1\n"
+}
+
+CURL() {
+ RESPONSE=$(curl --silent --request $1 \
+ --url "https://api.cloudflare.com/client/v4$2" \
+ --header "Content-Type: application/json" \
+ --header "Authorization: Bearer $API_TOKEN" \
+ --data "$3")
+ SUCCESS=$(echo $RESPONSE | jq -r ".success")
+ if [ "$SUCCESS" != "true" ]; then
+ ERROR "$(echo $RESPONSE | jq -r ".errors[0].message")"
+ kill $$
+ fi
+
+ echo $RESPONSE | jq ".result"
+}
+
+PATCH() {
+ CURL "PATCH" "$1" "$2"
+}
+
+POST() {
+ CURL "POST" "$1" "$2"
+}
+
+GET() {
+ CURL "GET" "$1" ""
+}
+
+EVENT "Getting Zones"
+ZONES=$(GET "/zones")
+ZONE_ID="null"
+
+i=0
+while true; do
+
+ ZONE_JSON=$(echo $ZONES | jq ".[$i]")
+
+ if [ "$ZONE_JSON" == "null" ]; then
+ break
+ fi
+
+ NAME=$(echo $ZONE_JSON | jq -r ".name")
+ ID=$(echo $ZONE_JSON | jq -r ".id")
+
+ LOG "Found Zone $NAME ($ID)"
+
+ if [ "$NAME" == "$ZONE" ]; then
+ ZONE_ID=$ID
+ break
+ fi
+
+ ((i=i+1))
+
+done
+
+if [ "$ZONE_ID" == "null" ]; then
+ ERROR "Could not find zone $DOMAIN"
+ exit 1
+fi
+
+EVENT "Getting Records"
+
+RECORDS=$(GET "/zones/$ZONE_ID/dns_records")
+
+IPv4Current="null"
+IPv6Current="null"
+IPv4Id="null"
+IPv6Id="null"
+
+i=0
+while true; do
+
+ RECORD=$(echo $RECORDS | jq ".[$i]")
+
+ if [ "$RECORD" == "null" ]; then
+ break
+ fi
+
+ NAME=$(echo $RECORD | jq -r '.name')
+ TYPE=$(echo $RECORD | jq -r '.type')
+ CONTENT=$(echo $RECORD | jq -r '.content')
+ ID=$(echo $RECORD | jq -r '.id')
+
+ LOG "Found record $NAME $TYPE \"$CONTENT\" ($ID)"
+
+ if [ "$NAME" == "$DOMAIN" ] && [ "$TYPE" == "A" ]; then
+ IPv4Current="$CONTENT"
+ IPv4Id="$ID"
+ fi
+
+ if [ "$NAME" == "$DOMAIN" ] && [ "$TYPE" == "AAAA" ]; then
+ IPv6Current="$CONTENT"
+ IPv6Id="$ID"
+ fi
+
+ ((i=i+1))
+
+done
+
+EVENT "Getting current IPs"
+
+IPv4New=$(curl ip.me -4sL --silent)
+LOG "Using IPv4 $IPv4New"
+
+IPv6New=$(curl ip.me -6sL --silent)
+LOG "Using IPv6 $IPv6New"
+
+UPDATE() {
+ PATCH "/zones/$ZONE_ID/dns_records/$1" "$2" > /dev/null
+}
+
+CREATE() {
+ POST "/zones/$ZONE_ID/dns_records" "$1" > /dev/null
+}
+
+IPv4JSON="{
+ \"content\": \"$IPv4New\",
+ \"name\": \"$DOMAIN\",
+ \"proxied\": false,
+ \"type\": \"A\"
+}"
+
+IPv6JSON="{
+ \"content\": \"$IPv6New\",
+ \"name\": \"$DOMAIN\",
+ \"proxied\": false,
+ \"type\": \"AAAA\"
+}"
+
+EVENT "Updating Records"
+
+if [ "$IPv4Id" == "null" ]; then
+ LOG "No IPv4 record found... creating new one"
+ CREATE "$IPv4JSON"
+elif [ "$IPv4Current" != "$IPv4New" ]; then
+ LOG "IPv4 record found... updating"
+ UPDATE "$IPv4Id" "$IPv4JSON"
+else
+ LOG "IPv4 is up to date... skipping"
+fi
+
+if [ "$IPv6Id" == "null" ]; then
+ LOG "No IPv6 record found... creating new one"
+ CREATE "$IPv6JSON"
+elif [ "$IPv6Current" != "$IPv6New" ]; then
+ LOG "IPv6 record found... updating"
+ UPDATE "$IPv6Id" "$IPv6JSON"
+else
+ LOG "IPv6 is up to date... skipping"
+fi
+
+EVENT "Successfully updated records"