Skip to content

WireGuard

The strange VPN that is pretty fast at everything.

Basic setup

Server side:

[Interface]
PrivateKey = <server-private-key>
Address = 10.0.0.1/24, 2001:db8::1/64
ListenPort = 51820

[Peer]
PublicKey = <client-public-key>
AllowedIPs = 10.0.0.2/32, 2001:db8::2/128

Client side:

[Interface]
PrivateKey = <client-private-key>
Address = 10.0.0.2/32, 2001:db8::2/128

[Peer]
PublicKey = <server-public-key>
AllowedIPs = 10.0.0.0/24, 2001:db8::/64
Endpoint = server.example.com:51820

Note: You can reverse roles by adding ListenPort to the clients Interface and Endpoint to the server Peer section, though this may complicate IPv4 NAT traversal.

Extra functionality

Behind IPv4 NAT

If you're behind NAT, the connection may timeout due to inactivity.

Add PersistentKeepalive to maintain the connection:

[Peer]
Endpoint = server.example.com:51820
PersistentKeepalive = 25

DNS

DNS configuration only works with wg-quick, systemd-networkd, or GUI tools - not with the basic wg command.

When routing all traffic through WireGuard (0.0.0.0/0), you may lose DNS access on some networks. Add DNS servers to your client configuration:

[Interface]
DNS = 1.1.1.1, 2606:4700:4700::1111

PostUp/PreDown scripts

PostUp and PreDown allow running commands when the interface comes up or goes down. These only work with wg-quick, systemd-networkd, or GUI tools - not with the basic wg command.

Common use cases (server side - NAT/forwarding):

[Interface]
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PreDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Client side examples:

[Interface]
PostUp = echo "Connected to VPN"
PostUp = /home/you/vpn-connect-script.sh
PreDown = echo "Disconnected from VPN"

Multiple commands can be separated with semicolons or using multiple PostUp/PreDown lines.

Note: %i is replaced with the interface name. Scripts run with root privileges, so be careful with security.

AllowedIPs

AllowedIPs serves dual purposes

Server side: Defines which source IPs are allowed from this peer (access control)
Client side: Defines which destinations to route through the tunnel (routing table)

The peer's Interface address must always be included in AllowedIPs.

Just other WG clients (mesh network)

[Peer]
AllowedIPs = 10.0.0.0/24, 2001:db8::/64

WireGuard network + home LAN access

[Peer]
AllowedIPs = 10.0.0.0/24, 2001:db8::/64, 192.168.1.0/24, 2001:db8:1::/64

Full tunnel (all traffic)

Routes all traffic through WireGuard:

[Peer]
AllowedIPs = 0.0.0.0/0, ::/0

Allow DNS

If you're using a weird OS like MacOS, you may need to specificly include routes for your DNS servers. Why? idk, it should already be covered.. Might be some security stuff.

[Peer]
AllowedIPs = 0.0.0.0/0, ::/0, 1.1.1.1/32, 2606:4700:4700::1111/128

Split tunnel (internet only, preserve local access)

Routes internet traffic through WireGuard while keeping local network access:

[Peer]
AllowedIPs = 2000::/3, 1.0.0.0/8, 2.0.0.0/8, 3.0.0.0/8, 4.0.0.0/6, 8.0.0.0/7, 11.0.0.0/8, 12.0.0.0/6, 16.0.0.0/4, 32.0.0.0/3, 64.0.0.0/2, 128.0.0.0/3, 160.0.0.0/5, 168.0.0.0/6, 172.0.0.0/12, 172.32.0.0/11, 172.64.0.0/10, 172.128.0.0/9, 173.0.0.0/8, 174.0.0.0/7, 176.0.0.0/4, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.169.0.0/16, 192.170.0.0/15, 192.172.0.0/14, 192.176.0.0/12, 192.192.0.0/10, 193.0.0.0/8, 194.0.0.0/7, 196.0.0.0/6, 200.0.0.0/5, 208.0.0.0/4

Additional considerations

IP forwarding: Enable on the server with net.ipv4.ip_forward=1 and net.ipv6.conf.all.forwarding=1 for routing to work.
Key generation: Use wg genkey | tee private.key | wg pubkey > public.key to generate keypairs securely.