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.
This commit is contained in:
114
dns-rescue.sh
Executable file
114
dns-rescue.sh
Executable file
@@ -0,0 +1,114 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user