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