mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 19:18:25 +00:00
fix(pfsense): restart unbound after editing the DNS Resolver options
Symptom: on pfSense Plus 26.07 amd64, fips-dns-setup wrote the .fips forward-zone into the DNS Resolver custom options, config.xml and the regenerated /var/unbound/unbound.conf both carried it, and the helper reported "DNS Resolver updated and restarted" — but `drill <npub>.fips` through unbound answered NXDOMAIN, and `unbound-control lookup` showed the query still going to the root servers. The daemon answered the same query directly. fips-dns-teardown had the mirror problem: the block was gone from the file while the running resolver kept forwarding. Root cause: the helper called sync_unbound_service(), which regenerates unbound.conf and then only *starts* unbound, a no-op while an instance is already running, so the running resolver never saw the new file. Fix: call services_unbound_configure(), which is what the GUI's Apply runs (services_unbound.php): it TERMs the running unbound, waits, and starts it on the regenerated configuration. Verified on the same VM: teardown and setup each produce a new unbound pid, `unbound-control lookup` reports "forwarding request", and the full chain answers NOERROR; after a reboot the block is regenerated from config.xml and the chain still answers. Regression check: check-pfsense-pkg.sh now asserts, statically, that the shipped helper calls services_unbound_configure() and not sync_unbound_service(); the call itself needs pfSense's includes and cannot run in CI. The README's test record gains the Plus 26.07 amd64 VM run that found this.
This commit is contained in:
committed by
Johnathan Corgan
parent
a72c589342
commit
69a512f7e8
+29
-13
@@ -506,20 +506,36 @@ gate — nothing re-checks it when this code changes.
|
||||
|
||||
Known still-unexercised paths, from that same run: `fips-dns-setup`'s
|
||||
refusal path (it has only ever run against a responder that was already
|
||||
answering), its DNS Forwarder branch, and `pkg delete`.
|
||||
answering) and its DNS Forwarder branch.
|
||||
(`fips-dns-teardown` has since been run on the same box and restored
|
||||
`custom_options` byte for byte.)
|
||||
|
||||
**No amd64 package has ever been installed.** The CE 2.8.1 (FreeBSD 15)
|
||||
and the CE 2.9 / Plus 26.x (FreeBSD 16) amd64 packages are built and
|
||||
pass the checker, and nothing more. The one hardware run was aarch64;
|
||||
the amd64 packages share every script here and have had none of that
|
||||
exposure, so read a passing check as "the package is well-formed", not
|
||||
"it works".
|
||||
The FreeBSD 16 amd64 package has been run once on pfSense Plus
|
||||
26.07-RELEASE amd64, in a KVM virtual machine installed with the Netgate
|
||||
installer (the same `FreeBSD:16:amd64` package serves CE 2.9.0). That
|
||||
package was built outside `master`'s CI, which builds no FreeBSD 16
|
||||
package, on the 16.0-CURRENT 20260907 snapshot:
|
||||
`pkg add`, the boot script through start, re-entrant start, restart and
|
||||
stop with the daemon answering `fipsctl` and DNS, `pfSctl -c 'service
|
||||
reload packages'` (the WAN-address-change path) leaving the running
|
||||
daemon alone, a reboot bringing up exactly one daemon with the DNS
|
||||
Resolver block regenerated from `config.xml`, `fips-dns-teardown`
|
||||
leaving `custom_options` empty as it was, and `pkg delete`. That run
|
||||
found the defect fixed alongside this text: `fips-dns-setup` wrote the
|
||||
block and reported "updated and restarted", but the running unbound was
|
||||
never restarted and answered NXDOMAIN for `.fips` until it was. What the
|
||||
VM did not cover: mesh traffic (no peer), the TUN datapath under pf, and
|
||||
CE itself. The CE 2.8.1 (FreeBSD 15) package is still built and checked
|
||||
only.
|
||||
|
||||
That matters because the aarch64 run found several defects, every one in
|
||||
this packaging rather than the daemon — a boot script whose pid check
|
||||
never succeeded, a DNS setup that reported success while nothing was
|
||||
listening, and a static build that faulted at `posix_spawn`. The daemon
|
||||
itself needed no changes. An untested path in the amd64 packages is
|
||||
exactly where the next one would sit.
|
||||
Left behind by `pkg delete`, by design or as known gaps:
|
||||
`/usr/local/etc/fips/fips.key` if the daemon generated one (it may be the
|
||||
node's identity), `/var/log/fips.log`, and the newsyslog entry under
|
||||
`/var/etc`, which a RAM-disk `/var` drops at the next boot anyway.
|
||||
|
||||
The hardware and VM runs found several defects, every one in this
|
||||
packaging rather than the daemon — a boot script whose pid check never
|
||||
succeeded, a DNS setup that reported success while nothing was
|
||||
listening, a static build that faulted at `posix_spawn`, and the
|
||||
resolver restart above. The daemon itself needed no changes. An untested
|
||||
path is exactly where the next one would sit.
|
||||
|
||||
@@ -29,6 +29,7 @@ if (!getenv('FIPS_UNBOUND_HELPER_TEST')) {
|
||||
require_once("config.inc");
|
||||
require_once("util.inc");
|
||||
require_once("unbound.inc");
|
||||
require_once("services.inc");
|
||||
}
|
||||
|
||||
define('FIPS_BEGIN', '# BEGIN FIPS - managed by fips-dns-setup, do not edit this block');
|
||||
@@ -218,9 +219,13 @@ if (!fips_resolver_enabled()) {
|
||||
}
|
||||
|
||||
/* Regenerate /var/unbound/unbound.conf from config.xml and restart the
|
||||
* resolver. Nothing shorter works: the file is generated wholesale, so
|
||||
* a reload alone would re-read the config we have not rewritten yet. */
|
||||
sync_unbound_service();
|
||||
* resolver, the way the GUI's Apply does (services_unbound.php). It has to
|
||||
* be this function: sync_unbound_service() regenerates the file too, but
|
||||
* then only *starts* unbound, which is a no-op while one is running, so
|
||||
* the running resolver kept its old forward set and answered NXDOMAIN for
|
||||
* .fips (found on Plus 26.07 amd64). services_unbound_configure() TERMs
|
||||
* the running instance first. */
|
||||
services_unbound_configure();
|
||||
|
||||
fips_log("DNS Resolver updated and restarted");
|
||||
exit(0);
|
||||
|
||||
@@ -527,6 +527,20 @@ fi
|
||||
# ── 6. PHP helper ───────────────────────────────────────────────────────────
|
||||
echo "-- php helper"
|
||||
HELPER="$PAYLOAD/libexec/fips/fips-unbound-custom.php"
|
||||
# After editing config.xml the helper must restart the running resolver the
|
||||
# way the GUI's Apply does, services_unbound_configure(): it TERMs unbound
|
||||
# and starts it on the regenerated unbound.conf. sync_unbound_service()
|
||||
# regenerates the file too but then only *starts* unbound, a no-op while one
|
||||
# is running, so the resolver kept its old forward set and answered NXDOMAIN
|
||||
# for .fips while setup reported success (Plus 26.07 amd64). A static check,
|
||||
# since the call needs pfSense's includes to run.
|
||||
if grep -qE '^[^*/#]*services_unbound_configure\(' "$HELPER" \
|
||||
&& ! grep -qE '^[^*/#]*sync_unbound_service\(' "$HELPER"; then
|
||||
pass "helper restarts unbound with services_unbound_configure()"
|
||||
else
|
||||
fail "helper does not restart unbound with services_unbound_configure()" \
|
||||
"sync_unbound_service() leaves a running unbound on its old config."
|
||||
fi
|
||||
if ! command -v php >/dev/null 2>&1; then
|
||||
skip "php -l and the fips_strip_block unit test (no php on this host)"
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user