Linux peer of packaging/freebsd/colibri_bridge.in: bridge the colibri-daemon control-plane Unix socket to TCP 9190 on the Tailscale interface so mesh hosts can reach the control plane. - colibri-bridge.service: systemd unit running socat under sandboxing, BindsTo the daemon, freebind so it can bind the tailnet IP before tailscaled is up. - colibri-bridge.env.example: tunables (systemd parallel to the rc.d sysrc vars). - colibri-bridge.nft: nftables ruleset for hosts WITHOUT ufw. - README: install steps + the verified domedog host facts (tailnet IP, ufw default-deny posture, 8443=CloudPanel and its public exposure) + open questions for the cross-host (hermes) review. Network gate already applied on domedog: `ufw allow in on tailscale0 to any port 9190 proto tcp`. The systemd unit is proposed pending the hermes review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
2.7 KiB
Desktop File
66 lines
2.7 KiB
Desktop File
[Unit]
|
|
# Colibri control-plane TCP bridge — Linux/systemd peer of the hermes rc.d
|
|
# service in packaging/freebsd/colibri_bridge.in.
|
|
#
|
|
# Bridges the colibri-daemon Unix socket to a TCP port on the Tailscale
|
|
# interface so other mesh hosts can reach the Colibri control plane. socat runs
|
|
# in the foreground; systemd supervises it (restart on crash, journald logs) —
|
|
# the systemd equivalent of FreeBSD running socat under daemon(8).
|
|
Description=Colibri control-plane TCP bridge (Tailscale -> Unix socket)
|
|
Documentation=https://code.smilepowered.org/clawdie/colibri
|
|
After=network-online.target tailscaled.service colibri-daemon.service
|
|
Wants=network-online.target
|
|
# Ordering + lifecycle: the bridge is useless without the daemon, and the
|
|
# socket vanishes if the daemon stops — so bind our lifecycle to it.
|
|
Requires=colibri-daemon.service
|
|
BindsTo=colibri-daemon.service
|
|
# Keep retrying while we wait for tailscaled to assign the address at boot
|
|
# (paired with freebind below, this race is largely moot, but be forgiving).
|
|
StartLimitIntervalSec=0
|
|
|
|
[Service]
|
|
Type=exec
|
|
# Must be a user in the colibri-daemon socket's group (the daemon chmods its
|
|
# socket 0770 owner+group). On domedog that is the daemon's own user.
|
|
User=clawdija
|
|
Group=clawdija
|
|
|
|
# Tunables live here (systemd parallel to the rc.d sysrc vars). See
|
|
# colibri-bridge.env.example.
|
|
EnvironmentFile=/etc/colibri/bridge.env
|
|
|
|
# Refuse to start until the daemon socket actually exists, mirroring the rc.d
|
|
# prestart check (clearer failure than a socat connect error).
|
|
ExecStartPre=/usr/bin/test -S ${COLIBRI_BRIDGE_SOCKET}
|
|
|
|
# bind=<tailscale-ip> keeps us off every other interface even if the firewall
|
|
# is flushed. freebind (Linux IP_FREEBIND, no privilege needed) lets socat bind
|
|
# the tailnet address before tailscaled has finished bringing it up, avoiding a
|
|
# boot-order race — the one place this unit improves on the FreeBSD version.
|
|
ExecStart=/usr/bin/socat -d \
|
|
TCP-LISTEN:${COLIBRI_BRIDGE_LISTEN_PORT},bind=${COLIBRI_BRIDGE_LISTEN_ADDR},freebind,fork,reuseaddr \
|
|
UNIX-CONNECT:${COLIBRI_BRIDGE_SOCKET}
|
|
Restart=on-failure
|
|
RestartSec=2
|
|
|
|
# --- hardening: socat needs only TCP + Unix sockets and no privileges ---
|
|
NoNewPrivileges=yes
|
|
ProtectSystem=strict
|
|
# ProtectHome=yes is safe ONLY while the socket lives outside /home (it does, by
|
|
# default, under /run). If you repoint COLIBRI_BRIDGE_SOCKET into a home dir,
|
|
# relax this to read-only or the connect will fail.
|
|
ProtectHome=yes
|
|
PrivateTmp=yes
|
|
PrivateDevices=yes
|
|
ProtectControlGroups=yes
|
|
ProtectKernelModules=yes
|
|
ProtectKernelTunables=yes
|
|
RestrictAddressFamilies=AF_INET AF_UNIX
|
|
RestrictNamespaces=yes
|
|
LockPersonality=yes
|
|
MemoryDenyWriteExecute=yes
|
|
SystemCallFilter=@system-service
|
|
SystemCallErrorNumber=EPERM
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|