#!/bin/sh # Declarative-ish config for Technitium: ensures the AD conditional # forwarder zones exist. Zones that already exist are NOT touched, so # manual tweaks in the web console survive re-runs. To re-apply a zone # from here, delete it in the console and re-run: # docker compose up technitium-init set -eu API="http://127.0.0.1:5380/api" : "${TECHNITIUM_ADMIN_PASSWORD:?set in .env}" : "${TROCH_DC1_IP:?set in .env}" : "${TROCH_DC2_IP:?set in .env}" : "${OSWALD_DC_IP:?set in .env}" echo "Waiting for the Technitium API..." i=0 until curl -sf -o /dev/null "$API/user/login" 2>/dev/null; do i=$((i + 1)) [ "$i" -le 60 ] || { echo "ERROR: API not up after 120s" >&2; exit 1; } sleep 2 done TOKEN=$(curl -sf -G "$API/user/login" \ --data-urlencode "user=admin" \ --data-urlencode "pass=$TECHNITIUM_ADMIN_PASSWORD" | jq -r '.token // empty') [ -n "$TOKEN" ] || { echo "ERROR: login failed — check TECHNITIUM_ADMIN_PASSWORD" >&2; exit 1; } AUTH="Authorization: Bearer $TOKEN" ZONES_JSON=$(curl -sf -H "$AUTH" "$API/zones/list?pageNumber=1&zonesPerPage=200") zone_exists() { echo "$ZONES_JSON" | jq -e --arg z "$1" \ '.response.zones[]? | select(.name == $z)' >/dev/null } api_ok() { jq -e '.status == "ok"' >/dev/null; } # ensure_fwd_zone [more forwarders...] ensure_fwd_zone() { zone=$1; shift if zone_exists "$zone"; then echo "zone $zone already exists — leaving as-is" return 0 fi first=$1; shift echo "creating conditional forwarder zone $zone -> $first" curl -sf -H "$AUTH" -G "$API/zones/create" \ --data-urlencode "zone=$zone" \ --data-urlencode "type=Forwarder" \ --data-urlencode "initializeForwarder=true" \ --data-urlencode "protocol=Udp" \ --data-urlencode "forwarder=$first" \ --data-urlencode "dnssecValidation=false" | api_ok for extra in "$@"; do echo " adding forwarder $extra to $zone" curl -sf -H "$AUTH" -G "$API/zones/records/add" \ --data-urlencode "domain=$zone" \ --data-urlencode "zone=$zone" \ --data-urlencode "type=FWD" \ --data-urlencode "protocol=Udp" \ --data-urlencode "forwarder=$extra" \ --data-urlencode "dnssecValidation=false" | api_ok done } # AD forward zones -> DCs over the WireGuard tunnel. # ad.atlashorizon.net also covers _msdcs.ad.atlashorizon.net. ensure_fwd_zone ad.atlashorizon.net "$TROCH_DC1_IP" "$TROCH_DC2_IP" ensure_fwd_zone ad.calliecorner.net "$TROCH_DC1_IP" "$TROCH_DC2_IP" ensure_fwd_zone ad.trochalakis.net "$TROCH_DC1_IP" "$TROCH_DC2_IP" # Append "$TROCH_DC1_IP" "$TROCH_DC2_IP" here ONLY if this zone replicates # forest-wide (ForestDnsZones) to the root DCs: ensure_fwd_zone ad.oswaldtheotter.net "$OSWALD_DC_IP" # Reverse zones so PTR lookups for site hosts work ensure_fwd_zone 20.168.192.in-addr.arpa "$TROCH_DC1_IP" "$TROCH_DC2_IP" ensure_fwd_zone 7.168.192.in-addr.arpa "$OSWALD_DC_IP" echo "Technitium AD forwarder zones OK."