Three related UDP transport changes that together close a real gap in the v0.2.x "this transport accepts inbound" assumption: - outbound_only (default false). When true, the transport binds a kernel-assigned ephemeral port (0.0.0.0:0) regardless of the configured bind_addr, refuses inbound handshakes (Transport trait's accept_connections() returns false), and is never advertised on Nostr regardless of advertise_on_nostr. Lets a node participate in the mesh as a pure client — initiate outbound links without exposing an inbound listener on a known port. Also closes the "loopback bind as outbound-only workaround" trap: a UDP socket bound to 127.0.0.1 pins 127.0.0.1 as the source IP on outbound packets, and Linux refuses to deliver such packets out an external interface — the daemon happily reports "transport started" while no flow ever reaches an external peer. - accept_connections (default true). Mirrors the existing Ethernet/BLE knob. Lets operators run UDP in a "client" posture (initiate outbound, refuse inbound msg1 from new addresses) without switching transport. The Node-level handshake gate already carves out msg1 from peers established on the transport so rekey works on existing sessions. - Startup validation: reject `transports.udp[*].bind_addr` set to a loopback address (127.x.x.x, ::1, localhost) when at least one peer has a non-loopback UDP address. Replaces the silent "peer link won't establish" failure mode with a clear error pointing at the bind misconfiguration. outbound_only is exempt (it overrides bind_addr to 0.0.0.0:0). The is_punch_packet-based filter from the previous commit, the Node-level admission gate landed earlier on master, and these new config fields together cover the three distinct ways the v0.2.x "this transport accepts inbound" assumption could break. Tests: validation truth table (loopback+external rejected, loopback+loopback ok, outbound_only exempt), is_loopback_addr_str helper, accept_connections wiring (default, explicit-false, outbound_only-forces-false), end-to-end ephemeral-bind in the runtime. 1082 tests pass with --features nostr-discovery.
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
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)
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
macos/ macOS .pkg installer via pkgbuild
systemd/ Generic Linux systemd tarball packaging
openwrt/ OpenWrt .ipk packaging via cargo-zigbuild
windows/ Windows .zip package with service scripts
Formats
Debian/Ubuntu (.deb)
Built with cargo-deb. Installs
fips, fipsctl, and fipstop to /usr/bin/, places config at
/etc/fips/fips.yaml (preserved on upgrade), and enables the systemd
service.
# 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)
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/build-ipk.sh --arch mipsel
See openwrt/README.md for router-specific installation instructions.
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
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.
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.fipsDNS resolution