From faeac11ca86c19a66ac344875f7b9bb50e38f624 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Mon, 5 Oct 2026 23:38:36 +0000 Subject: [PATCH] Remove the .fips DNS routing on package remove, not only on purge Removing the .deb while fips-dns was not running left the resolver's .fips routing file in place. prerm stops fips-dns, but systemd runs its teardown only for an active unit, and postrm cleaned up the routing only on purge. After an apt remove the resolver kept sending .fips queries to [::1]:5354, where nothing listens once the daemon is gone, so .fips lookups timed out until the file was deleted by hand. postrm now runs the DNS cleanup on both remove and purge. A purge of an installed package runs remove and then purge; the second pass finds no file and restarts nothing. A purge of a package already removed runs only the purge pass, which still cleans up. Configuration, keys and the fips group are still removed only on purge. The deb-install check now removes the package with the routing planted and fips-dns stopped, then plants the routing again and purges from config-files state, so each postrm branch is exercised on its own. The packaging text test reads the remove|purge branch. --- packaging/debian/postrm | 34 ++++-- src/packaging_tests.rs | 20 +-- testing/deb-install/test.sh | 234 ++++++++++++++++++++++++------------ 3 files changed, 190 insertions(+), 98 deletions(-) diff --git a/packaging/debian/postrm b/packaging/debian/postrm index 8f1afd5d..123e48aa 100755 --- a/packaging/debian/postrm +++ b/packaging/debian/postrm @@ -3,21 +3,16 @@ set -e case "$1" in - purge) - # Remove configuration and identity keys - rm -rf /etc/fips/ - - # Remove tmpfiles.d entry - rm -f /usr/lib/tmpfiles.d/fips.conf - - # Remove runtime directory - rm -rf /run/fips/ - + remove|purge) # Remove the DNS routing fips-dns-setup may have written, in case # fips-dns-teardown did not run (prerm's stop runs it only when - # fips-dns.service was active), and make the resolver drop it. The - # paths match packaging/common/fips-dns-teardown, which dpkg has - # already removed, so it cannot be called from here. + # fips-dns.service was active), and make the resolver drop it. This + # runs on remove as well as purge: a removed package leaves nothing + # listening behind the routing, and purging a package already removed + # runs only postrm purge. On a purge of an installed package the + # purge pass finds nothing left and restarts nothing. The paths match + # packaging/common/fips-dns-teardown, which dpkg has already removed, + # so it cannot be called from here. restart_resolved=0 if [ -f /etc/systemd/dns-delegate.d/fips.dns-delegate ]; then rm -f /etc/systemd/dns-delegate.d/fips.dns-delegate @@ -52,6 +47,19 @@ case "$1" in || echo "fips: warning: could not reload NetworkManager; reload it to drop the .fips route" fi fi + ;; +esac + +case "$1" in + purge) + # Remove configuration and identity keys + rm -rf /etc/fips/ + + # Remove tmpfiles.d entry + rm -f /usr/lib/tmpfiles.d/fips.conf + + # Remove runtime directory + rm -rf /run/fips/ # Remove fips system group if getent group fips >/dev/null 2>&1; then diff --git a/src/packaging_tests.rs b/src/packaging_tests.rs index e68df0a9..18b525c9 100644 --- a/src/packaging_tests.rs +++ b/src/packaging_tests.rs @@ -391,17 +391,19 @@ fn freebsd_newsyslog_entry_signals_the_daemon8_supervisor_started_with_sighup_re ); } -/// Pins the DNS cleanup in `postrm purge` and `uninstall.sh` to the files -/// `fips-dns-setup` writes, so a purge after a `fips-dns` that never ran its -/// teardown does not leave the resolver sending `.fips` to a dead responder. +/// Pins the DNS cleanup in `postrm remove` and `postrm purge` and in +/// `uninstall.sh` to the files `fips-dns-setup` writes, so a remove or purge +/// after a `fips-dns` that never ran its teardown does not leave the resolver +/// sending `.fips` to a dead responder. /// /// This is a text test. Each path must appear on an `rm -f` line, but a /// resolver command passes wherever it appears on a code line, including in a -/// message. What `postrm` actually does is covered by the deb-install purge -/// check. No suite runs `uninstall.sh`: its two resolved paths were run once, -/// by hand in a container, and its dnsmasq and NetworkManager paths by nothing. +/// message. What `postrm` actually does is covered by the deb-install remove +/// and purge checks. No suite runs `uninstall.sh`: its two resolved paths were +/// run once, by hand in a container, and its dnsmasq and NetworkManager paths +/// by nothing. #[test] -fn dns_cleanup_in_postrm_purge_and_uninstall_removes_every_file_fips_dns_setup_writes_and_restarts_its_resolver() +fn dns_cleanup_in_postrm_remove_and_purge_and_uninstall_removes_every_file_fips_dns_setup_writes_and_restarts_its_resolver() { let setup = rc_vars(&repo_file("packaging/common/fips-dns-setup")); let teardown = rc_vars(&repo_file("packaging/common/fips-dns-teardown")); @@ -433,8 +435,8 @@ fn dns_cleanup_in_postrm_purge_and_uninstall_removes_every_file_fips_dns_setup_w let scripts = [ ( - "packaging/debian/postrm purge)", - case_branch(&repo_file("packaging/debian/postrm"), "purge"), + "packaging/debian/postrm remove|purge)", + case_branch(&repo_file("packaging/debian/postrm"), "remove|purge"), ), ( "packaging/systemd/uninstall.sh", diff --git a/testing/deb-install/test.sh b/testing/deb-install/test.sh index 63977bd4..6e73d154 100755 --- a/testing/deb-install/test.sh +++ b/testing/deb-install/test.sh @@ -10,8 +10,10 @@ # through the resolver backend that fips-dns-setup configured. Then # exercises fips-gateway against the same daemon to verify the # gateway/daemon default-pairing. Finally it -# purges the package with the DNS routing file planted and fips-dns -# stopped, and checks the file is removed and systemd-resolved restarted. +# removes the package with the DNS routing file planted and fips-dns +# stopped, and checks the file is removed and systemd-resolved restarted, +# then plants the file again and purges the package from config-files +# state, with the same checks. # # This is the most thorough test surface — it exercises: # - cargo deb packaging (binary stripping, dependency declaration) @@ -19,7 +21,8 @@ # of /etc/fips/fips.yaml # - postinst maintainer scripts (systemd unit enablement, # fips-dns.service running fips-dns-setup) -# - postrm purge (removing the DNS routing fips-dns-setup wrote) +# - postrm remove and postrm purge (removing the DNS routing +# fips-dns-setup wrote) # - The fips, fips-dns, and (optionally) fips-gateway systemd units # - End-to-end .fips resolution as a real user would experience it # @@ -342,19 +345,155 @@ check_gateway_default_listener() { fi } -# Purge the package with the DNS routing file planted and fips-dns stopped, and +# Put the saved DNS routing file back at and restart systemd-resolved, +# then check the state in which removal leaves the file behind: the file in +# place, fips-dns.service not active, and the resolver routing .fips to +# [::1]:5354. Every failure is recorded with