feat: WireGuard VPN on cum-services with wg-access-server #21

Closed
marti wants to merge 3 commits from feature/wireguard-vpn into main
Owner

Adds a WireGuard VPN to cum-services, managed through a web console at vpn.cumsek.com.

What

  • wg-access-server via the nixpkgs NixOS module. No containers. Works with the stock WireGuard apps: sign in, add a device, scan the QR code or download the config.
  • Peers are stored in a new wg_access_server database on the existing Postgres, provisioned like the other databases (ensureDBOwnership and a sops-managed password).
  • Secrets (admin password, server private key, session secret, DB password) live in .secrets.yaml and are merged into the config through a sops template.
  • vpn.cumsek.com is generated from cum.nix, so it gets an nginx vhost, an ACME cert and a dashboard card. Port 8000 stays closed in the firewall; the console is only reachable through nginx.
  • Clients get 10.44.0.0/24, a full tunnel NATed out of ens18 (LAN and internet), and DNS through the server. IPv6 is dropped in the tunnel because the LAN is IPv4-only.

Before deploying

The wildcard *.cumsek.com record is proxied by Cloudflare, which cannot carry UDP. Peers therefore connect to wg.cumsek.com. You need to:

  1. Create wg.cumsek.com as a DNS only (grey cloud) A record pointing at the home IP.
  2. Forward UDP 51820 on the router to 192.168.1.201.

The admin login is admin; the password is wg_access_server.admin_password in cum secrets.

If cloudflare-warp on this host runs in full-tunnel mode, it may route VPN replies through WARP. Check this first if clients connect but no traffic passes.

Testing

  • nixosConfigurations.cum-services builds.
  • Ran a throwaway NixOS VM test with the same settings against Postgres 18: admin login works, adding a device writes the row to Postgres and adds the peer to wg0, and the forward and masquerade rules get installed.
  • Not deployed to the real host yet.

🤖 Generated with Claude Code

Adds a WireGuard VPN to cum-services, managed through a web console at `vpn.cumsek.com`. ## What - **wg-access-server** via the nixpkgs NixOS module. No containers. Works with the stock WireGuard apps: sign in, add a device, scan the QR code or download the config. - Peers are stored in a new `wg_access_server` database on the existing Postgres, provisioned like the other databases (`ensureDBOwnership` and a sops-managed password). - Secrets (admin password, server private key, session secret, DB password) live in `.secrets.yaml` and are merged into the config through a sops template. - `vpn.cumsek.com` is generated from `cum.nix`, so it gets an nginx vhost, an ACME cert and a dashboard card. Port 8000 stays closed in the firewall; the console is only reachable through nginx. - Clients get `10.44.0.0/24`, a full tunnel NATed out of `ens18` (LAN and internet), and DNS through the server. IPv6 is dropped in the tunnel because the LAN is IPv4-only. ## Before deploying The wildcard `*.cumsek.com` record is proxied by Cloudflare, which cannot carry UDP. Peers therefore connect to `wg.cumsek.com`. You need to: 1. Create `wg.cumsek.com` as a **DNS only** (grey cloud) A record pointing at the home IP. 2. Forward **UDP 51820** on the router to `192.168.1.201`. The admin login is `admin`; the password is `wg_access_server.admin_password` in `cum secrets`. If `cloudflare-warp` on this host runs in full-tunnel mode, it may route VPN replies through WARP. Check this first if clients connect but no traffic passes. ## Testing - `nixosConfigurations.cum-services` builds. - Ran a throwaway NixOS VM test with the same settings against Postgres 18: admin login works, adding a device writes the row to Postgres and adds the peer to `wg0`, and the forward and masquerade rules get installed. - Not deployed to the real host yet. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Provisions the database and role the VPN console stores peers in, plus
its admin password, WireGuard server key and session secret. The role
password is hex because wg-access-server rebuilds its storage URL into
an unquoted libpq key=value string.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
wg-access-server is in nixpkgs with a NixOS module, works with stock
WireGuard clients, and can keep its peers in Postgres. The console sits
behind nginx at vpn.cumsek.com. The WireGuard endpoint is wg.cumsek.com
because the wildcard record is proxied by Cloudflare, which cannot carry
UDP.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
marti closed this pull request 2026-10-30 10:33:59 +01:00

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
cumsek/nix!21
No description provided.