# WireGuard mesh between hives (optional) The peer config in [the hive directory](hive-directory.md#hive-identity-config) uses public HTTPS for all inter-hive traffic. For private deployments — or to reduce latency and TLS overhead on intra-swarm traffic — hyperhive can configure a host-to-host WireGuard mesh. ## Generating keys On each hive host: ```bash wg genkey | install -m 0400 /dev/stdin /etc/wireguard/hive.key wg pubkey < /etc/wireguard/hive.key # → share this with peer operators ``` ## Config example (two hives) ```nix # hive A (firsthive.myswarm.example, mesh IP 10.100.0.1) services.hyperhive = { deploy.wireguard = { enable = true; privateKeyFile = "/etc/wireguard/hive.key"; address = "10.100.0.1/24"; listenPort = 51820; # optional, default 51820 }; # The same `hives` attrset both hosts hold — mesh fields included, # since "where this hive can be dialled" is a fact about that hive. swarm.hives = { firsthive = { domain = "firsthive.myswarm.example"; wireguardPublicKey = "base64keyA="; wireguardEndpoint = "198.51.100.1:51820"; wireguardAddress = "10.100.0.1/32"; }; secondhive = { domain = "secondhive.elsewhere.example"; wireguardPublicKey = "base64keyB="; wireguardEndpoint = "203.0.113.42:51820"; wireguardAddress = "10.100.0.2/32"; }; }; }; # hive B (secondhive.elsewhere.example, mesh IP 10.100.0.2) services.hyperhive = { deploy.wireguard = { enable = true; privateKeyFile = "/etc/wireguard/hive.key"; address = "10.100.0.2/24"; }; swarm.hives = { # … identical to hive A's … }; }; ``` ## What the mesh does - hyperhive configures `networking.wireguard.interfaces.wg-hive` on the host (not inside agent containers; containers reach peers via the host's routing table). - It opens UDP port 51820 (or `listenPort`) on the host firewall. - It reads each entry's `wireguardAddress` from `services.hyperhive.swarm.hives`, minus this host's own hive, to build `wg-hive`'s `allowedIPs`, so intra-swarm traffic can route over the mesh address rather than the public domain. - It sets `persistentKeepalive = 25` by default; override or null to disable (not needed when both sides have public IPs and no NAT). ## NAT / one-sided endpoints If one host is behind NAT and can't accept incoming connections, only that host needs a null `wireguardEndpoint` on the peer config — the other side initiates. With keepalive on, the NAT hole stays open. If both hosts are behind NAT, you need a STUN relay or a third host (exit node); hyperhive sets up neither.