Files
fips/packaging
Johnathan Corgan 7adcd851b7 Merge the deployed-line comment sweep and key-material work
Carries the comment sweep, the key-material clearing, and the two
constant-reconciliation commits up from master. Two of the five items on
that line are deliberately excluded, and most of the resolution work was
keeping them out.

Excluded, and why:

- The frame-length validation does not come. This branch needs its own
  design for msg2 and msg3 rather than an extra arm, and that work is
  sequenced separately. It arrived silently in four files that merged
  without a conflict, so it was removed from each: the reject variant,
  the stats counter, the wire helper and its tests, and the receive-path
  call site with the dispatch visibility widening its tests wanted.
  Landing only the counters would have left a metric that reports zero
  forever with nothing able to increment it.
- The post-handshake identity confirmation does not come, and cannot.
  The older lines run a pattern that learns the initiator's static key at
  message 1; this branch does not learn it until message 3, so there is
  no identity to confirm at that point and no insertion point for the
  check. Its type, its classifier and its confirmation block all
  conflicted and were resolved to this branch's side, but two further
  pieces auto-merged with no conflict and had to be removed by hand: the
  module visibility widening, and the classifier call site.
- The transport framing constants are not re-sourced here. This branch
  has rewritten that whole block: message 1 is a different size, message
  2 and message 3 are minimums rather than exact values, and the version
  gate is a different version. Taking the incoming side would have
  sourced a minimum from an exact value.

Carried, with adaptation where the patterns differ:

- Key-material clearing applies to this branch's own handshake, which is
  XX at both layers rather than IK and XK. The incoming code could not be
  taken as written, since it carries whole method bodies for patterns
  this branch does not use. The erasing guard, the parameter erase in
  both constructors, and the clearing of each Diffie-Hellman output and
  secret-key copy were applied to this branch's own sites instead.
- The security and session-layer documents keep this branch's pattern
  names and gain the correction about the handshake AEAD, which passes
  an empty associated-data field here too.
- The drain-window test needed this branch's optional-identity
  constructor, since an anonymous dial is a first-class case here.
2026-08-16 18:08:57 +00:00
..
2026-08-13 15:57:32 +00:00
2026-07-23 03:03:05 +00:00

FIPS Packaging

This directory contains packaging for all supported target platforms. All build outputs go to deploy/ at the project root.

Quick Start

make deb        # Debian/Ubuntu .deb
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 zip        # Windows .zip package
make all        # deb + tarball (default)

Build Prerequisites

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.

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 support is optional and, when building with it, additionally needs bluez, libdbus-1-dev, and pkg-config; the build picks up BLE if those are present and skips it cleanly if not.

Directory Structure

packaging/
  aur/            Arch Linux AUR packaging (PKGBUILD, supporting files)
  common/         Shared assets (default config, hosts file)
  debian/         Debian/Ubuntu .deb packaging via cargo-deb
  freebsd/        FreeBSD .pkg packaging via pkg-create(8)
  macos/          macOS .pkg installer via pkgbuild
  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. Installs 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.

# Build
make deb

# Install
sudo dpkg -i deploy/fips_<version>_<arch>.deb

# Remove (preserves config and keys)
sudo dpkg -r fips

# Purge (removes config and identity keys)
sudo dpkg -P fips

systemd Tarball

A self-contained tarball with binaries and an install.sh script for any systemd-based Linux distribution.

# 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 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. Supports aarch64, mipsel, mips, arm, and x86_64 targets.

# Build (default: aarch64)
make ipk

# Build for a specific architecture
bash packaging/openwrt-ipk/build-ipk.sh --arch mipsel

See 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.

# 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 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.

# 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).

# 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 for host resolver setup and field-tested caveats.

Windows (.zip)

A ZIP archive containing binaries, default config, and PowerShell service helper scripts. Requires the wintun driver for TUN support.

# 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 -File install-service.ps1

# Uninstall (preserves config)
powershell -File uninstall-service.ps1

# Uninstall and remove config
powershell -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).

# 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 for AUR publication instructions and maintainer guide.

Nix / NixOS (flake)

A flake 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 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.

nix build .#fips          # build the package (all four binaries)
nix run .#fips -- --help  # run a binary directly
nix run .#fipsctl -- status
nix develop               # dev shell with the pinned toolchain + cargo-edit
nix flake check           # build + validate the flake

Add to a NixOS configuration via the flake's packages.<system>.fips output, e.g. environment.systemPackages = [ fips.packages.${system}.default ];.

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