Skip to content

Overview

cerberd runs on a Linux WireGuard hub. One binary is both the daemon and its CLI. Spokes (MikroTik routers, laptops, phones) run no cerber code.

┌──────────── hub ────────────┐
CLI ──unix──► │ cerberd ──► wg0.db (SQLite) │
API ──TCP───► │ │ │
│ ├─► wg0 (wgctrl + ip) │
│ └─► RouterOS REST ───────┼──► spokes
└─────────────────────────────┘
  1. Owns the hub interface. It creates wg0, sets its key, port, MTU and address, and adds and removes peers and their routes. It applies per-peer diffs, never a wholesale replace, and repairs drift every few seconds.
  2. Keeps a peer database. Names, reserved IPs, private and public keys, blocked state, tags and router bindings live in SQLite. The CLI and the HTTP API are the only ways to change them.
  3. Builds direct links between RouterOS spokes over their REST API, on top of the hub path. Links are manual for now (cerberd link up a b); tag-based automatic links come later.

One instance per hub interface, like wg-quick. The interface name ties everything together:

wg0 instance
systemd unit cerberd@wg0
config (YAML) /etc/cerberd/wg0.yaml
database /var/lib/cerberd/wg0.db
API socket /run/cerberd/wg0.sock

See Files and paths for the full list.

  • Forwarding doesn’t depend on cerberd. Stopping, restarting or crashing the daemon leaves wg0 up with all its peers. On start it adopts the live interface and reconciles; there is no flap. Only cerberd down deletes it.
  • One writer. Only cerberd writes wg0. Don’t run wg-quick@wg0 or WGDashboard on the same interface.
  • Blast-radius guard. A reconcile that would cut more than hub.max_removals peers (or routes) off the hub changes nothing and is reported. A wrong or empty database can’t empty the hub.
  • Only tagged router objects. On routers cerberd only touches objects it created (comment=cerber:..., name=cerber-...). It never modifies the spoke’s hub peer or anything untagged.
  • Out of scope: IP forwarding, firewall and NAT. They belong in the host configuration (nftables, sysctl.d), independent of wg0.
Term Meaning
peer a database record: a name, a key pair (or just the public key), and its IPs
overlay address a peer’s /32 inside hub.overlay. The first one is primary
LAN at most one /24 per peer inside hub.lan_space, routed to that peer
blocked kept in the database with its keys and addresses, but off wg0
node a peer with a router binding: cerberd may drive its router and build direct links
foreign peer a peer on wg0 that the database doesn’t know
direct link a WireGuard peer between two spokes’ routers, so their traffic skips the hub
  • Spokes that get direct links must be RouterOS v7 routers. Any WireGuard client works as a plain peer.
  • Direct links are made by hand (cerberd link up). They aren’t stored in the database: after a restart, cerberd adopts the healthy ones it finds on the routers and removes the rest.
  • IPv4 only for overlay and LAN addresses.