WireGuard Quick Start

WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.

Client Side #

Install the WireGuard package / application for your operating system.

Create key pairs:

wg genkey | tee privatekey | wg pubkey > publickey

Create configuration file:

Address =, fd86:ea04:1111::2/128
PrivateKey = <content of privatekey, base64 string>
PublicKey = <content of server publickey, base64 string>
Endpoint = <public ip of server:51820>
AllowedIPs =, ::/0
PersistentKeepalive = 25

Interface is for this machine (client info here), and Peer is for other machine (server info here). and fd86:ea04:1111::2 are private IP addresses. I can specify any private IP addresses here, as long as the IP addresses are matched with private subnet assigned to the server.

/32 is a subnet mask, which means one single IPv4. As a client, this machine only need one IPv4 within the virtual network. Similarly, /128 is a CIDR indicating one single IPv6.

The DNS line is optional, which should be a DNS resolver which provides optimal resolutions for the server. Here I use from cloudflare.

Endpoint specifies how to access the server. The IP can be IPv4 or IPv6, but typically IPv4, because the client machine may be under an IPv4-only network. The port (51820 here) must match the ListenPort specified in the interface of the server., ::/0 means sending all traffic to the server.

If the client is behind NAT, the router will need to translate its internal IP and port before forwarding the packets to the Internet. And the router will keep tracks of the connections in a Network Address Translation table. Based on this NAT table, it routinely closes off ports that appear dormant. If the router erroneously closes the WireGuard port, the WireGuard service, unaware of this change, will continue to send packets to the closed port. This leads to network problems. PersistentKeepalive = 25 means sending a keeplive packet to the server every 25 seconds to prevent the NAT expiration (typically in 60 seconds for most routers).

To enable the tunnel, run:

sudo wg-quick up /path/to/wg0.conf

To turn off the tunnel, run:

sudo wg-quick down /path/to/wg0.conf

If you uses a GUI WireGuard application, you can import the configuration file instead.

If you uses the WireGuard mobile application, the fast way to import the configuration is scan a QR code:

cat /path/to/wg0.conf | qrencode -t ansiutf8

Multiple servers can be specified in multiple .conf files.

Server Side #

Install the WireGuard package on server, then generate key pairs as mentioned above.

Create /etc/wireguard/wg0.conf:

Address    =, fd86:ea04:1111::1/64
PrivateKey = <content of privatekey, base64 string> 
ListenPort = 51820
PostUp   = iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE

PublicKey  = <content of client publickey, base64 string> 
AllowedIPs =, fd86:ea04:1111::2/128

/24 is a subnet mask for 256 IPv4 addresses, since an IPv4 address uses 32 bits, masking 24 bits leaves 8 bits (2 ** 8 = 256). In the above example, is preserved for compatibility reasons (IPv4 addresses ending with .0 are historically considered representing the network itself and used for broadcasting), and is used by the server. Thus this virtual network allows up to 254 clients.

The subnet mask for IPv6 could be /120 (2 ** (128-120) = 256). However, IPv6 recommends using /64 as the smallest subnet, and a lot of software assumes an IPv6 subnet will not be smaller than /64.

PostUp forwards Internet requests from clients, and ens3 is the network interface to access Internet on the server. PostDown deletes the iptable rules when the VPN is off. Actually these are WireGuard hooks, you can fill any shell command here.

A quick explanation of iptables rules:

The PublicKey and AllowedIPs in the Peer section should match the configuration of the client.

You can add more clients (multiple Peer sections).

Enable forwarding IPv4 and IPv6 packets on the server:

echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

sysctl modifies kernel parameters at runtime, and -p loads /etc/sysctl.conf. This is only required on the server, since client allow Internet through server.

Start WireGuard:

sudo wg-quick up wg0
# equivalent to `sudo wg-quick down /etc/wireguard/wg0.conf`

Stop WireGuard:

sudo wg-quick down wg0

You may also add WireGuard service to your init system, e.g. systemd:

sudo systemctl enable wg-quick@wg0.service