mirror of
https://github.com/jmcorgan/fips.git
synced 2026-10-05 19:18:25 +00:00
The shipped fips.yaml comment and the package README told users to bind physical port names and never a bridge name such as br-lan, while the shipped lan entry itself binds br-lan. A lab test settled which is right: with a two-member Linux bridge, a socket on br-lan forms links and carries traffic, while a socket on a bridge member port sends frames but never forms a link, because the bridge takes the frames that arrive on its members. br_netfilter does not change that, unloaded or loaded with its call hooks off or on. Correct the comment and the README rule to say: bind the LAN bridge, never one of its member ports; ports outside any bridge bind by their own name. Which ports the bridge holds depends on the board (on x86/64 OpenWrt eth0 is the LAN port and eth1 the WAN port), so the README describes the members by board type and points at `bridge link`, which lists them. A DSA switch with hardware bridge offload was not covered and needs a check on a router. fips-bridge.conf, the package Makefile, 90-fips-setup and the README said kmod-br-netfilter is needed for the Ethernet transport to receive frames on bridge member ports. They now say what the module and the sysctl file actually do (load br_netfilter with its IP, IPv6 and ARP call hooks off) and that they do not make member ports usable. The dependency, the sysctl file and the module load are kept as shipped; their removal waits on a check on a router. The shipped configuration is unchanged.
262 lines
8.6 KiB
Markdown
262 lines
8.6 KiB
Markdown
# FIPS OpenWrt Package
|
|
|
|
This directory is an OpenWrt feed package that builds and installs FIPS on any
|
|
OpenWrt 22.03+ router via the standard `opkg` package system.
|
|
|
|
## Package contents
|
|
|
|
| Installed path | Purpose |
|
|
|---|---|
|
|
| `/usr/bin/fips` | Mesh daemon |
|
|
| `/usr/bin/fipsctl` | CLI control tool (`fipsctl show peers`, `fipsctl show links`, …) |
|
|
| `/usr/bin/fipstop` | Live TUI dashboard |
|
|
| `/usr/bin/fips-gateway` | Outbound LAN gateway service (not started by default) |
|
|
| `/usr/bin/fips-mesh-setup` | Opt-in helper — creates an open 802.11s mesh interface for router↔router backhaul |
|
|
| `/usr/bin/fips-ap-setup` | Opt-in helper — creates the open `!FIPS` access SSID for client devices |
|
|
| `/etc/init.d/fips` | procd service for the daemon (auto-start, crash respawn) |
|
|
| `/etc/init.d/fips-gateway` | procd service for the gateway (disabled by default) |
|
|
| `/etc/fips/fips.yaml` | Node configuration (edit before first start) |
|
|
| `/etc/fips/firewall.sh` | Firewall helper — accepts traffic on `fips0` |
|
|
| `/etc/sysctl.d/fips-bridge.conf` | Turns off `br_netfilter`'s firewall call hooks |
|
|
| `/etc/sysctl.d/fips-gateway.conf` | `proxy_ndp` and IPv6 forwarding for the gateway |
|
|
| `/etc/hotplug.d/net/99-fips` | Applies firewall rules when `fips0` comes up |
|
|
| `/etc/uci-defaults/90-fips-setup` | First-boot kernel module, firewall and dnsmasq `.fips` forwarding setup |
|
|
| `/lib/upgrade/keep.d/fips` | Preserves `/etc/fips/` across `sysupgrade` |
|
|
|
|
## Requirements
|
|
|
|
### Build host
|
|
|
|
| Requirement | Notes |
|
|
|---|---|
|
|
| OpenWrt SDK 22.03+ | Older versions lack fw4 / nftables support |
|
|
| Rust host toolchain | Enable in `make menuconfig` → Advanced → Rust, or install rustup |
|
|
| Rust target for your router | Added automatically by the Makefile via `rustup target add` |
|
|
|
|
### Router
|
|
|
|
| Requirement | Notes |
|
|
|---|---|
|
|
| `kmod-tun` | Required for `fips0` TUN interface |
|
|
| `kmod-br-netfilter` | Loaded, hooks off (`fips-bridge.conf`); see notes below |
|
|
|
|
Both kernel modules are listed as package dependencies (`DEPENDS`) and will be
|
|
installed automatically by `opkg`.
|
|
|
|
## Target architectures
|
|
|
|
The Makefile maps the OpenWrt `ARCH` variable to the correct Rust musl target:
|
|
|
|
| OpenWrt `ARCH` | Rust target |
|
|
|---|---|
|
|
| `aarch64` | `aarch64-unknown-linux-musl` |
|
|
| `x86_64` | `x86_64-unknown-linux-musl` |
|
|
| `mipsel` | `mipsel-unknown-linux-musl` |
|
|
| `mips` | `mips-unknown-linux-musl` |
|
|
| `arm` | `arm-unknown-linux-musleabihf` |
|
|
|
|
To add a missing architecture, add an `ifeq` block in `Makefile` mapping the
|
|
OpenWrt `ARCH` value to the Rust target triple.
|
|
|
|
## Building with the OpenWrt SDK
|
|
|
|
### 1. Obtain the SDK
|
|
|
|
Download the SDK for your router's target from
|
|
[downloads.openwrt.org](https://downloads.openwrt.org) and extract it.
|
|
|
|
### 2. Add this package
|
|
|
|
Copy or symlink this directory into the SDK's `package/` tree:
|
|
|
|
```bash
|
|
# From inside the SDK root:
|
|
ln -s /path/to/fips/packaging/openwrt-ipk package/fips
|
|
```
|
|
|
|
Or add the FIPS repository as a feed in `feeds.conf`:
|
|
|
|
```
|
|
src-git-full fips https://github.com/jmcorgan/fips.git
|
|
```
|
|
|
|
Then update and install feeds:
|
|
|
|
```bash
|
|
./scripts/feeds update fips
|
|
./scripts/feeds install -a -p fips
|
|
```
|
|
|
|
### 3. Build
|
|
|
|
```bash
|
|
make package/fips/compile V=s
|
|
```
|
|
|
|
The resulting `.ipk` is placed in `bin/packages/<arch>/`.
|
|
|
|
Installed on a router, the package enables and starts `fips` and leaves
|
|
`fips-gateway` disabled. Built into a firmware image, it is different: the
|
|
maintainer scripts do nothing at image build time, and the image build enables
|
|
every init script a package ships, `fips-gateway` included. To build an image
|
|
with the gateway off, pass `DISABLED_SERVICES="fips-gateway"` to the image
|
|
builder's `make image`.
|
|
|
|
### 4. Pin the source version
|
|
|
|
For reproducible production builds, replace `PKG_SOURCE_VERSION:=master` in
|
|
`Makefile` with a specific commit SHA and set `PKG_MIRROR_HASH` to the correct
|
|
hash (or keep `skip` for development):
|
|
|
|
```makefile
|
|
PKG_SOURCE_VERSION:=bf117dfabc123... # full 40-char SHA
|
|
PKG_MIRROR_HASH:=skip
|
|
```
|
|
|
|
## Installing on the router
|
|
|
|
```bash
|
|
scp bin/packages/<arch>/fips_0.1.0-1_<arch>.ipk root@192.168.1.1:/tmp/
|
|
ssh root@192.168.1.1 opkg install /tmp/fips_0.1.0-1_<arch>.ipk
|
|
```
|
|
|
|
## First-time configuration
|
|
|
|
Edit `/etc/fips/fips.yaml` on the router before starting the daemon:
|
|
|
|
```bash
|
|
ssh root@192.168.1.1
|
|
vi /etc/fips/fips.yaml
|
|
```
|
|
|
|
The default config enables:
|
|
|
|
- An ephemeral identity, generated on each start. Uncomment
|
|
`node.identity.persistent: true` to keep one; the key is then saved next to
|
|
the config, as `/etc/fips/fips.key`.
|
|
- TUN interface `fips0`
|
|
- DNS responder on `[::1]:5354`
|
|
- UDP transport on `[::]:2121`
|
|
- TCP transport on `0.0.0.0:8443`
|
|
- Ethernet transport, including the `wan`, `wwan` and `lan` entries
|
|
|
|
For Ethernet transport, edit the interface names in the `ethernet:` section to
|
|
match your router. **For the LAN, bind the LAN bridge (`br-lan`), never one of
|
|
its member ports** (on DSA boards `lan1`..`lanN`; on others whichever `ethN` the
|
|
bridge holds; `bridge link` lists them). A socket on a bridge member port sends
|
|
frames but never forms a link, because the bridge takes the frames that arrive
|
|
on its members; loading `br_netfilter` does not change that.
|
|
A lab test with a two-member Linux bridge found this with `br_netfilter`
|
|
unloaded, loaded with its call hooks off, and loaded with them on, while a
|
|
socket on `br-lan` worked both with `br_netfilter` unloaded and with it loaded
|
|
as shipped. Ports outside any bridge bind by their own name. The shipped
|
|
default WAN port is `eth0` (OpenWrt 24); on OpenWrt 25 (DSA) boards the WAN
|
|
port is named `wan`, and the `.apk` package ships that default. Run
|
|
`ip link show` to confirm the names on your board.
|
|
|
|
The lab used software bridges only. A DSA switch with hardware bridge offload
|
|
has not been checked, so confirm the LAN entry forms links on such a router.
|
|
`kmod-br-netfilter`, `fips-bridge.conf` and the module load in `90-fips-setup`
|
|
are kept until their removal has been checked on a router.
|
|
|
|
## Service management
|
|
|
|
```bash
|
|
/etc/init.d/fips start
|
|
/etc/init.d/fips stop
|
|
/etc/init.d/fips restart
|
|
/etc/init.d/fips enable # start at boot (already enabled by opkg postinstall)
|
|
/etc/init.d/fips disable
|
|
```
|
|
|
|
### Outbound LAN gateway (optional)
|
|
|
|
The `fips-gateway` service is installed but disabled by default. It
|
|
turns the router into an outbound gateway that bridges LAN clients
|
|
onto the FIPS mesh. Enable only after configuring a `gateway:`
|
|
section in `/etc/fips/fips.yaml`:
|
|
|
|
```bash
|
|
/etc/init.d/fips-gateway enable
|
|
/etc/init.d/fips-gateway start
|
|
```
|
|
|
|
See `docs/tutorials/deploy-fips-gateway.md` in the source tree for
|
|
the full walkthrough.
|
|
|
|
## Inspection and logs
|
|
|
|
```bash
|
|
# Node-level status overview
|
|
fipsctl show status
|
|
|
|
# Peer table
|
|
fipsctl show peers
|
|
|
|
# Transport links
|
|
fipsctl show links
|
|
|
|
# Active end-to-end sessions
|
|
fipsctl show sessions
|
|
|
|
# Live TUI dashboard
|
|
fipstop
|
|
|
|
# Daemon logs (OpenWrt syslog)
|
|
logread | grep fips
|
|
```
|
|
|
|
See [`docs/reference/cli-fipsctl.md`](../../docs/reference/cli-fipsctl.md)
|
|
for the full subcommand list.
|
|
|
|
## Upgrading
|
|
|
|
OpenWrt 25 and later have no opkg. Upgrade there with the `.apk` package,
|
|
using the same command that installs it:
|
|
|
|
```bash
|
|
apk add --allow-untrusted /tmp/fips_<new-version>_<arch>.apk
|
|
```
|
|
|
|
The `.apk` package's upgrade scripts stop `fips` and `fips-gateway`, start
|
|
`fips` again, and start `fips-gateway` only if it was enabled; see
|
|
[`../openwrt-apk/README.md`](../openwrt-apk/README.md).
|
|
|
|
On OpenWrt 24.10 and earlier, install the new `.ipk` with a plain
|
|
`opkg install`:
|
|
|
|
```bash
|
|
opkg install /tmp/fips_<new-version>_<arch>.ipk
|
|
```
|
|
|
|
opkg runs this as an upgrade. The installed package's `prerm` stops `fips` and
|
|
`fips-gateway` without disabling them, and the new package's `postinst` starts
|
|
`fips` and starts `fips-gateway` again if it was enabled.
|
|
|
|
An upgrade from 0.5.1 or earlier is the exception. The `prerm` in those
|
|
packages disables `fips-gateway` and records nothing about whether it was
|
|
enabled, so the new `postinst` enables it again. If you had the gateway
|
|
disabled, disable it again after that first upgrade:
|
|
|
|
```bash
|
|
/etc/init.d/fips-gateway stop
|
|
/etc/init.d/fips-gateway disable
|
|
```
|
|
|
|
If opkg refuses because the new file's version sorts lower than the installed
|
|
one, as it can between development builds, add `--force-downgrade`. opkg then
|
|
takes the same upgrade path.
|
|
|
|
Do not use `--force-reinstall`. opkg runs it as a removal followed by a fresh
|
|
install, so `fips-gateway` ends up disabled. To turn it back on:
|
|
|
|
```bash
|
|
/etc/init.d/fips-gateway enable
|
|
/etc/init.d/fips-gateway start
|
|
```
|
|
|
|
The config in `/etc/fips/fips.yaml` and the identity key `/etc/fips/fips.key`
|
|
(when persistent identity is on) are preserved by `opkg` (the yaml is installed
|
|
as a conffile; the key is not a package file). Both survive `sysupgrade` via
|
|
`/lib/upgrade/keep.d/fips`.
|