WireGuard configs come in pairs and the two halves have to agree. Set the tunnel up once here and get both files, plus the key commands and the forwarding rules.
The name misleads almost everyone. On a peer, AllowedIPs says which destinations get sent through the tunnel: 0.0.0.0/0 routes everything, a LAN subnet routes only that. On the server, the same field says which source addresses that peer is permitted to use, and it is how WireGuard decides which peer a packet belongs to. Two peers cannot share an address. If traffic is not flowing, AllowedIPs is where to look first.
This WireGuard config generator produces both halves of a working tunnel: a server wg0.conf with a peer block per client, and a client config with the right AllowedIPs for a full VPN or a split tunnel. It includes nftables masquerade rules for gateway mode, the ip_forward setting people forget, PersistentKeepalive for peers behind NAT, and the wg genkey commands to create the keypairs.
You generate them yourself, and the placeholders mark where each goes. Run umask 077 first so the private keys are not world readable, then wg genkey | tee server.key | wg pubkey > server.pub for each side. Never paste a private key into a peer config; each side holds its own private key and the other side’s public key.
Two usual causes. IP forwarding is off, so the server will not route between interfaces: set net.ipv4.ip_forward=1. Or there is no NAT rule, so replies from the internet have nowhere to return to: the masquerade rule in PostUp handles that. Check both before suspecting the tunnel.
A peer behind NAT has no reachable address until it sends something, and the NAT mapping expires after a period of silence. Sending a small packet every 25 seconds keeps the mapping alive so the server can initiate traffic. Set it on the peer behind NAT, not on the publicly reachable server.
Yes, UDP on your listen port, 51820 by default. WireGuard is UDP only. If you use ufw the rule is ufw allow 51820/udp, and the ufw rule builder has it as a preset.