00a95fda80
Registers {hostname}.home.dustin.coffee → host IP on boot via AdGuard Home API.
Deploy to any LXC/VM with ./install.sh — supports root (system service),
sudo user (system via sudo), and unprivileged user (systemd --user or crontab).
Files:
- adguard-register.sh — detects hostname+IP, idempotent create/update
- install.sh — deployment script with auto-detection of install method
- uninstall.sh — removes service and binary
- README.md — full documentation
Tested across 24 hosts (LXCs and VMs) on a 172.20.0.0/16 home lab network.
89 lines
2.7 KiB
Bash
Executable File
89 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# adguard-register — registers this host with AdGuard Home DNS rewrites
|
|
# Deploy to each LXC/VM, run at boot via systemd oneshot or @reboot cron
|
|
|
|
set -euo pipefail
|
|
|
|
ADGUARD_URL="http://172.20.1.1"
|
|
USERNAME="newkirk"
|
|
PASSWORD="Vaxjy911!"
|
|
# Get short hostname (portable: try hostname -s, fall back to /etc/hostname or /proc)
|
|
if command -v hostname &>/dev/null; then
|
|
HOSTNAME=$(hostname -s)
|
|
elif [ -f /etc/hostname ]; then
|
|
HOSTNAME=$(cat /etc/hostname | cut -d. -f1)
|
|
else
|
|
HOSTNAME=$(cat /proc/sys/kernel/hostname 2>/dev/null | cut -d. -f1)
|
|
fi
|
|
|
|
# Get primary IPv4 (non-loopback, non-docker, non-tailscale)
|
|
IP=$(ip -4 addr show scope global | grep -v 'docker\|tailscale\|br-\|veth' | grep -oP 'inet \K[\d.]+' | head -1)
|
|
|
|
if [ -z "$IP" ]; then
|
|
echo "ERROR: Could not determine primary IPv4 address"
|
|
exit 1
|
|
fi
|
|
|
|
DOMAIN="${HOSTNAME}.home.dustin.coffee"
|
|
|
|
# Login
|
|
COOKIE=$(curl -s -D - "${ADGUARD_URL}/control/login" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"name\":\"${USERNAME}\",\"password\":\"${PASSWORD}\"}" \
|
|
| grep -i 'set-cookie' | grep -oP 'agh_session=[a-f0-9]+' | head -1)
|
|
|
|
if [ -z "$COOKIE" ]; then
|
|
echo "ERROR: Failed to authenticate with AdGuard Home"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if rewrite already exists
|
|
EXISTING=$(curl -s "${ADGUARD_URL}/control/rewrite/list" -b "$COOKIE")
|
|
EXISTING_ANSWER=$(echo "$EXISTING" | python3 -c "
|
|
import sys,json
|
|
data=json.load(sys.stdin)
|
|
for r in data:
|
|
if r.get('domain') == '$DOMAIN':
|
|
print(r.get('answer',''))
|
|
break
|
|
" 2>/dev/null)
|
|
|
|
if [ -n "$EXISTING_ANSWER" ]; then
|
|
if [ "$EXISTING_ANSWER" = "$IP" ]; then
|
|
echo "OK: $DOMAIN already points to $IP — nothing to do"
|
|
exit 0
|
|
fi
|
|
# Update existing
|
|
echo "Updating $DOMAIN: $EXISTING_ANSWER → $IP"
|
|
curl -s -X POST "${ADGUARD_URL}/control/rewrite/update" \
|
|
-b "$COOKIE" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"target\":{\"domain\":\"$DOMAIN\"},\"update\":{\"domain\":\"$DOMAIN\",\"answer\":\"$IP\"}}" \
|
|
> /dev/null
|
|
else
|
|
# Create new
|
|
echo "Registering $DOMAIN → $IP"
|
|
curl -s -X POST "${ADGUARD_URL}/control/rewrite/add" \
|
|
-b "$COOKIE" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"domain\":\"$DOMAIN\",\"answer\":\"$IP\"}" \
|
|
> /dev/null
|
|
fi
|
|
|
|
# Verify
|
|
VERIFY=$(curl -s "${ADGUARD_URL}/control/rewrite/list" -b "$COOKIE" | python3 -c "
|
|
import sys,json
|
|
data=json.load(sys.stdin)
|
|
for r in data:
|
|
if r.get('domain') == '$DOMAIN':
|
|
print(r.get('answer',''))
|
|
" 2>/dev/null)
|
|
|
|
if [ "$VERIFY" = "$IP" ]; then
|
|
echo "SUCCESS: $DOMAIN → $IP verified"
|
|
exit 0
|
|
else
|
|
echo "WARN: Verification failed — $DOMAIN resolves to '$VERIFY', expected '$IP'"
|
|
exit 1
|
|
fi
|