Skip to content

Instantly share code, notes, and snippets.

@vilhelmen
Last active February 10, 2018 04:19
Show Gist options
  • Save vilhelmen/a14efe9a35946dffe5bbee49ae5f355f to your computer and use it in GitHub Desktop.
Save vilhelmen/a14efe9a35946dffe5bbee49ae5f355f to your computer and use it in GitHub Desktop.
DDWRT caching Cloudflare DNS updater script without jffs
#!/bin/sh
# This assumes we are the only one who updates this record
# Doesn't need jffs to work.
# Base64 encode (use 64-char breaks) this and load into startup script
# Decode with openssl (busybox is missing uudecode???) to the filesystem and chmod +x
# Add script target location to cron
ZONE_ID='WWWWW'
API_KEY='XXXXX'
DOMAIN='YYYYY'
EMAIL='ZZZZZ'
CERT_FILE='/tmp/comodo_cert.pem'
IP_FILE='/tmp/cloudflare_ip'
ID_FILE='/tmp/cloudflare_id'
if [ ! -s "${CERT_FILE}" ]; then
# DD-WRT stopped shipping CA bundles >:C
# Comodo cert for the cloudflare API
# TODO: Update in 2038
echo '-----BEGIN CERTIFICATE-----
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
-----END CERTIFICATE-----
' > "${CERT_FILE}"
fi
if [ ! -s "${IP_FILE}" ]; then
RESPONSE=$(curl --cacert "${CERT_FILE}" \
-X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?type=A&name=${DOMAIN}&match=all" \
-H "X-Auth-Email: ${EMAIL}" \
-H "X-Auth-Key: ${API_KEY}" \
-H "Content-Type: application/json")
# Or, just dump response and parse on run instead of two files
# Putting both in one file and parsing is NOT worth the effort
echo "${RESPONSE}" | sed -rne 's/.*"content":"([0-9\.]+)".*/\1/p' > "${IP_FILE}"
echo "${RESPONSE}" | sed -rne 's/.*"id":"([a-fA-F0-9]+)".*/\1/p' > "${ID_FILE}"
fi
if [ -s "${IP_FILE}" ]; then
# we got something back that is probably right
RECORD_IP=$(cat "${IP_FILE}")
RECORD_ID=$(cat "${ID_FILE}")
else
return 1
fi
CURRENT_IP=$(nvram get wan_ipaddr)
# 0.0.0.0 when unknown/released
# 192.168.100.* when mediacom is being an ass >:C
if [ "${CURRENT_IP}" != "${RECORD_IP}" ] && [ "${CURRENT_IP}" != "0.0.0.0" ] && [ "${CURRENT_IP}" == "${CURRENT_IP#192.168.100.}" ]; then
# Need to update record
RESPONSE=$(curl --cacert "${CERT_FILE}" \
-X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
-H "X-Auth-Email: ${EMAIL}" \
-H "X-Auth-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"${DOMAIN}\",\"content\":\"${CURRENT_IP}\",\"ttl\":1,\"proxied\":false}")
RESULT=$(echo "${RESPONSE}" | sed -rne 's/.*"success":([truefals]+),.*/\1/p')
if [ "${RESULT}" != "true" ]; then
logger "ZONE UPDATE: IP UPDATE NEDED AND FAILED >:C"
return 2
fi
echo "${CURRENT_IP}" > "${IP_FILE}"
logger "ZONE UPDATE: ${RECORD_IP} -> ${CURRENT_IP}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment