# FIPS Packaging

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

## Quick Start

```sh
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 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.

```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 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

```text
packaging/
  aur/            Arch Linux AUR packaging (PKGBUILD, supporting files)
  common/         Shared assets (default config, hosts file)
  debian/         Debian/Ubuntu .deb packaging via cargo-deb
  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](https://github.com/kornelski/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.

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

```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. Supports aarch64, mipsel, mips, arm, and x86\_64 targets.

```sh
# Build (default: aarch64)
make ipk

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

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
```

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

```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 -- 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
