Most guides answer "how do I add a WireGuard peer?" with wg-quick down wg0 && wg-quick up wg0. That works, and it also disconnects everyone currently using the tunnel in order to add one line to a file. On a server with a handful of clients it is a brief annoyance. On a server you actually rely on, it is the reason people avoid adding peers at all.
There is a command that does it live.
How do you add a peer to WireGuard?
One line, on the running interface:
wg set wg0 peer <CLIENT_PUBLIC_KEY> allowed-ips 10.0.0.5/32
The peer exists from that moment. No restart, no dropped handshakes, no interruption for anyone already connected. wg set talks to the kernel module directly and edits the live configuration of the interface.
Confirm it took:
wg show wg0
The new public key appears in the list, with no handshake yet — that is expected, the handshake happens when the client first sends traffic.
How do you add a peer from the command line, start to finish?
On the client machine, generate the key pair:
wg genkey | tee client.key | wg pubkey > client.pub
client.key is the private key and never leaves that machine. client.pub is what the server needs.
On the server:
wg set wg0 peer "$(cat client.pub)" allowed-ips 10.0.0.5/32
Back on the client, the config file needs the server's public key, its endpoint, and the address you just assigned:
[Interface]
PrivateKey = <contents of client.key>
Address = 10.0.0.5/32
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
The two keys are the step people get wrong: each side holds the other side's public key, never its own.
What goes in AllowedIPs when you add a peer?
It depends which side you are on, and this asymmetry is the source of most confusion.
| On the server, for this peer | On the client, for the server | |
|---|---|---|
| What it means | which address belongs to this client | which traffic to send through the tunnel |
| Typical value | 10.0.0.5/32 — one address | 0.0.0.0/0 (everything) or the LAN subnet (split tunnel) |
| Can it overlap another peer? | No | not applicable |
| Effect if wrong | packets go to the wrong peer, or are dropped | traffic bypasses the tunnel, or the tunnel captures your LAN |
The no-overlap rule is structural rather than tidiness. AllowedIPs is what tells WireGuard which peer a given destination belongs to, so an address listed on two peers makes that decision ambiguous — and the practical symptom is that adding a client silently knocks the previous one offline.
How do you make the new peer survive a reboot?
wg set changes the running interface. It does not touch /etc/wireguard/wg0.conf, so a reboot forgets it. Two ways to persist:
Add the block to the file by hand:
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 10.0.0.5/32
Or write the live state back to disk:
wg showconf wg0 > /etc/wireguard/wg0.conf
chmod 600 /etc/wireguard/wg0.conf
wg showconf prints the interface's private key along with everything else, so the destination file must not be world-readable. If you took the second route, check the permissions before you move on.
To reload an edited file without dropping sessions:
wg syncconf wg0 <(wg-quick strip wg0)
syncconf applies the differences. wg-quick down/up does not — it rebuilds the interface from scratch, which is exactly what you were trying to avoid.
How do you script adding peers on Linux?
The sequence has no interactive step, so it scripts directly:
#!/usr/bin/env bash
set -euo pipefail
NAME="$1"; IP="$2" # ./addpeer.sh laptop 10.0.0.7
umask 077
wg genkey | tee "$NAME.key" | wg pubkey > "$NAME.pub"
wg set wg0 peer "$(cat "$NAME.pub")" allowed-ips "$IP/32"
wg showconf wg0 > /etc/wireguard/wg0.conf
echo "added $NAME at $IP"
umask 077 matters: without it the freshly written private key is readable by every account on the box. set -euo pipefail matters too — without it, a failed wg set still leaves you with key files and a cheerful success message.

A hand resting on the keyboard while the monitor stays black — adding a peer with wg set produces no visible confirmation at all, which is why wg show is the only thing that tells you it worked.
Why doesn't the new peer connect?
The command succeeded and nothing happens. In practice it is almost always one of three things, and all three are checkable rather than guessable.
- The keys are swapped. The server holds the client's public key; the client holds the server's. Putting a private key where a public one belongs fails silently.
- The client is behind NAT with no
PersistentKeepalive. The server has no route back until the client speaks first, and the NAT mapping expires in between.PersistentKeepalive = 25on the client side keeps it open. - The address is already taken. Two peers with the same
AllowedIPsis the case that looks the most mysterious, because the older peer is the one that breaks.
That third failure is what wg-clients-audit exists for. It reads a folder of client configs and reports duplicate addresses, reused private keys, and AllowedIPs ranges broad enough to swallow the local network — the three faults that produce a tunnel which connects and then behaves strangely. Running it before you hand a config to someone is faster than diagnosing it afterwards.
Start with wg show wg0. A peer with no latest handshake never completed one, which points at keys or reachability. A peer that handshakes but carries no data points at AllowedIPs.
What to remember
wg set adds a peer live; wg-quick down/up disconnects everyone to do the same job. Whatever you add live is gone on reboot unless you also write it to the config, and wg showconf will happily write your private key into a world-readable file if you let it. One /32 per client, never overlapping. And when a new peer misbehaves, check wg show before changing anything — the difference between "no handshake" and "handshake but no traffic" tells you which half of the setup to look at.
★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200+ Mbps guaranteed
Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region→


