switch-resolver-to-bind9.sh: some modifications on script output.

This commit is contained in:
2026-10-27 13:10:41 +01:00
parent bf7dca0ced
commit 7b4d0218e7
+58 -14
View File
@@ -13,10 +13,31 @@ readonly EXPECTED_NSS='hosts: files myhostname dns'
MODE="${1:---check}"
case "$MODE" in --check|--apply|--rollback|--help) ;; *) echo "Usage: $0 [--check|--apply|--rollback|--help]" >&2; exit 2;; esac
# Colorize status labels on terminals; respect NO_COLOR and redirected output.
if [[ -t 1 && ! -v NO_COLOR && "${TERM:-}" != dumb ]]; then
GREEN=$'\033[32m'
GREY=$'\033[90m'
RED=$'\033[31m'
YELLOW=$'\033[33m'
RESET=$'\033[0m'
else
GREEN='' GREY='' RED='' YELLOW='' RESET=''
fi
info() { printf '[ Info ] %s\n' "$*"; }
ok() { printf '[ ok ] %s\n' "$*"; }
skipped() { printf '[ skipped ] %s\n' "$*"; }
failed() { printf '[ failed ] %s\n' "$*" >&2; }
ok() { printf '%s[ ok ]%s %s\n' "$GREEN" "$RESET" "$*"; }
skipped() { printf '%s[ skipped ]%s %s\n' "$GREY" "$RESET" "$*"; }
failed() { printf '%s[ failed ]%s %s\n' "$RED" "$RESET" "$*" >&2; }
# Delimited summary at the end of --check / before an interactive --apply.
status_banner(){
local color="$1" message="$2" detail="${3:-}"
printf '\n%s------------------------------------------------------------%s\n' "$color" "$RESET"
printf '%s%s%s\n' "$color" "$message" "$RESET"
[[ -z "$detail" ]] || printf '%s%s%s\n' "$color" "$detail" "$RESET"
printf '%s------------------------------------------------------------%s\n' "$color" "$RESET"
}
# Every invocation finishes with one additional empty output line.
trap 'printf "\n"' EXIT
fatal() { failed "$*"; exit 1; }
echononl(){ printf '%-56s' "$*"; }
require_root(){ [[ "${EUID}" -eq 0 ]] || fatal 'Please run as root.'; }
@@ -47,14 +68,14 @@ is_fully_switched(){
# BIND must reject a known bogus signature, not merely answer normal queries.
preflight(){
echononl 'BIND9 on 127.0.0.1:53'
if dig @127.0.0.1 oopen.de A +time=3 +tries=1 +short | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then ok 'reachable'; else echo; fatal 'Local BIND9 does not resolve oopen.de'; fi
if dig @127.0.0.1 oopen.de A +time=3 +tries=1 +short | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'; then ok 'reachable'; else echo; failed 'Local BIND9 does not resolve oopen.de'; return 1; fi
echononl 'DNSSEC positive test (AD flag)'
local reply
reply=$(dig @127.0.0.1 cloudflare.com A +dnssec +adflag +time=5 +tries=1)
if grep -q 'status: NOERROR' <<< "$reply" && grep -Eq 'flags:.*[[:space:]]ad[;[:space:]]' <<< "$reply"; then ok 'validated'; else echo; fatal 'BIND9 DNSSEC positive test failed'; fi
if grep -q 'status: NOERROR' <<< "$reply" && grep -Eq 'flags:.*[[:space:]]ad[;[:space:]]' <<< "$reply"; then ok 'validated'; else echo; failed 'BIND9 DNSSEC positive test failed'; return 1; fi
echononl 'DNSSEC negative test (SERVFAIL)'
reply=$(dig @127.0.0.1 www.dnssec-failed.org A +time=5 +tries=1)
if grep -q 'status: SERVFAIL' <<< "$reply"; then ok 'rejected as expected'; else echo; fatal 'BIND9 does not reject invalid DNSSEC test zone'; fi
if grep -q 'status: SERVFAIL' <<< "$reply"; then ok 'rejected as expected'; else echo; failed 'BIND9 does not reject invalid DNSSEC test zone'; return 1; fi
}
show_check(){
@@ -66,11 +87,29 @@ show_check(){
grep -E '^hosts:' "$NSS" || true
printf 'systemd-resolved active: %s\n' "$(systemctl is-active systemd-resolved 2>/dev/null || true)"
printf 'systemd-resolved enabled: %s\n' "$(systemctl is-enabled systemd-resolved 2>/dev/null || true)"
if is_fully_switched; then ok 'Already directly using BIND9 (resolved disabled)';
elif is_direct; then info 'BIND9 direct configuration is present; resolved still active/enabled';
else info 'Not fully configured for direct BIND9'; fi
if [[ -f "$CURRENT_FILE" ]]; then info "Rollback state: $(state_dir_from_marker)"; fi
preflight
local readiness=0
if preflight; then readiness=1; fi
if is_fully_switched; then
if (( readiness )); then
status_banner "$GREY" 'Umstellung auf BIND9 bereits durchgeführt.'
else
status_banner "$YELLOW" 'Umstellung bereits durchgeführt, aber DNS-Prüfung fehlgeschlagen.'
fi
elif [[ -f "$CURRENT_FILE" ]]; then
status_banner "$YELLOW" 'Umstellung kann nicht ausgeführt werden.' \
'Ein vorheriger Rollback-Stand ist vorhanden; zunächst prüfen oder zurückbauen.'
elif (( readiness )); then
status_banner "$GREEN" 'Umstellung kann durchgeführt werden.'
else
status_banner "$YELLOW" 'Umstellung kann nicht ausgeführt werden.' \
'BIND9-/DNSSEC-Voraussetzungen nicht erfüllt; bitte Fehler prüfen.'
fi
if [[ -f "$CURRENT_FILE" ]]; then
printf '\n=== Rollback information ===\n'
info 'Backup from before the last --apply is available'
info "Backup: $(state_dir_from_marker)"
info "Restore with: $0 --rollback"
fi
}
restore_files(){
@@ -113,12 +152,17 @@ apply(){
[[ -f "$NSS" ]] || fatal "$NSS missing"
[[ -e "$RESOLV" || -L "$RESOLV" ]] || fatal "$RESOLV missing"
[[ ! -f "$CURRENT_FILE" ]] || {
if is_fully_switched; then skipped 'Already installed; no changes'; exit 0; fi
if is_fully_switched; then status_banner "$GREY" 'Umstellung auf BIND9 bereits durchgeführt.'; skipped 'No changes'; exit 0; fi
status_banner "$YELLOW" 'Umstellung kann nicht ausgeführt werden.' 'Vorheriger Rollback-Stand vorhanden.'
fatal 'An earlier script run has rollback state. Use --check or --rollback first.';
}
if is_fully_switched; then skipped 'Already directly using BIND9; no changes'; exit 0; fi
if is_fully_switched; then status_banner "$GREY" 'Umstellung auf BIND9 bereits durchgeführt.'; skipped 'No changes'; exit 0; fi
info 'Preflight checks (no changes)'
preflight
if ! preflight; then
status_banner "$YELLOW" 'Umstellung kann nicht ausgeführt werden.' 'BIND9-/DNSSEC-Voraussetzungen nicht erfüllt.'
return 1
fi
status_banner "$GREEN" 'Umstellung kann durchgeführt werden.'
printf '\nPlanned changes:\n hosts: files myhostname dns\n resolv.conf: nameserver 127.0.0.1\n stop and disable systemd-resolved\n'
info 'Network interfaces, routes, BIND9 and MTA are not changed.'
confirm || { skipped 'Abbruch durch User'; exit 0; }