Clean sweep — no kill on the Colibri wire protocol, CLI surface, TUI keybinding, or documentation. Backward-compat aliases removed; daemon and client deploy together so no transitional period needed. Wire: KillAgent→StopAgent, "kill-agent"→"stop-agent" (no alias) CLI: colibri kill→stop, Command::KillAgent→StopAgent Lib: client.kill_agent()→stop_agent() TUI: kill_selected()→stop_selected(), "kill"→"stop" label Docs: spawn/kill→spawn/stop, kill-agent→stop-agent (40+ instances) Retained kill only where it belongs: - child.kill() / handle.kill() (OS SIGKILL) - Unix kill(1) in sigterm tests - OOM kill, process-group kill comments (kernel mechanism) |
||
|---|---|---|
| .. | ||
| colibri-bridge.env.example | ||
| colibri-bridge.nft | ||
| colibri-bridge.service | ||
| README.md | ||
Colibri bridge — Linux (systemd)
Linux/systemd peer of packaging/freebsd/colibri_bridge.in. Exposes the
colibri-daemon control-plane Unix socket as a TCP port on the Tailscale
interface only, so other mesh hosts can drive the control plane.
The FreeBSD bridge already runs on hermes (binds hermes's own tailnet address);
this is the matching domedog side. The network gate (ufw) is already applied
on domedog (see "domedog host facts"); the systemd unit here is the proposed
service — review the open questions with hermes before enable --now.
Real
100.xTailscale addresses are never committed to git. Each host's address is supplied at deploy time (tailscale ip -4) via/etc/colibri/bridge.env— seeCOLIBRI_BRIDGE_LISTEN_ADDR=TAILSCALE_IP_REQUIRED.
Files
| File | Purpose |
|---|---|
colibri-bridge.service |
systemd unit running socat (peer of the rc.d script) |
colibri-bridge.env.example |
tunables — install to /etc/colibri/bridge.env |
colibri-bridge.nft |
nftables ruleset for hosts without ufw (see facts below) |
Install (one-time, as root)
install -D -m 0644 packaging/linux/colibri-bridge.service \
/etc/systemd/system/colibri-bridge.service
install -D -m 0644 packaging/linux/colibri-bridge.env.example \
/etc/colibri/bridge.env # then edit for this host
# Firewall: scope port 9190 to tailscale0 (peer of the hermes pf rule).
# domedog runs ufw (active, default-deny input) — the allow goes in ufw, and
# ufw's default-deny already blocks 9190 on every other interface:
ufw allow in on tailscale0 to any port 9190 proto tcp comment 'colibri-bridge'
# On a host WITHOUT ufw / with a default-accept input, use the nft table instead:
# install -D -m 0644 packaging/linux/colibri-bridge.nft /etc/colibri/colibri-bridge.nft
# nft -f /etc/colibri/colibri-bridge.nft
systemctl daemon-reload
systemctl enable --now colibri-bridge.service
systemctl status colibri-bridge.service
Quick check from another tailnet host:
printf '{"cmd":"status"}\n' | nc -w2 "$(tailscale ip -4)" 9190 # run on/against this host
domedog host facts (verified 26.jun.2026)
The networking reality this packaging assumes, recorded so the next person doesn't have to re-derive it:
- Tailnet IPv4: each host has a distinct
100.xaddress — get it withtailscale ip -4(not committed to git per policy). - Init / service mgr: systemd (Ubuntu 24.04). FreeBSD/hermes uses rc.d.
- Daemon user:
clawdija(hermes:clawdie). No dedicatedcolibrigroup exists on domedog; the bridge runs as the daemon's own user so it can reach the 0770 socket. - Firewall: ufw active + enabled, default deny (incoming) / allow (outgoing), backed by nftables, with fail2ban on top. Live packet counters confirm it's enforcing, not just configured.
- Currently-allowed inbound ports: 22/tcp (ssh), 80/tcp, 443 (tcp+udp),
8433–8443/tcp, and now 9190/tcp scoped to
tailscale0(the bridge, added for this work). - Port 8443 = CloudPanel server control panel (nginx vhost
cloudpanel.conf, run by theclpuser from/home/clp/services/nginx/). Only 8443 actually listens; 8433–8442 are allowed but unused (range wider than needed). ⚠️ CloudPanel's admin login is exposed to Anywhere (public), not tailnet-scoped — the opposite posture from this bridge; flagged for the host-exposure review.
Open questions for the hermes discussion
- The socket has no auth — the tailnet boundary is the auth. With both
hosts bridging the control plane, any tailnet peer that can reach either host
can issue full control-plane commands (
spawn-agent,stop-agent,terminal-*). Consider a Tailscale ACL scoping:9190to specific peers. - Socket path parity. Both sides assume
/run/colibri/colibri.sock(FreeBSD:/var/run/colibri/colibri.sock). domedog's daemon must be started with a matchingCOLIBRI_DAEMON_SOCKET; the daemon's default is under$XDG_DATA_HOME, which the bridge can't see underProtectHome=yes. - CloudPanel public exposure (8443) — decide whether to keep it public or move it behind the tailnet like the bridge.
Notes
- The FreeBSD
colibri_bridge.inhealth/statusblock bug (scrambled function definitions) was fixed and pushed on the hermes side during this work. colibri-bridge.nftis retained for hosts with a default-accept input chain; on a ufw host itsacceptis not reliable (ufw'sdropis terminal across base chains) and itsdropis redundant (ufw already default-denies). Kept as documentation of intent and for the no-ufw case.