Cloudflare API: Using OpenBSD base only

February 11, 2025 #dns #openbsd #shell

Comming soon…

#!/bin/sh

# Cloudflare vars
CF_API_HOST="api.cloudflare.com"
CF_API_URL="/client/v4/zones"
CF_API_TOKEN=""
# DNS record vars
CF_DOMAIN="example.net"
CF_RECORD_TYPE="A"
CF_RECORD_NAME="name.example.net"
CF_RECORD_TTL="1" #1=auto
CF_RECORD_PROXIED="false"
# Interface/ip vars
interface="vlan0"
interface_ip=$(dhcpleasectl -l ${interface} | awk '/inet/ {print $2}')

# Exit 1 on empty ip address
if [[ -z ${interface_ip} ]]; then
  echo "$0: empty ipv4 address"
  exit 1
fi

# Get the Zone ID for the domain
ZONE_ID=$(echo $(nc -c ${CF_API_HOST} 443 << EOF
GET ${CF_API_URL}?name=${CF_DOMAIN} HTTP/1.1
Host: ${CF_API_HOST}
Connection: close
Authorization: Bearer ${CF_API_TOKEN}

EOF
) | awk -F'"id":"' '{split($2, a, "\""); print a[1]}')

# Check if the Zone ID was found
if [ -z "${ZONE_ID}" ]; then
  echo "Zone ID not found for ${CF_DOMAIN}"
  exit 1
fi

# Get the Record ID of the Record name and type for the domain
GET_URL=$(printf "%s/%s/dns_records?name=%s&type=%s" \
                 "${CF_API_URL}" \
                 "${ZONE_ID}" \
                 "${CF_RECORD_NAME}" \
                 "${CF_RECORD_TYPE}")
CF_RECORD_ID=$(echo $(nc -c ${CF_API_HOST} 443 << EOF
GET ${GET_URL} HTTP/1.1
Host: ${CF_API_HOST}
Connection: close
Authorization: Bearer ${CF_API_TOKEN}

EOF
) | awk -F'"id":"' '{split($2, a, "\""); print a[1]}')

# Update the record with the new ip address
echo "Sending request to Cloudflare API to update DNS record..."
UPDATE_PAYLOAD=$(printf "{\"type\":\"%s\",\"name\":\"%s\",
\"content\":\"%s\",\"ttl\":%s,\"proxied\":%s}" \
"${CF_RECORD_TYPE}" \
"${CF_RECORD_NAME}" \
"${interface_ip}" \
"${CF_RECORD_TTL}" \
"${CF_RECORD_PROXIED}")

PAYLOAD_LENGTH=$(printf "${UPDATE_PAYLOAD}" | wc -c)

CL_API_RESPONSE=$(nc -c ${CF_API_HOST} 443 << EOF
PUT ${CF_API_URL}/${ZONE_ID}/dns_records/${CF_RECORD_ID} HTTP/1.1
Host: ${CF_API_HOST}
Connection: close
Content-Length: ${PAYLOAD_LENGTH}
Content-Type: application/json
Authorization: Bearer ${CF_API_TOKEN}

${UPDATE_PAYLOAD}

EOF
)

# Check if the update was successful
SUCCESS=$(echo "${CL_API_RESPONSE}" |
  awk -F'"success":' 'BEGIN{ ORS="" } {split($2, a, ","); print a[1]}')

MODIFIED_ON=$(echo "${CL_API_RESPONSE}" | \
  awk -F'"modified_on":"' 'BEGIN{ ORS="" } {split($2, a, "\""); print a[1]}')

if [ "${SUCCESS}" = "true" ]; then
  printf "Successfully updated DNS record:\n"
  printf "Type: %s\nName: %s\nContent: %s\nModified on: %s\n" \
         "${CF_RECORD_TYPE}" "${CF_RECORD_NAME}" \
         "${interface_ip}" "${MODIFIED_ON}"
else
  echo "Error updating DNS record"
  echo "${CL_API_RESPONSE}"
  exit 1
fi