fix: handle Postfix DNS resolution after switching to BIND9
This commit is contained in:
@@ -11,7 +11,7 @@ readonly NSS=/etc/nsswitch.conf
|
|||||||
readonly EXPECTED_NSS='hosts: files myhostname dns'
|
readonly EXPECTED_NSS='hosts: files myhostname dns'
|
||||||
|
|
||||||
MODE="${1:---check}"
|
MODE="${1:---check}"
|
||||||
case "$MODE" in --check|--apply|--rollback|--help) ;; *) echo "Usage: $0 [--check|--apply|--rollback|--help]" >&2; exit 2;; esac
|
case "$MODE" in --check|--apply|--rollback|--repair-postfix|--help) ;; *) echo "Usage: $0 [--check|--apply|--rollback|--repair-postfix|--help]" >&2; exit 2;; esac
|
||||||
|
|
||||||
# Colorize status labels on terminals; respect NO_COLOR and redirected output.
|
# Colorize status labels on terminals; respect NO_COLOR and redirected output.
|
||||||
if [[ -t 1 && ! -v NO_COLOR && "${TERM:-}" != dumb ]]; then
|
if [[ -t 1 && ! -v NO_COLOR && "${TERM:-}" != dumb ]]; then
|
||||||
@@ -78,6 +78,60 @@ preflight(){
|
|||||||
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
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Debian Postfix: systemd instance startup refreshes the chroot resolver files.
|
||||||
|
# This is deliberately limited to running Postfix instances. No data_directory
|
||||||
|
# files are ever removed. A queue flush remains a separate admin decision.
|
||||||
|
postfix_units(){
|
||||||
|
local unit
|
||||||
|
while read -r unit _; do
|
||||||
|
[[ "$unit" == postfix@*.service ]] || continue
|
||||||
|
printf '%s\n' "$unit"
|
||||||
|
done < <(systemctl list-units --type=service --state=active --no-legend --plain 'postfix@*.service' 2>/dev/null)
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_postfix(){
|
||||||
|
local -a units=()
|
||||||
|
local unit queue_dir chroot_resolv
|
||||||
|
if ! command -v postconf >/dev/null 2>&1; then
|
||||||
|
skipped 'Postfix not installed; no MTA restart required'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
mapfile -t units < <(postfix_units)
|
||||||
|
if (( ${#units[@]} == 0 )); then
|
||||||
|
if systemctl is-active --quiet postfix.service; then
|
||||||
|
units=(postfix.service)
|
||||||
|
else
|
||||||
|
skipped 'No active Postfix service; no MTA restart required'
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
info 'Restarting active Postfix systemd service(s) to refresh chroot DNS'
|
||||||
|
for unit in "${units[@]}"; do
|
||||||
|
systemctl restart "$unit" || { failed "Postfix restart failed: $unit"; return 1; }
|
||||||
|
if ! systemctl is-active --quiet "$unit"; then
|
||||||
|
failed "Postfix service not active after restart: $unit"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
ok "Postfix restarted: $unit"
|
||||||
|
done
|
||||||
|
# Only assert a chroot resolver copy when it exists; custom setups may
|
||||||
|
# use multiple queue directories or run SMTP clients without chroot.
|
||||||
|
queue_dir=$(postconf -h queue_directory 2>/dev/null || true)
|
||||||
|
if [[ -n "$queue_dir" && -f "$queue_dir/etc/resolv.conf" ]]; then
|
||||||
|
chroot_resolv="$queue_dir/etc/resolv.conf"
|
||||||
|
if cmp -s "$RESOLV" "$chroot_resolv"; then
|
||||||
|
ok "Postfix chroot resolver synchronized: $chroot_resolv"
|
||||||
|
else
|
||||||
|
failed "Postfix chroot resolver differs: $chroot_resolv"
|
||||||
|
failed 'Check Debian postfix configure-instance.sh / active instances'
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
info 'No default Postfix chroot resolv.conf found (possibly non-chroot or custom layout)'
|
||||||
|
fi
|
||||||
|
info 'Deferred mail is not flushed automatically; if appropriate run: postqueue -f'
|
||||||
|
}
|
||||||
|
|
||||||
show_check(){
|
show_check(){
|
||||||
require_root
|
require_root
|
||||||
need dig; need systemctl; need getent
|
need dig; need systemctl; need getent
|
||||||
@@ -145,6 +199,7 @@ rollback_to(){
|
|||||||
restore_files "$path"
|
restore_files "$path"
|
||||||
restore_services "$path"
|
restore_services "$path"
|
||||||
ok 'Configuration and resolved service state restored'
|
ok 'Configuration and resolved service state restored'
|
||||||
|
sync_postfix
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(){
|
apply(){
|
||||||
@@ -166,7 +221,7 @@ apply(){
|
|||||||
status_banner "$GREEN" 'Umstellung kann durchgeführt werden.' \
|
status_banner "$GREEN" 'Umstellung kann durchgeführt werden.' \
|
||||||
"Ausführen mit: $0 --apply"
|
"Ausführen mit: $0 --apply"
|
||||||
printf '\nPlanned changes:\n hosts: files myhostname dns\n resolv.conf: nameserver 127.0.0.1\n stop and disable systemd-resolved\n'
|
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.'
|
info 'Network interfaces, routes and BIND9 are unchanged; active Postfix will restart.'
|
||||||
confirm || { skipped 'Abbruch durch User'; exit 0; }
|
confirm || { skipped 'Abbruch durch User'; exit 0; }
|
||||||
|
|
||||||
mkdir -p "$STATE_DIR"
|
mkdir -p "$STATE_DIR"
|
||||||
@@ -216,11 +271,25 @@ apply(){
|
|||||||
echononl 'systemd-resolved disabled'
|
echononl 'systemd-resolved disabled'
|
||||||
is_fully_switched && ok 'yes' || { echo; false; }
|
is_fully_switched && ok 'yes' || { echo; false; }
|
||||||
preflight
|
preflight
|
||||||
|
sync_postfix
|
||||||
trap - ERR INT TERM
|
trap - ERR INT TERM
|
||||||
ok 'Switch completed successfully'
|
ok 'Switch completed successfully'
|
||||||
info "Rollback available: $0 --rollback"
|
info "Rollback available: $0 --rollback"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repair_postfix(){
|
||||||
|
require_root
|
||||||
|
need systemctl; need postconf; need cmp
|
||||||
|
if ! is_direct; then
|
||||||
|
fatal 'Resolver is not configured for direct BIND9; use --check first'
|
||||||
|
fi
|
||||||
|
if ! preflight; then
|
||||||
|
fatal 'Local DNSSEC preflight failed; Postfix unchanged'
|
||||||
|
fi
|
||||||
|
sync_postfix
|
||||||
|
ok 'Postfix DNS synchronization completed'
|
||||||
|
}
|
||||||
|
|
||||||
rollback(){
|
rollback(){
|
||||||
require_root
|
require_root
|
||||||
local path
|
local path
|
||||||
@@ -235,15 +304,18 @@ rollback(){
|
|||||||
case "$MODE" in
|
case "$MODE" in
|
||||||
--help)
|
--help)
|
||||||
cat <<'HELP'
|
cat <<'HELP'
|
||||||
Usage: switch-resolver-to-bind9.sh [--check|--apply|--rollback|--help]
|
Usage: switch-resolver-to-bind9.sh [--check|--apply|--rollback|--repair-postfix|--help]
|
||||||
--check read-only checks (default)
|
--check read-only checks (default)
|
||||||
--apply verify BIND9 DNSSEC; back up; switch DNS/NSS; stop+disable resolved
|
--apply verify BIND9 DNSSEC; back up; switch DNS/NSS; stop+disable resolved
|
||||||
--rollback restore files and resolved service state saved before last --apply
|
--rollback restore files and resolved service state saved before last --apply
|
||||||
|
--repair-postfix restart active Postfix instance(s) to refresh chroot DNS
|
||||||
--help this help
|
--help this help
|
||||||
|
After Postfix restart: consider postqueue -f to retry deferred messages.
|
||||||
Notes: run as root; requires BIND9 already working; no package changes.
|
Notes: run as root; requires BIND9 already working; no package changes.
|
||||||
HELP
|
HELP
|
||||||
;;
|
;;
|
||||||
--check) show_check ;;
|
--check) show_check ;;
|
||||||
--apply) apply ;;
|
--apply) apply ;;
|
||||||
--rollback) rollback ;;
|
--rollback) rollback ;;
|
||||||
|
--repair-postfix) repair_postfix ;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user