Last active
October 24, 2025 16:47
-
-
Save ergolyam/6ea69a7b6c64e7e725b299243a771e1c to your computer and use it in GitHub Desktop.
This custom updater integrates OpenWrt’s `ddns-scripts` with Spaceship.dev DNS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| API_KEY="$api_key" | |
| API_SECRET="$api_secret" | |
| FQDN="$domain" | |
| ADDR="$__IP" | |
| TTL=3600 | |
| WAIT="${param_wait:-8}" | |
| DNS="${dns_server:-1.1.1.1}" | |
| RECORDS="${param_records:-@}" | |
| REC_LIST="$(printf '%s' "$RECORDS" | tr ',' ' ')" | |
| BASE="https://spaceship.dev/api/v1/dns/records/$FQDN" | |
| CURL_BASE_OPTS="-sS --fail --connect-timeout 5 -m 20 --retry 3 --retry-delay 2 --retry-all-errors" | |
| HDRS="-H X-Api-Key:$API_KEY -H X-Api-Secret:$API_SECRET" | |
| i="$WAIT" | |
| while [ "$i" -gt 0 ]; do | |
| ip route get 1.1.1.1 >/dev/null 2>&1 || { sleep 1; i=$((i-1)); continue; } | |
| nslookup spaceship.dev "$DNS" >/dev/null 2>&1 || { sleep 1; i=$((i-1)); continue; } | |
| break | |
| done | |
| CURRENT_JSON="$(curl $CURL_BASE_OPTS -G "$BASE" \ | |
| -d take=500 -d skip=0 -d orderBy=name $HDRS)" || exit 1 | |
| DEL_ITEMS="" | |
| PUT_ITEMS="" | |
| for name in $REC_LIST; do | |
| [ -n "$name" ] || continue | |
| OLD_IPS="$(printf '%s' "$CURRENT_JSON" \ | |
| | jsonfilter -e "@.items[@.type=\"A\" && @.name=\"$name\"].address" 2>/dev/null)" | |
| has_match=0 | |
| for ip in $OLD_IPS; do | |
| [ -n "$ip" ] || continue | |
| if [ "$ip" != "$ADDR" ]; then | |
| if [ -z "$DEL_ITEMS" ]; then | |
| DEL_ITEMS=$(printf '{"type":"A","name":"%s","address":"%s"}' "$name" "$ip") | |
| else | |
| DEL_ITEMS=$(printf '%s,{"type":"A","name":"%s","address":"%s"}' "$DEL_ITEMS" "$name" "$ip") | |
| fi | |
| else | |
| has_match=1 | |
| fi | |
| done | |
| if [ "$has_match" -eq 0 ]; then | |
| if [ -z "$PUT_ITEMS" ]; then | |
| PUT_ITEMS=$(printf '{"type":"A","name":"%s","address":"%s","ttl":%s}' "$name" "$ADDR" "$TTL") | |
| else | |
| PUT_ITEMS=$(printf '%s,{"type":"A","name":"%s","address":"%s","ttl":%s}' "$PUT_ITEMS" "$name" "$ADDR" "$TTL") | |
| fi | |
| fi | |
| done | |
| [ -n "$DEL_ITEMS" ] && DEL_ITEMS="[$DEL_ITEMS]" | |
| if [ -n "$DEL_ITEMS" ]; then | |
| curl $CURL_BASE_OPTS -X DELETE "$BASE" $HDRS \ | |
| -H "Content-Type: application/json" \ | |
| --data "$DEL_ITEMS" \ | |
| -o /dev/null || exit 1 | |
| fi | |
| if [ -n "$PUT_ITEMS" ]; then | |
| PUT_BODY=$(printf '{"force":false,"items":[%s]}' "$PUT_ITEMS") | |
| curl $CURL_BASE_OPTS -X PUT "$BASE" $HDRS \ | |
| -H "Content-Type: application/json" \ | |
| --data "$PUT_BODY" \ | |
| -o /dev/null || exit 1 | |
| fi | |
| exit $? |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Deploying
update_spaceship.shon OpenWrt (DDNS)This custom updater integrates OpenWrt’s
ddns-scriptswith Spaceship.dev DNS.On each run, it ensures the specified A records point to the router’s current public IPv4 and removes stale A records for those names.
OpenWrt 19.07+ (tested with recent releases).
Packages:
ddns-scripts(andddns-scripts-regularon some versions)curljsonfilterInstall:
Save the script as
/usr/lib/ddns/update_spaceship.shand make it executable:What the script does:
api_key,api_secret), domain (domain), the current WAN IP (__IP), and the list of records (param_records) from the DDNS environment.TTL=3600./etc/config/ddnsand add a service (replace placeholders with your values):param_recordsis a comma-separated list of hostnames underdomain. Use@for the root record.upd_privateipis0. Consider switching ISPs or using a tunnel if you need a public IPv4.lookup_hostis what ddns-scripts resolves to decide if an update is needed (usually the root or one of your records).Enable and start the DDNS service
/etc/init.d/ddns enable /etc/init.d/ddns restartcheck_intervalyou set (10 minutes above).Verify
Check logs:
Confirm DNS records match your current public IPv4:
# Should show your WAN public IP nslookup example.com 1.1.1.1 nslookup www.example.com 1.1.1.1