mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08: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
|
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
|
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
|
(`fips-dns-teardown` has since been run on the same box and restored
|
||||||
`custom_options` byte for byte.)
|
`custom_options` byte for byte.)
|
||||||
|
|
||||||
**No amd64 package has ever been installed.** The CE 2.8.1 (FreeBSD 15)
|
The FreeBSD 16 amd64 package has been run once on pfSense Plus
|
||||||
and the CE 2.9 / Plus 26.x (FreeBSD 16) amd64 packages are built and
|
26.07-RELEASE amd64, in a KVM virtual machine installed with the Netgate
|
||||||
pass the checker, and nothing more. The one hardware run was aarch64;
|
installer (the same `FreeBSD:16:amd64` package serves CE 2.9.0). That
|
||||||
the amd64 packages share every script here and have had none of that
|
package was built outside `master`'s CI, which builds no FreeBSD 16
|
||||||
exposure, so read a passing check as "the package is well-formed", not
|
package, on the 16.0-CURRENT 20260907 snapshot:
|
||||||
"it works".
|
`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
|
Left behind by `pkg delete`, by design or as known gaps:
|
||||||
this packaging rather than the daemon — a boot script whose pid check
|
`/usr/local/etc/fips/fips.key` if the daemon generated one (it may be the
|
||||||
never succeeded, a DNS setup that reported success while nothing was
|
node's identity), `/var/log/fips.log`, and the newsyslog entry under
|
||||||
listening, and a static build that faulted at `posix_spawn`. The daemon
|
`/var/etc`, which a RAM-disk `/var` drops at the next boot anyway.
|
||||||
itself needed no changes. An untested path in the amd64 packages is
|
|
||||||
exactly where the next one would sit.
|
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("config.inc");
|
||||||
require_once("util.inc");
|
require_once("util.inc");
|
||||||
require_once("unbound.inc");
|
require_once("unbound.inc");
|
||||||
|
require_once("services.inc");
|
||||||
}
|
}
|
||||||
|
|
||||||
define('FIPS_BEGIN', '# BEGIN FIPS - managed by fips-dns-setup, do not edit this block');
|
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
|
/* Regenerate /var/unbound/unbound.conf from config.xml and restart the
|
||||||
* resolver. Nothing shorter works: the file is generated wholesale, so
|
* resolver, the way the GUI's Apply does (services_unbound.php). It has to
|
||||||
* a reload alone would re-read the config we have not rewritten yet. */
|
* be this function: sync_unbound_service() regenerates the file too, but
|
||||||
sync_unbound_service();
|
* 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");
|
fips_log("DNS Resolver updated and restarted");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|||||||
@@ -527,6 +527,20 @@ fi
|
|||||||
# ── 6. PHP helper ───────────────────────────────────────────────────────────
|
# ── 6. PHP helper ───────────────────────────────────────────────────────────
|
||||||
echo "-- php helper"
|
echo "-- php helper"
|
||||||
HELPER="$PAYLOAD/libexec/fips/fips-unbound-custom.php"
|
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
|
if ! command -v php >/dev/null 2>&1; then
|
||||||
skip "php -l and the fips_strip_block unit test (no php on this host)"
|
skip "php -l and the fips_strip_block unit test (no php on this host)"
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user