Preparing to run ferrix next to BIRD on the production router. - build: the config proto is now parsed in pure Rust, so building needs no `protoc` binary. It previously worked only where one happened to be installed; the Dockerfile in this repo could not have built. - peers gain `local_address`, the source IP for connections we open (and therefore the next hop we advertise). When both speakers share a host the OS would otherwise pick an arbitrary local address and the peer, which identifies us by address, would refuse the session. Address-family mismatches are rejected at config load; an address the host lacks shows up as the peer's backoff reason. - docs/lab/prod/on-router: static musl cross-build instructions, config, hardened systemd unit (unprivileged, SIGTERM gives BIRD a Cease), loopback addresses for networkd, the BIRD stanza for a same-host multihop session, and reverse-proxy examples with TLS and a password, since the API has no authentication. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2.6 KiB
Running ferrix_bgp on the production router
ferrix and BIRD run side by side on pr01 and peer over two loopback addresses. Students reach the status page through a reverse proxy that adds TLS and a password. Nothing here has been run on the router; treat each step as something to check.
1. Build a static Linux binary (on the Mac)
The x86_64-unknown-linux-musl target and Homebrew's musl cross-linker are
enough; the router needs no Rust toolchain and no protoc.
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-linux-musl-gcc \
cargo build --release -p bgp --target x86_64-unknown-linux-musl
scp target/x86_64-unknown-linux-musl/release/bgp pr01:/tmp/ferrix-bgp
Check the router really is x86-64 first (uname -m).
2. Install on the router
install -m 0755 /tmp/ferrix-bgp /usr/local/bin/ferrix-bgp
install -d /etc/ferrix-bgp
install -m 0644 ferrix.textpb /etc/ferrix-bgp/ferrix.textpb
install -m 0644 ferrix-bgp.service /etc/systemd/system/ferrix-bgp.service
3. Loopback addresses
Merge 05-lab-lo.network into the networkd file that matches lo, then
networkctl reload and confirm with ip -6 addr show dev lo.
4. BIRD
Replace the protocol bgp ferrix stanza with bird-ferrix-local.conf, then
birdc configure check and birdc configure timeout 300 / confirm.
5. Start
systemctl daemon-reload
systemctl enable --now ferrix-bgp
journalctl -u ferrix-bgp -f
birdc show protocols all ferrix
6. Let students in
The API has no authentication and announces into a real AS, so do not expose port 8080. Put a reverse proxy in front with TLS and a class password. The event stream is long-lived, so the proxy must not buffer it.
Caddy:
lab.example.net {
basic_auth {
student <hash from `caddy hash-password`>
}
reverse_proxy 127.0.0.1:8080 {
flush_interval -1
}
}
nginx, inside a TLS server block:
location / {
auth_basic "BGP lab";
auth_basic_user_file /etc/nginx/lab.htpasswd;
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 1h;
}
Restricting the proxy to the university's address ranges as well is cheap and worth doing.
Things to know
- Announced routes live in memory. A restart of the service forgets them and students have to announce again.
- Stopping the service sends BIRD a Cease first, so restarts reconnect at once.
- ferrix's own safety net is
local_route_policy; BIRD's import filter and import limit are the second one. Keep both.