Unbound DNS API Endpoints

Started by BertFLL, June 14, 2025, 12:22:49 PM

Previous topic - Next topic
Greetings,

I am attempting to Linux shell script Unbound DNS Host Overrides as part of a larger automation configuration project. I've searched for documentation and really did not find much useful information besides the XML model. Inspecting web gui pages looking for valid endpoints, I have discovered the following:

search:  /api/unbound/settings/searchHostOverride/
get:     /api/unbound/settings/getHostOverride/
set:     /api/unbound/settings/setHostOverride/
add:     /api/unbound/settings/addHostOverride/
del:     /api/unbound/settings/delHostOverride/
toggle:  /api/unbound/settings/toggleHostOverride/
reconfigure: /api/unbound/service/reconfigure

The only three valid endpoints are searchHostOverride, addHostOverride and reconfigure. Calling any of the other endpoints produce an error {"errorMessage":"Endpoint not found"}. I can search, add and reconfigure without issues.

The following script has the dependancies of curl and jq. I've tried many variations to update a record, this being the last attempt, to delete and then recreate but to no avail. A sample script follows:

#!/bin/bash
set -euo pipefail

# ========= Configuration =========
OPNSENSE_HOST="192.168.1.1"  # e.g., 192.168.1.1
API_KEY="your_api_key"
API_SECRET="your_api_secrete"
VERIFY_TLS=false
CURL_TLS_FLAG=$([[ "$VERIFY_TLS" == "true" ]] && echo "" || echo "-k")
API_BASE="https://${OPNSENSE_HOST}/api/unbound/settings"
UNBOUND_RECONF_API="https://${OPNSENSE_HOST}/api/unbound/service/reconfigure"
CURL_AUTH="-u ${API_KEY}:${API_SECRET}"

# ========= Arguments =========
BASE_HOST="$1"             # e.g., (hostname -s)
HOST_DOMAIN="$2"           # e.g., domain.com
HOST_IP="$3"               # e.g., 192.168.100.100
DESCRIPTION="${BASE_HOST}.${HOST_DOMAIN}"

# ========= Step 1: Search for Existing Override =========
echo "[INFO] Checking for existing DNS override: ${DESCRIPTION}..."

SEARCH_RESPONSE=$(curl -sS $CURL_TLS_FLAG $CURL_AUTH "${API_BASE}/searchHostOverride")
UUID=$(echo "$SEARCH_RESPONSE" | jq -r \
  --arg host "$BASE_HOST" --arg domain "$HOST_DOMAIN" \
  '.rows[] | select(.hostname == $host and .domain == $domain) | .uuid')

# ========= Step 2: If exists, delete =========
if [[ -n "$UUID" && "$UUID" != "null" ]]; then
  echo "[INFO] Existing override found (UUID: $UUID). Deleting before re-adding..."
  DELETE_RESPONSE=$(curl -sS $CURL_TLS_FLAG $CURL_AUTH \
    -X POST "${API_BASE}/delHostOverride" \
    -H "Content-Type: application/json" \
    -d "{\"uuid\":\"$UUID\"}")
  echo -e "[DEBUG] Delete response:\n$DELETE_RESPONSE"
  sleep 1
else
  echo "[INFO] No existing override found. Creating new one for ${DESCRIPTION} -> ${HOST_IP}..."
fi

# ========= Step 3: Add new override =========
ADD_PAYLOAD=$(jq -n \
  --arg hostname "$BASE_HOST" \
  --arg domain "$HOST_DOMAIN" \
  --arg server "$HOST_IP" \
  --arg description "$DESCRIPTION" \
  '{
    host: {
      enabled: "1",
      hostname: $hostname,
      domain: $domain,
      rr: "A",
      mxprio: "",
      mx: "",
      server: $server,
      description: $description
    }
  }')

ADD_RESPONSE=$(curl -sS $CURL_TLS_FLAG $CURL_AUTH \
  -X POST "${API_BASE}/addHostOverride" \
  -H "Content-Type: application/json" \
  -d "$ADD_PAYLOAD")

echo "[DEBUG] Add response: $ADD_RESPONSE"

# ========= Step 4: Reconfigure Unbound =========
echo "[INFO] Applying DNS configuration..."
RECONF_RESPONSE=$(curl -sS $CURL_TLS_FLAG $CURL_AUTH \
  -X POST "${UNBOUND_RECONF_API}")

if echo "$RECONF_RESPONSE" | grep -qi '"status":"ok"'; then
  echo -e "[SUCCESS] DNS configuration applied.\n$RECONF_RESPONSE"
else
  echo "[WARN] Reconfigure response: $RECONF_RESPONSE"
fi

I find it hard to believe that the endpoints are nonexistent because the web gui does complete the task. Any additional insight/help is greatly appreciated.

Thanks.