From 8fd515e81f50c119508253144af5a02285cba3d5 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Fri, 5 Jun 2026 18:04:24 +0000 Subject: [PATCH] packaging: ship fips.yaml as an example, not a dpkg conf-file Installing /etc/fips/fips.yaml as a live dpkg conf-file collides with a configuration-management-rendered or operator-edited config on upgrade: dpkg either prompts interactively (keep/replace), stalling unattended upgrades, or clobbers the local file. Ship the default config as /usr/share/doc/fips/fips.yaml.example (mode 644) and drop it from conf-files. postinst now seeds /etc/fips/fips.yaml from the example only when it does not already exist (mode 600), yielding to any existing config without a prompt or clobber. Add ConditionPathExists for the config to the service unit so a missing config skips the unit cleanly rather than crash-looping. --- Cargo.toml | 4 ++-- packaging/README.md | 14 ++++++++++++-- packaging/debian/fips.service | 5 +++++ packaging/debian/postinst | 10 ++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bf25c12..7543be6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,7 +71,7 @@ assets = [ ["target/release/fips", "/usr/bin/", "755"], ["target/release/fipsctl", "/usr/bin/", "755"], ["target/release/fipstop", "/usr/bin/", "755"], - ["packaging/common/fips.yaml", "/etc/fips/fips.yaml", "600"], + ["packaging/common/fips.yaml", "/usr/share/fips/fips.yaml.example", "644"], ["packaging/common/hosts", "/etc/fips/hosts", "644"], ["packaging/common/fips.nft", "/etc/fips/fips.nft", "644"], ["packaging/debian/fips.service", "/lib/systemd/system/fips.service", "644"], @@ -84,7 +84,7 @@ assets = [ ["packaging/debian/fips-gateway.service", "/lib/systemd/system/fips-gateway.service", "644"], ["docs/design/fips-security.md", "/usr/share/doc/fips/fips-security.md", "644"], ] -conf-files = ["/etc/fips/fips.yaml", "/etc/fips/hosts", "/etc/fips/fips.nft"] +conf-files = ["/etc/fips/hosts", "/etc/fips/fips.nft"] [dev-dependencies] tempfile = "3.15" diff --git a/packaging/README.md b/packaging/README.md index 161207c..7147728 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -33,10 +33,20 @@ packaging/ ### Debian/Ubuntu (`.deb`) Built with [cargo-deb](https://github.com/kornelski/cargo-deb). Installs -`fips`, `fipsctl`, and `fipstop` to `/usr/bin/`, places config at -`/etc/fips/fips.yaml` (preserved on upgrade), and enables the systemd +`fips`, `fipsctl`, and `fipstop` to `/usr/bin/`, and enables the systemd service. +The default configuration ships as an example at +`/usr/share/fips/fips.yaml.example` and is **not** a dpkg conf-file. +(It is deliberately **not** under `/usr/share/doc`, which minimal and +container installs path-exclude, since the postinst reads it at install +time.) +On install, `postinst` seeds `/etc/fips/fips.yaml` (mode 600) from the +example **only if it does not already exist**, so a configuration that +was rendered by configuration management or edited by an operator is +never prompted for or clobbered on upgrade. To reset to defaults, remove +`/etc/fips/fips.yaml` and reinstall, or copy the example back manually. + ```sh # Build make deb diff --git a/packaging/debian/fips.service b/packaging/debian/fips.service index 4460eaa..d1b5616 100644 --- a/packaging/debian/fips.service +++ b/packaging/debian/fips.service @@ -3,6 +3,11 @@ Description=FIPS Mesh Network Daemon After=network-online.target Wants=network-online.target +# The config file is no longer a packaged conf-file; postinst seeds it +# if absent. Skip the unit (inactive, not failed) rather than crash-loop +# if it is ever missing. +ConditionPathExists=/etc/fips/fips.yaml + [Service] Type=simple ExecStart=/usr/bin/fips --config /etc/fips/fips.yaml diff --git a/packaging/debian/postinst b/packaging/debian/postinst index 3e2c200..5c4bf4c 100755 --- a/packaging/debian/postinst +++ b/packaging/debian/postinst @@ -9,6 +9,16 @@ case "$1" in groupadd --system fips fi + # Seed /etc/fips/fips.yaml from the shipped example only if it + # does not already exist. The live config is no longer a dpkg + # conf-file; this copy-if-absent yields to any operator- or + # configuration-management-rendered file and never clobbers it. + if [ ! -e /etc/fips/fips.yaml ]; then + install -m 600 -o root -g root \ + /usr/share/fips/fips.yaml.example \ + /etc/fips/fips.yaml + fi + # Drop-in directory for operator nftables rules included by # /etc/fips/fips.nft. Empty by default; the include glob matches # nothing cleanly out of the box.