Skip to content

Instantly share code, notes, and snippets.

@SunRed
Last active June 3, 2026 13:20
Show Gist options
  • Select an option

  • Save SunRed/07619d854c5e6bd33db565fa14a842e2 to your computer and use it in GitHub Desktop.

Select an option

Save SunRed/07619d854c5e6bd33db565fa14a842e2 to your computer and use it in GitHub Desktop.
Script to update an ipv4/ipv6 dns record with your ip at hosting.de using their api for a free dynamic dns solution instead of paying for their service
#!/usr/bin/env bash
set -euo pipefail
readonly APIKEY='$$YOUR API KEY$$'
readonly ENDPOINT='https://secure.hosting.de'
readonly ZONE='$$YOUR DOMAIN$$'
readonly RECORD='$$YOUR SUBDOMAIN$$'
# Record IDs for some reason required even though documentation says optional if name is given
readonly IPV4ID='asd1'
readonly IPV6ID='asd2'
_contains() {
local str="$1"
local sub="$2"
echo "$str" | grep -- "$sub" >/dev/null 2>&1
}
_post() {
local body="$1"
local post_url="$2"
local httpmethod="${3:-}"
local postContentType="${4:-}"
if [ -z "$httpmethod" ]; then
httpmethod="POST"
fi
if [ -z "$postContentType" ]; then
postContentType="application/json"
fi
local response=$(curl -sS -X $httpmethod -H "Content-Type: $postContentType" --data "$body" "$post_url")
local ret="$?"
printf "%s" "$response"
return $ret
}
cachedir="${XDG_CACHE_HOME:-$HOME/.cache}/ddns-update"
mkdir -p "${cachedir}"
cached_ipv4_file="${cachedir}/ipv4"
cached_ipv6_file="${cachedir}/ipv6"
[[ -f "$cached_ipv4_file" ]] && cached_ipv4="$(<$cached_ipv4_file)" || cached_ipv4=""
[[ -f "$cached_ipv6_file" ]] && cached_ipv6="$(<$cached_ipv6_file)" || cached_ipv6=""
current_ipv4=$(dig +short +tls -4 +timeout=5 +tries=1 @dns.opendns.com A myip.opendns.com)
current_ipv6=$(dig +short +tls -6 +timeout=5 +tries=1 @dns.opendns.com AAAA myip.opendns.com)
declare -a records
update=false
if [ "$cached_ipv4" != "$current_ipv4" ]; then
echo "Updating ipv4 record..."
echo "$current_ipv4" > "$cached_ipv4_file"
records+=("{\"id\":\"${IPV4ID}\",\"name\":\"${RECORD}\",\"type\":\"A\",\"content\":\"${current_ipv4}\",\"comments\":\"DDNS Last Modified: $(date +"%Y-%m-%dT%H:%M:%S%z")\",\"ttl\":60}")
update=true
fi
if [ "$cached_ipv6" != "$current_ipv6" ]; then
echo "Updating ipv6 record..."
echo "$current_ipv6" > "$cached_ipv6_file"
records+=("{\"id\":\"${IPV6ID}\",\"name\":\"${RECORD}\",\"type\":\"AAAA\",\"content\":\"${current_ipv6}\",\"comments\":\"DDNS Last Modified: $(date +"%Y-%m-%dT%H:%M:%S%z")\",\"ttl\":60}")
update=true
fi
if [ $update = true ]; then
records_list=$(printf "%s," "${records[@]}" | sed 's/,$//')
data="{\"authToken\":\"${APIKEY}\",\"zoneName\":\"${ZONE}\",\"recordsToModify\":[${records_list}]}"
result=$(_post "${data}" "${ENDPOINT}/api/dns/v1/json/recordsUpdate")
if _contains "$result" '"status": "error"'; then
if _contains "$result" '"code": 10109'; then
echo "The API-Key is invalid or could not be found"
exit 2
else
echo "UNKNOWN API ERROR"
exit 3
fi
exit 1
fi
echo "Updated"
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment