mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 11:08:25 +00:00
packaging/README.md and the pfSense builder's header said a firmware upgrade removes the package, and the fips-dns-setup comment said the same of everything under /usr/local. pfSense-upgrade reinstalls only pfSense-pkg-* packages, and a live Plus 26.03.1 to 26.07 upgrade kept this one, as the pfSense README, the post-install banner and pkg-descr already say. A major base change still calls for the package built for the new base.
509 lines
20 KiB
Markdown
509 lines
20 KiB
Markdown
# FIPS Packaging
|
|
|
|
This directory contains packaging for all supported target platforms.
|
|
Most build outputs go to `deploy/` at the project root; `make ipk`
|
|
and `make apk` write to `dist/` instead.
|
|
|
|
## Quick Start
|
|
|
|
```sh
|
|
make deb # Debian/Ubuntu .deb (built in the pinned container)
|
|
make rpm # Fedora/RHEL .rpm, named fips-mesh (built in the pinned container)
|
|
make tarball # systemd install tarball
|
|
make ipk # OpenWrt .ipk (opkg, OpenWrt 24.x and earlier)
|
|
make apk # OpenWrt .apk (apk-tools, mandatory on OpenWrt 25+)
|
|
make aur # Arch Linux AUR package (fips-git, local build + namcap)
|
|
make pkg # macOS .pkg installer
|
|
make freebsd # FreeBSD .pkg package (on FreeBSD; use gmake)
|
|
make pfsense # pfSense .pkg package (on FreeBSD; use gmake)
|
|
make zip # Windows .zip package
|
|
make all # deb + tarball (default)
|
|
```
|
|
|
|
## The two Debian build paths
|
|
|
|
`make deb` builds in a container pinned to the oldest supported
|
|
Debian-family distribution, named with the glibc floor in
|
|
[build-floor.env](build-floor.env), and checks the package it produced
|
|
against that floor before handing it back. The floor itself is lower than that
|
|
image's glibc: RHEL 9 is the lowest supported distribution project-wide, and
|
|
both families ship these same binaries. Its only host prerequisite is
|
|
docker: the toolchain and the build dependencies live in the image. This
|
|
is the path the release workflow, the integration suite and the internal
|
|
builder all take, so a package that passes locally is built the way the
|
|
shipped one is.
|
|
|
|
`make deb-host` is the old path. It builds on the host, at whatever glibc
|
|
the host has, and it is checked against nothing. Use it for local
|
|
iteration only. A package built on a current distribution records a
|
|
version dependency that the loader refuses on Debian 12 and Ubuntu 22.04,
|
|
which is what shipped in every Linux artifact from v0.3.0 through v0.5.0,
|
|
so it must not produce anything anyone else installs.
|
|
|
|
## Build Prerequisites
|
|
|
|
The prerequisites below apply to the host-build targets. `make deb` needs
|
|
docker and nothing else.
|
|
|
|
These targets build FIPS from source, so the host needs a build
|
|
environment in addition to a Rust toolchain (the version pinned in
|
|
`rust-toolchain.toml` is auto-installed by rustup).
|
|
|
|
On Linux, `libclang` is **required**: the LAN gateway's nftables
|
|
bindings are generated by `bindgen` at build time, which needs
|
|
`libclang.so` on the build host. Without it the build fails inside the
|
|
`rustables` crate with an "Unable to find libclang" error.
|
|
|
|
```sh
|
|
sudo apt install libclang-dev # Debian / Ubuntu
|
|
```
|
|
|
|
This is a build-time prerequisite only — it is not a runtime
|
|
dependency, so hosts installing a pre-built `.deb` do not need it.
|
|
|
|
BLE is not optional, and it is not universal either. `build.rs` sets
|
|
`ble_available` for glibc Linux or Android, which is the set of
|
|
platforms with a concrete backend: the transport is absent from musl
|
|
Linux, macOS, FreeBSD and Windows builds entirely. On glibc Linux
|
|
`libdbus-1-dev` and `pkg-config` are hard build prerequisites: there is
|
|
no probe that skips BLE when they are missing. The BlueZ daemon is a
|
|
runtime dependency and is not needed to build.
|
|
|
|
## Directory Structure
|
|
|
|
```text
|
|
packaging/
|
|
aur/ Arch Linux AUR packaging (PKGBUILD, supporting files)
|
|
common/ Shared assets (default config, hosts file) and pkg-lib.sh,
|
|
the helpers the FreeBSD and pfSense builders share
|
|
debian/ Debian/Ubuntu .deb packaging via cargo-deb
|
|
rpm/ Fedora/RHEL .rpm packaging via rpmbuild, over the binaries
|
|
the Debian container build produces
|
|
freebsd/ FreeBSD .pkg packaging via pkg-create(8)
|
|
pfsense/ pfSense .pkg packaging (FreeBSD-based, but not the same)
|
|
macos/ macOS .pkg installer via pkgbuild
|
|
nixos/ NixOS flake module (services.fips.*)
|
|
systemd/ Generic Linux systemd tarball packaging
|
|
openwrt-ipk/ OpenWrt .ipk packaging via cargo-zigbuild (opkg)
|
|
openwrt-apk/ OpenWrt .apk packaging via cargo-zigbuild + apk mkpkg
|
|
windows/ Windows .zip package with service scripts
|
|
```
|
|
|
|
## Formats
|
|
|
|
### Debian/Ubuntu (`.deb`)
|
|
|
|
Built with [cargo-deb](https://github.com/kornelski/cargo-deb). Installs
|
|
`fips`, `fipsctl`, `fipstop`, and `fips-gateway` to `/usr/bin/`, ships
|
|
the `fips`, `fips-dns`, `fips-firewall`, and `fips-gateway` systemd
|
|
units, and enables the `fips` and `fips-dns` services.
|
|
|
|
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
|
|
|
|
# Install
|
|
sudo apt install ./deploy/fips_<version>_<arch>.deb
|
|
|
|
# Remove (preserves config and keys)
|
|
sudo dpkg -r fips
|
|
|
|
# Purge (removes config and identity keys)
|
|
sudo dpkg -P fips
|
|
```
|
|
|
|
### RPM (`.rpm`)
|
|
|
|
Built with `rpmbuild` from [rpm/fips.spec](rpm/fips.spec). The same files land
|
|
in the same places as the `.deb`, the same `fips` system group is created, the
|
|
same `/etc/fips/fips.yaml` seeding happens, and the same two units are enabled;
|
|
`fips-firewall` and `fips-gateway` stay opt-in.
|
|
|
|
**The package is named `fips-mesh`, not `fips`.** Fedora's namespace already
|
|
has a `fips` — an unrelated OpenGL FITS image viewer, currently 3.4.0 — which
|
|
owns `/usr/bin/fips`. Ours at 0.6.0 would be an *older* `fips` to every RPM
|
|
tool, so a routine `dnf upgrade` replaces a running mesh node with an image
|
|
viewer and takes the units with it; that is not hypothetical, it happened
|
|
within the hour on a test machine. The two cannot coexist either, since both
|
|
ship `/usr/bin/fips`, so the spec declares `Conflicts: fips` and dnf refuses
|
|
with both names on screen instead of a bare path.
|
|
|
|
Like the Debian package, it has two build paths, and for the same reason.
|
|
|
|
`make rpm` compiles nothing on the host: it builds the binaries in the image
|
|
declared in [build-floor.env](build-floor.env), packages those, and checks the
|
|
glibc requirement of the finished package against the declared floor. So the
|
|
RPM carries the same objects as the `.deb` and the tarball, and a package built
|
|
above the floor fails there rather than at a user's `dnf install`. rpmbuild
|
|
runs in `FIPS_RPM_BUILD_IMAGE` (AlmaLinux 9, pinned by digest), which supplies
|
|
two things a build host may lack: rpmbuild itself, and systemd-rpm-macros,
|
|
without which the spec's `%systemd_post` would not expand and the package would
|
|
ship scriptlets that quietly do nothing. Docker is the only host prerequisite.
|
|
|
|
`make rpm-host` packages whatever the host toolchain built. Like `deb-host` it
|
|
is for local iteration and not for anything anyone else installs; nothing
|
|
checks its floor.
|
|
|
|
The release workflow calls the same container script both matrix legs, with
|
|
`--no-build`, over the binaries it has already recovered from the `.deb` — one
|
|
build, three artifacts — and attaches the result to the GitHub Release next to
|
|
the `.deb` and the tarball.
|
|
|
|
```sh
|
|
# Build (requires docker)
|
|
make rpm
|
|
|
|
# Install
|
|
sudo dnf install ./deploy/fips-mesh-<version>-<release>.<arch>.rpm
|
|
|
|
# Remove (keeps /etc/fips, including identity keys)
|
|
sudo dnf remove fips-mesh
|
|
```
|
|
|
|
Two firewalls, on the distributions where firewalld owns nftables. They do not
|
|
conflict — firewalld manages its own tables and `fips-firewall.service` adds
|
|
`table inet fips`, which returns immediately for anything not arriving on
|
|
`fips0` — but firewalld is filtering the node whether or not that unit ever
|
|
runs, and in two places worth knowing:
|
|
|
|
- **Inbound peers arrive on your ordinary interface**, on the transport ports
|
|
(`2121/udp` and `8443/tcp` in the shipped config), and those are in whatever
|
|
zone that interface belongs to. Fedora Workstation's default zone opens
|
|
`1025-65535` for both protocols, so it works there untouched; RHEL, CentOS
|
|
Stream and Fedora Server default to `public`, which allows `ssh`,
|
|
`dhcpv6-client` and `mdns` and nothing else, so a node there accepts no
|
|
inbound peers until the ports are opened:
|
|
|
|
```sh
|
|
sudo firewall-cmd --permanent --add-port=2121/udp --add-port=8443/tcp
|
|
sudo firewall-cmd --reload
|
|
```
|
|
|
|
- **`fips0` itself lands in the default zone**, since nothing assigns it one —
|
|
`firewall-cmd --get-zone-of-interface=fips0` says `no zone`, which means the
|
|
default. Mesh traffic to local services is then subject to that zone as well
|
|
as to the fips baseline. Giving the interface its own zone keeps the two
|
|
decisions apart, and `trusted` leaves the filtering to `/etc/fips/fips.nft`
|
|
and its drop-ins, which is where it is meant to be:
|
|
|
|
```sh
|
|
sudo firewall-cmd --permanent --zone=trusted --change-interface=fips0
|
|
sudo firewall-cmd --reload
|
|
```
|
|
|
|
Either way the fips table stays invisible to firewalld: `firewall-cmd
|
|
--list-all` will not show it, and opening a port with `firewall-cmd` does not
|
|
open it in the fips table. That is what `/etc/fips/fips.d/` is for.
|
|
|
|
Note also that a default RHEL, CentOS Stream or AlmaLinux install has no
|
|
resolver backend `fips-dns-setup` can use: systemd is older than the
|
|
`dns-delegate` drop-in, systemd-resolved is installed but not enabled, and
|
|
dnsmasq is not installed. The script falls through to its last branch and
|
|
prints manual instructions, so `.fips` names do not resolve until a backend is
|
|
in place. Fedora, which enables systemd-resolved, is configured automatically.
|
|
|
|
Three things differ from the Debian package, because the package managers do:
|
|
|
|
- **The floor is checked on the package, not against it.** `cargo-deb` writes a
|
|
dependency floor that can disagree with the binaries, so
|
|
`testing/check-deb-depends.sh` compares the two. rpm derives the requirement
|
|
from the ELF files and cannot disagree with them, which moves the risk one
|
|
step back — to binaries built above the floor in the first place.
|
|
`testing/check-rpm-floor.sh` reads `libc.so.6(GLIBC_x.y)` out of the finished
|
|
package, the same table `dnf` enforces at install time, and fails the build
|
|
above the floor.
|
|
- **No purge.** dpkg distinguishes remove from purge, and `postrm purge`
|
|
deletes `/etc/fips` and the `fips` group. rpm has no such distinction, so the
|
|
equivalent would run on an ordinary erase — and during a distribution upgrade
|
|
that erases and reinstalls — taking the node's identity keys with it.
|
|
Configuration and keys therefore survive `dnf remove`; delete `/etc/fips`
|
|
yourself if you mean it.
|
|
- **Version vs Release.** A dev build is `0.6.0-0.dev.git<date>.<sha>` rather
|
|
than the `.deb`'s `0.6.0~dev+git<date>.<sha>-1`. rpm has understood `~` since
|
|
4.10, so this is a choice rather than a limitation: a Release beginning with
|
|
`0.` is the convention for pre-release packages in this ecosystem, and it
|
|
sorts below the `1` a tagged release carries. The Release carries no `%{dist}` tag
|
|
either: there is one build, the glibc one, and a dist tag would name whichever
|
|
image happened to run rpmbuild in an artifact that installs on all of them.
|
|
|
|
No install-test suite covers the RPM. The `deb-install` suite exercises the
|
|
`.deb` across five distributions on every push; the RPM is built on every push
|
|
and installed by nobody but you.
|
|
|
|
### systemd Tarball
|
|
|
|
A self-contained tarball with binaries and an `install.sh` script for
|
|
any systemd-based Linux distribution.
|
|
|
|
```sh
|
|
# Build
|
|
make tarball
|
|
|
|
# Install (on target host)
|
|
tar -xzf deploy/fips-<version>-linux-<arch>.tar.gz
|
|
sudo ./fips-<version>-linux-<arch>/install.sh
|
|
```
|
|
|
|
See [systemd/README.install.md](systemd/README.install.md) for full
|
|
installation and configuration instructions.
|
|
|
|
### OpenWrt (`.ipk`, opkg — OpenWrt 24.x and earlier)
|
|
|
|
Cross-compiled with cargo-zigbuild and assembled as a standard `.ipk`
|
|
archive. The build script accepts aarch64, mipsel, mips, arm and
|
|
x86\_64; releases publish aarch64 and x86\_64. The MIPS targets are
|
|
not built: 32-bit MIPS has no 64-bit atomics, which fips and
|
|
`nostr-relay-pool` both use (see the comment in
|
|
`.github/workflows/package-openwrt.yml`).
|
|
|
|
```sh
|
|
# Build (default: aarch64)
|
|
make ipk
|
|
|
|
# Build for a specific architecture
|
|
bash packaging/openwrt-ipk/build-ipk.sh --arch x86_64
|
|
```
|
|
|
|
See [openwrt-ipk/README.md](openwrt-ipk/README.md) for router-specific
|
|
installation instructions.
|
|
|
|
### OpenWrt (`.apk`, apk-tools — mandatory on OpenWrt 25+)
|
|
|
|
OpenWrt 25 makes apk-tools the mandatory package manager (it is opt-in on
|
|
24.10). Same SDK-free approach
|
|
(cargo-zigbuild), but the `.apk` container is assembled by `apk mkpkg`
|
|
rather than hand-rolled, so the build additionally needs an apk-tools v3
|
|
`apk` binary built from source. The installed-filesystem payload is shared
|
|
with the `.ipk` package.
|
|
|
|
```sh
|
|
# Build (default: aarch64; also x86_64)
|
|
make apk
|
|
|
|
# Build for a specific architecture
|
|
bash packaging/openwrt-apk/build-apk.sh --arch x86_64
|
|
```
|
|
|
|
Packages are unsigned; install with `apk add --allow-untrusted`. See
|
|
[openwrt-apk/README.md](openwrt-apk/README.md) for building apk-tools and
|
|
router-specific installation.
|
|
|
|
### macOS (`.pkg`)
|
|
|
|
Built with `pkgbuild` (included with Xcode command-line tools). Installs
|
|
binaries to `/usr/local/bin/`, config to `/usr/local/etc/fips/`, sets up
|
|
the `/etc/resolver/fips` DNS resolver for `.fips` domains, and loads a
|
|
launchd daemon. The TUN device is named `utun<N>` (kernel-assigned)
|
|
rather than `fips0`.
|
|
|
|
```sh
|
|
# Build
|
|
make pkg
|
|
|
|
# Install
|
|
sudo installer -pkg deploy/fips-<version>-macos-<arch>.pkg -target /
|
|
|
|
# Remove
|
|
sudo packaging/macos/uninstall.sh
|
|
```
|
|
|
|
### FreeBSD (`.pkg`)
|
|
|
|
Built natively on a FreeBSD host with `pkg create`. Ships `fips`,
|
|
`fipsctl`, and `fipstop` (`fips-gateway` is excluded — its NAT backend
|
|
is nftables, Linux-only), rc.d services, and `.fips` DNS integration
|
|
for `local_unbound`, `unbound`, or `dnsmasq`. Config installs
|
|
sample-style under `/usr/local/etc/fips/` (edits survive upgrades).
|
|
|
|
```sh
|
|
# Build (on FreeBSD; this Makefile needs GNU make — pkg install gmake)
|
|
gmake freebsd
|
|
# or directly, no gmake needed:
|
|
./packaging/freebsd/build-pkg.sh
|
|
|
|
# Install
|
|
pkg add ./deploy/fips-<version>-freebsd-<arch>.pkg
|
|
sysrc fips_enable=YES fips_dns_enable=YES
|
|
service fips start
|
|
service fips_dns start
|
|
```
|
|
|
|
See [freebsd/README.md](freebsd/README.md) for host resolver setup and
|
|
field-tested caveats.
|
|
|
|
### pfSense (`.pkg`)
|
|
|
|
pfSense is FreeBSD underneath, but the FreeBSD package does not work
|
|
there, and fails silently in three ways: pfSense boots packages by
|
|
globbing `/usr/local/etc/rc.d/*.sh` (a suffixless rc script is never
|
|
run), it generates `unbound.conf` from `config.xml` and reads no
|
|
`conf.d` directory (the DNS drop-in is never read), and it writes
|
|
`do-ip6: no` unless "Allow IPv6" is enabled (so a responder on `[::1]`
|
|
is unreachable). This package ships `fips.sh`, integrates DNS through
|
|
the DNS Resolver custom options in `config.xml`, and binds the
|
|
responder on `127.0.0.1`.
|
|
|
|
Unlike the other packages, this one **links statically by default**
|
|
(`--dynamic` opts out). pfSense runs a FreeBSD base you cannot
|
|
obtain — Netgate builds Plus from its own 16.0-CURRENT snapshot — so
|
|
a dynamically linked binary can reference a libc symbol the appliance
|
|
does not export, install cleanly, and then refuse to start. A static
|
|
package declares no shared libraries at all.
|
|
|
|
**On aarch64 this is refused, not applied.** A statically linked
|
|
aarch64 FreeBSD binary faults where `posix_spawn` should be, so the
|
|
daemon dies the first time it shells out. ARM builds must pass
|
|
`--dynamic`, and then `ldd` on the appliance is the check that the
|
|
base drift is not real.
|
|
|
|
The build host's architecture must match the target's, and `pkg`
|
|
refuses a mismatched ABI major, so the package carries the target's:
|
|
pfSense CE 2.8.1 is FreeBSD 15 amd64; CE 2.9.0 and Plus 26.x are
|
|
FreeBSD 16 (amd64, plus aarch64 for Plus on ARM appliances). The
|
|
FreeBSD 16 amd64 package is the FreeBSD 15.1 build relabelled
|
|
(`--no-build --abi FreeBSD:16:amd64`): static binaries from an older
|
|
release on a newer kernel is the direction FreeBSD supports, and it has
|
|
been run on Plus 26.03.1 and 26.07. No aarch64 package is published:
|
|
rustup ships no toolchain for aarch64 FreeBSD, so such a build cannot
|
|
honour the `rust-toolchain.toml` pin. It is build-it-yourself.
|
|
|
|
```sh
|
|
# Build (on FreeBSD; this Makefile needs GNU make — pkg install gmake)
|
|
gmake pfsense
|
|
# or directly, no gmake needed:
|
|
./packaging/pfsense/build-pkg.sh
|
|
|
|
# Validate the package before shipping it
|
|
./testing/check-pfsense-pkg.sh deploy/fips-<version>-pfsense-ce2.8-amd64.pkg
|
|
|
|
# Install (on the firewall, as root)
|
|
pkg add ./fips-<version>-pfsense-ce2.8-amd64.pkg
|
|
/usr/local/etc/rc.d/fips.sh start
|
|
/usr/local/libexec/fips/fips-dns-setup # edits config.xml; run deliberately
|
|
```
|
|
|
|
Not a Netgate-supported package. A pfSense firmware upgrade keeps it (it
|
|
is a plain pkg, not a `pfSense-pkg-*`); after a major base change,
|
|
reinstall the package built for the new base. See
|
|
[pfsense/README.md](pfsense/README.md) for the "Allow IPv6" prerequisite
|
|
the mesh depends on, firewall-rule notes, and upgrade and removal
|
|
behaviour.
|
|
|
|
### Windows (`.zip`)
|
|
|
|
A ZIP archive containing binaries, default config, and PowerShell
|
|
service helper scripts. Requires the [wintun](https://www.wintun.net/)
|
|
driver for TUN support.
|
|
|
|
```powershell
|
|
# Build
|
|
make zip
|
|
|
|
# Or directly
|
|
powershell -File packaging/windows/build-zip.ps1
|
|
|
|
# Extract and install as service (requires Administrator)
|
|
Expand-Archive deploy\fips-<version>-windows-x86_64.zip -DestinationPath fips
|
|
cd fips
|
|
powershell -ExecutionPolicy Bypass -File install-service.ps1
|
|
|
|
# Uninstall (preserves config)
|
|
powershell -ExecutionPolicy Bypass -File uninstall-service.ps1
|
|
|
|
# Uninstall and remove config
|
|
powershell -ExecutionPolicy Bypass -File uninstall-service.ps1 -RemoveAll
|
|
```
|
|
|
|
### Arch Linux (AUR)
|
|
|
|
Two AUR packages are maintained: `fips` (release, builds from tagged
|
|
tarball) and `fips-git` (development, builds from latest git master).
|
|
|
|
```sh
|
|
# Build and validate locally (git variant)
|
|
make aur
|
|
|
|
# Install from AUR
|
|
yay -S fips-git # development build from master
|
|
yay -S fips # release build from latest tag
|
|
```
|
|
|
|
See [aur/README.md](aur/README.md) for AUR publication instructions
|
|
and maintainer guide.
|
|
|
|
### Nix / NixOS (flake)
|
|
|
|
A [flake](../flake.nix) at the project root builds all four binaries
|
|
(`fips`, `fipsctl`, `fips-gateway`, `fipstop`) from source. It pins the
|
|
exact toolchain from `rust-toolchain.toml` via
|
|
[fenix](https://github.com/nix-community/fenix) and wires up the
|
|
build-time native dependencies (`libclang` for `bindgen`, plus `dbus`
|
|
and `pkg-config` for BLE), so it needs no system setup beyond Nix with
|
|
flakes enabled.
|
|
|
|
```sh
|
|
nix build .#fips # build the package (all four binaries)
|
|
nix run .#fips -- --help # run a binary directly
|
|
nix run .#fipsctl -- show status
|
|
nix develop # dev shell with the pinned toolchain + cargo-edit
|
|
nix flake check # build + validate the flake
|
|
```
|
|
|
|
The flake also exposes:
|
|
|
|
- `overlays.default` — adds `pkgs.fips` to nixpkgs
|
|
- `nixosModules.default` — a NixOS module (`packaging/nixos/`) that provides
|
|
`services.fips.enable` and runs the daemon as a systemd service
|
|
|
|
**As a package only** (no service management):
|
|
|
|
```nix
|
|
environment.systemPackages = [ fips.packages.${system}.default ];
|
|
```
|
|
|
|
**As a managed NixOS service** (recommended — starts on boot, journalctl logs):
|
|
|
|
```nix
|
|
# flake.nix
|
|
{
|
|
inputs.fips = {
|
|
url = "github:jmcorgan/fips";
|
|
inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
|
|
outputs = { self, nixpkgs, fips, ... }@inputs: {
|
|
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
|
|
system = "x86_64-linux";
|
|
specialArgs = { inherit inputs; };
|
|
modules = [
|
|
./configuration.nix
|
|
fips.nixosModules.default
|
|
{ services.fips.enable = true; }
|
|
];
|
|
};
|
|
};
|
|
}
|
|
```
|
|
|
|
See [`packaging/nixos/README.md`](nixos/README.md) for the full option
|
|
reference (`services.fips.enable`, `.package`, `.configFile`,
|
|
`.openFirewall`).
|
|
|
|
## Shared Assets
|
|
|
|
`common/` contains assets used across packaging formats:
|
|
|
|
- `fips.yaml` — default configuration (ephemeral identity, UDP/TCP/TUN/DNS)
|
|
- `hosts` — static hostname-to-npub mappings for `.fips` DNS resolution
|