Files
racknerd/technitium/configure.sh
T
2026-07-16 00:54:33 -07:00

100 lines
3.4 KiB
Bash

#!/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 <zone> <forwarder> [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"
# Primary zones for VPN client registration (openvpn learn-address hook
# writes <username>.$VPN_DNS_ZONE A records + PTRs for 172.31.8.0/24)
ensure_primary_zone() {
zone=$1
if zone_exists "$zone"; then
echo "zone $zone already exists — leaving as-is"
return 0
fi
echo "creating primary zone $zone"
curl -sf -H "$AUTH" -G "$API/zones/create" \
--data-urlencode "zone=$zone" \
--data-urlencode "type=Primary" | api_ok
}
if [ -n "${VPN_DNS_ZONE:-}" ]; then
ensure_primary_zone "$VPN_DNS_ZONE"
ensure_primary_zone "8.31.172.in-addr.arpa"
fi
echo "Technitium AD forwarder zones OK."