mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 19:18:25 +00:00
The FreeBSD package wrote the daemon's output to /var/log/fips.log and never rotated it, so the log grew without bound. Ship a newsyslog entry in /usr/local/etc/newsyslog.conf.d, which the stock newsyslog.conf includes: five bzip2-compressed generations of 1000 KB, mode 600 to match the file daemon(8) creates. An entry alone would not work, because daemon(8) keeps the -o file open and reopens it on SIGHUP only when started with -H, and only the supervisor handles that signal. The rc script now starts daemon(8) with -H and records the supervisor's pid in /var/run/fips/daemon.pid, which is the pid file the entry signals. The child pidfile that rc.subr uses for stop and status is unchanged. Add a lib test that checks the rc script, the newsyslog entry and the package staging agree on the log path, the signalled pid file and the installed location. The FreeBSD package smoke install now also confirms the stock newsyslog configuration picks up the shipped entry, starts the daemon, forces a rotation of its log, and checks that daemon(8) closes the rotated file and holds the new one open. This exercises the SIGHUP reopen that the static check of the packaging files cannot.
110 lines
4.5 KiB
Markdown
110 lines
4.5 KiB
Markdown
# FIPS FreeBSD packaging
|
|
|
|
Builds a native FreeBSD `.pkg` shipping `fips`, `fipsctl`, `fipstop`,
|
|
rc.d services, and `.fips` DNS integration. `fips-gateway` is excluded
|
|
(its NAT backend is nftables, Linux-only).
|
|
|
|
Platform notes: the Ethernet and BLE transports are not available on
|
|
FreeBSD (UDP, TCP, Tor, and Nym are). The UDP datapath deliberately
|
|
uses the portable single-packet receive loop — FreeBSD's `recvmmsg(2)`
|
|
is a libc loop over `recvmsg`, not a kernel batch, so the Linux/macOS
|
|
batched arm would gain nothing — and the connected-UDP fast path is
|
|
not compiled pending FreeBSD-specific `SO_REUSEPORT` validation.
|
|
|
|
## Build
|
|
|
|
```sh
|
|
./packaging/freebsd/build-pkg.sh # cargo build --release + pkg create
|
|
./packaging/freebsd/build-pkg.sh --no-build # package existing release binaries
|
|
```
|
|
|
|
Output: `deploy/fips-<version>-freebsd-<arch>.pkg`. pkg versions cannot
|
|
contain `-` or `+`, so both are mapped to `.`: a Cargo version of
|
|
`<x.y.z>-dev` becomes `fips-<x.y.z>.dev-freebsd-amd64.pkg`.
|
|
|
|
## Install
|
|
|
|
```sh
|
|
pkg add ./deploy/fips-<version>-freebsd-<arch>.pkg
|
|
# post-install seeds this from the sample if absent, at mode 0600
|
|
vi /usr/local/etc/fips/fips.yaml
|
|
sysrc fips_enable=YES fips_dns_enable=YES
|
|
service fips start
|
|
service fips_dns start
|
|
fipsctl show status
|
|
```
|
|
|
|
Config installs sample-style (`@sample` semantics via manifest
|
|
scripts), so an edited `fips.yaml` survives upgrade/removal.
|
|
`fips.yaml` is installed `0600` — it may hold the node's private key
|
|
(`nsec:`). The daemon runs under daemon(8) with pidfile
|
|
`/var/run/fips/fips.pid` and logs to `/var/log/fips.log` (rc.conf
|
|
knobs: `fips_config`, `fips_flags`, `fips_logfile`).
|
|
|
|
The log is rotated by `/usr/local/etc/newsyslog.conf.d/fips.conf`: five
|
|
bzip2-compressed generations of 1000 KB. daemon(8) runs with `-H` and
|
|
records its own pid in `/var/run/fips/daemon.pid`; newsyslog signals that
|
|
pid after the rename, and daemon(8) reopens the log. The entry covers
|
|
the default `fips_logfile` only, so a log moved elsewhere needs its own
|
|
newsyslog entry. The entry belongs to the package and is replaced on
|
|
upgrade.
|
|
|
|
The package creates a `fips` group; members can run `fipsctl` and
|
|
`fipstop` without root (`pw groupmod fips -m <user>`, then re-login).
|
|
On `pkg upgrade` the services are stopped before the binaries are
|
|
replaced and started again afterwards if enabled; on `pkg delete` they
|
|
are stopped and the `.fips` resolver drop-in is removed.
|
|
|
|
## .fips DNS integration
|
|
|
|
The daemon answers `.fips` queries on `[::1]:5354`. `fips_dns` points
|
|
the system resolver's `fips.` zone there; backends tried in order:
|
|
base `local_unbound` (drop-in `/var/unbound/conf.d/fips.conf`), pkg
|
|
`unbound`, pkg `dnsmasq`. The unbound drop-in must (and does) set:
|
|
|
|
- `do-not-query-localhost: no` — unbound's default silently refuses
|
|
loopback forwarders, SERVFAILing every `.fips` query.
|
|
- `do-ip6: yes` — the daemon binds `::1` only.
|
|
- `domain-insecure: "fips."` — the zone is unsigned.
|
|
|
|
### One-time host resolver setup (NOT automated)
|
|
|
|
The package configures the `fips.` zone only; making the local
|
|
resolver the *system* resolver is an operator decision. On a typical
|
|
box:
|
|
|
|
```sh
|
|
sysrc local_unbound_enable=YES
|
|
local-unbound-setup 1.1.1.1 9.9.9.9 # explicit upstreams — see below
|
|
service local_unbound restart
|
|
```
|
|
|
|
Field-tested caveats (`fips-dns-setup` detects and warns about each):
|
|
|
|
- `/etc/resolv.conf` must list a loopback nameserver (ideally only
|
|
`127.0.0.1`), or nothing ever queries unbound and `.fips` cannot
|
|
resolve.
|
|
- **Do not use a home-router DNS proxy as unbound's upstream.** Many
|
|
CPE forwarders are EDNS-broken; unbound always sends EDNS, so every
|
|
public query SERVFAILs. Forward to real resolvers (ISP or public).
|
|
- Remove `options edns0` from `/etc/resolv.conf` if present, and set
|
|
`resolv_conf_options=""` in `/etc/resolvconf.conf` so resolvconf(8)
|
|
does not re-add it — against an EDNS-broken router it breaks libc
|
|
resolution outright.
|
|
- Never run `local-unbound-setup` with no arguments while resolv.conf
|
|
already points at 127.0.0.1 — it snapshots that as upstream and
|
|
forwards unbound to itself.
|
|
|
|
## Debugging
|
|
|
|
```sh
|
|
drill -p 5354 <npub>.fips @::1 AAAA # daemon directly (bypasses unbound)
|
|
drill <npub>.fips AAAA # full chain; SERVER: must be 127.0.0.1
|
|
cat /var/run/fips/dns-backend # which backend fips_dns configured
|
|
```
|
|
|
|
The TUN interface gets a kernel-assigned name (`tun0`, `tun1`, ...),
|
|
like `utun` on macOS, and is destroyed automatically when the daemon
|
|
exits. `ifconfig <name>` prints `Opened by PID <n>` for the process
|
|
holding a tun device.
|