Files
jitty-scripts/dns-rescue.sh
Mollusk b13b9f7fc5 New Script: dns-rescue.sh
Interactive recovery tool for the AdGuard-Home-only DNS setup.
Useful when AGH fails to start at boot and systemd-resolved is masked.
2026-05-11 04:55:56 -04:00

115 lines
3.3 KiB
Bash
Executable File

#!/bin/bash
# dns-rescue.sh — emergency DNS recovery on a machine where AdGuard Home is the
# sole local resolver (systemd-resolved is masked). If AGH fails to start, this
# machine has no DNS until you intervene. Run this script from a TTY login.
#
# Author: Justin Moore
# Version: 0.1.0
set -u
RESOLV=/etc/resolv.conf
FALLBACK=1.1.1.1
require_root() {
if [[ $EUID -ne 0 ]]; then
echo "Re-running with sudo..."
exec sudo -E "$0" "$@"
fi
}
show_status() {
echo "=== /etc/resolv.conf ==="
cat "$RESOLV" 2>/dev/null || echo "(missing!)"
echo
echo "=== AdGuard Home service ==="
systemctl is-active adguardhome 2>&1 | head -1
systemctl is-enabled adguardhome 2>&1 | head -1
echo
echo "=== Last 15 AGH log lines (this boot) ==="
journalctl -u adguardhome -b --no-pager -n 15 2>&1 | tail -15
echo
echo "=== Port 53 listeners ==="
ss -lntu 2>/dev/null | awk '/:53 /{print}' | head -5
echo
echo "=== Masked resolved units ==="
systemctl is-enabled systemd-resolved.service systemd-resolved-varlink.socket systemd-resolved-monitor.socket 2>&1 | paste -d' ' - - - -
}
add_fallback_dns() {
if grep -q "nameserver $FALLBACK" "$RESOLV" 2>/dev/null; then
echo "$FALLBACK is already in $RESOLV — nothing to do."
return
fi
echo "nameserver $FALLBACK" >> "$RESOLV"
echo "Added fallback nameserver $FALLBACK to $RESOLV."
echo "Test:"
getent hosts archlinux.org && echo " DNS now resolves."
}
restart_agh() {
systemctl restart adguardhome
sleep 1
systemctl is-active adguardhome
journalctl -u adguardhome -b --no-pager -n 10 | tail -10
}
unmask_resolved() {
cat <<MSG
This rolls back the local-DNS setup partway:
- unmasks systemd-resolved + its varlink/monitor sockets
- starts systemd-resolved (will bind 127.0.0.53:53)
- does NOT change /etc/resolv.conf, NetworkManager dropin, or nsswitch.conf
Use this if AGH itself is broken and you want resolved back as a stopgap.
You will still need to point /etc/resolv.conf at 127.0.0.53 (or let NM regenerate it)
to actually use resolved.
MSG
read -rp "Proceed? [y/N] " ans
[[ "$ans" =~ ^[Yy]$ ]] || { echo "Cancelled."; return; }
systemctl unmask systemd-resolved.service systemd-resolved-varlink.socket systemd-resolved-monitor.socket
systemctl start systemd-resolved
systemctl status systemd-resolved --no-pager -n 5
}
menu() {
cat <<MENU
DNS rescue menu:
1) Show DNS status (resolv.conf, AGH state, log, port 53)
2) Add $FALLBACK as a temporary fallback nameserver
3) Restart AdGuard Home and tail its log
4) Unmask + start systemd-resolved (heavier rollback)
5) Open editor on /etc/resolv.conf
q) Quit
MENU
read -rp "> " choice
case "$choice" in
1) show_status ;;
2) add_fallback_dns ;;
3) restart_agh ;;
4) unmask_resolved ;;
5) "${EDITOR:-vi}" "$RESOLV" ;;
q|Q) exit 0 ;;
*) echo "Unknown choice." ;;
esac
}
require_root "$@"
if [[ $# -gt 0 ]]; then
case "$1" in
status) show_status ;;
fallback) add_fallback_dns ;;
restart) restart_agh ;;
unmask) unmask_resolved ;;
*) echo "Usage: $0 [status|fallback|restart|unmask] (no arg = interactive menu)"; exit 2 ;;
esac
exit 0
fi
show_status
while true; do menu; done