Guide··8 min read

Self-hosted VPN for small teams: what nobody tells you

Davronbek Achilov
Davronbek Achilov
Founder, NexGuard

If you search "self-hosted VPN for teams", every result tells you the same thing: install WireGuard, edit a config, you are done. Tutorials show you how to add three peers. They do not tell you what happens at peer fifteen, or when someone joins remotely from a country where UDP is throttled, or when your office IP changes.

I am going to tell you the things that bit us. This is not theoretical. We ran a hand-rolled WireGuard setup for a 12-person team for two and a half years before building NexGuard.

1. Key rotation is harder than it looks

Conventional wisdom says rotate keys every 6 months. In practice, rotating keys for a remote team means coordinating a window where everyone simultaneously updates their config. We tried a soft rotation (old key valid for a week, new key issued) and it was a mess of edge cases. We rotated keys exactly twice in two years, both times because someone left the team.

If you are not going to actually rotate keys, at least put expiration dates on tokens. JWT-based tokens with "exp" claims solve this — the WireGuard tunnel keeps working but the token to re-authenticate expires.

2. Adding a new server is a rebuild, not an add

The naive WireGuard topology is hub-and-spoke: one server, all peers connect to it. The moment you want a second server (different region, redundancy, whatever), you have to rethink the routing. allowed_ips on every client config has to know about both servers. Mesh routing between servers requires configuring each as a peer of the other. By the time you are running 3 servers with 20 peers, the config files are 200 lines and a single typo in a /32 can route someone's traffic into a black hole.

NexGuard's join-API approach lets servers exchange peer info dynamically. New peer joins server A, all other servers learn about it within seconds. Same for adding a new server.

3. Logging is not optional and is not built in

Default WireGuard logs three things: handshakes, errors, and "connection successful". When someone says "the VPN is slow", you have nothing to show them. No throughput stats per peer. No latency. No record of when they connected.

We added our own metrics layer that exposes per-peer tx/rx bytes, last handshake time, and endpoint changes. This is invisible most of the time but indispensable when something breaks.

4. ISPs sometimes block UDP 51820

This was the bug that drove me to build NexGuard. About 1 in 20 ISPs we encountered would silently rate-limit or block UDP on the default WireGuard port. The connection establishes, then traffic just stops. No error. No timeout. Just zero throughput.

Workarounds: - Move WireGuard to UDP 443 (sometimes works) - Move WireGuard to UDP 53 (DNS port, often less filtered) - Tunnel WireGuard packets over a TCP/TLS connection (always works, slower)

NexGuard does the third by default. The cost is some throughput overhead (maybe 10-15% in our tests) and you lose true peer-to-peer. The benefit is the connection works behind every firewall we have ever tested.

5. Onboarding is the worst part

Adding a new person to a hand-rolled WireGuard setup involves: SSH to server, generate a key pair, add peer to config, restart interface, send the new person their private key (over a secure channel — email is wrong, Signal is right), walk them through installing WireGuard, walk them through importing the config, troubleshoot when their machine has weird firewall rules.

Best case 10 minutes. Worst case half an hour. Times every new hire and every time someone gets a new laptop.

The fix is: make the only thing the user needs to do is paste a token. Everything else (keys, config, NAT setup) happens automatically. This is the whole reason NexGuard's GUI client exists — paste token, click connect, you are on the network.

6. Mobile devices are second-class everywhere

The official WireGuard app on iOS and Android is great, but giving someone a config file via QR code does not scale beyond 10 devices. And mobile devices roam between networks, so handshakes timeout and reconnect frequently. WireGuard handles this well at the protocol level, but the apps' battery usage when reconnecting frequently is noticeable.

This is the area where Tailscale is still ahead. Their mobile apps are excellent. We are working on ours but it is going to take time.

7. Compliance and audit logs

Once you start having actual customers, someone is going to ask "who accessed the production database VPN at 3am on March 4?". With raw WireGuard, you have no answer. You need to build audit logging.

Our audit log records: peer joins, peer leaves, key rotations, ACL rule changes, admin actions. Boring until you need it. Critical when you need it.

The takeaway

I am not saying do not self-host WireGuard. We did it for years and it worked, mostly. But if you are doing it because you think it will be simple, brace yourself. The simple part is the first three peers. Everything after that is engineering work.

If you do not want to do that engineering work, that is what NexGuard exists for. We did the work so you do not have to. Self-hosted, free for 5 devices, paid plans start at $9/month for one server with 50 devices. If you want more control than a SaaS gives you but less work than rolling your own, we are probably the right fit.