Guide · WireGuard

WireGuard config files explained, line by line

A tutorial has told you to paste a dozen lines into a file called wg0.conf, and most of them look like line noise: a key, an address with a slash in it, 0.0.0.0/0, and a number that might be seconds. It's less mysterious than it looks, and every line is there for a reason.

TL;DR: A WireGuard config file has an [Interface] section about your own device (its private key, its address inside the tunnel and, optionally, a DNS server) and one [Peer] section for each machine it talks to (that machine's public key, where to find it, and which addresses to send its way). The server keeps a matching file with one [Peer] per device, and phone apps read the very same text from a QR code.

The whole file, before we take it apart

We'll follow one example the whole way through: your laptop, connecting to a small WireGuard server you run at vpn.example.com, with everything the laptop does online going through it. Below is the laptop's complete file. The angle brackets are placeholders; a real file has a key in each of those spots.

The format is the old INI style: a section name in square brackets, then lines of Key = value. Anything after a # is a comment, which WireGuard ignores, so you're free to note which machine is which. You'll be glad of that the day you have five of these.

There are only two kinds of section. [Interface] is about this device: who it is and how it sits on the tunnel. [Peer] is about another machine: who that is, where to find it and what to send it. A laptop talking to one server has one of each.

The laptop's file: wg0.conf
[Interface]
# This laptop
PrivateKey = <the laptop's private key>
Address = 10.0.0.2/32, 2001:db8::2/128
DNS = 10.0.0.1

[Peer]
# The server at vpn.example.com
PublicKey = <the server's public key>
PresharedKey = <a secret only these two share>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = vpn.example.com:51820
PersistentKeepalive = 20

[Interface]: who this laptop is

PrivateKey is the laptop's identity, a 44-character string made by the wg genkey command. Whoever holds it is this laptop as far as the server is concerned, so it never leaves the device, and it's the reason the whole file deserves the care you'd give a password. The matching public key isn't in this file at all: it goes in the server's. Our guide to WireGuard keys covers how the pair is made.

Address is the laptop's address inside the tunnel. 10.0.0.2/32 is exactly one IPv4 address (the /32 says all 32 bits are fixed), and 2001:db8::2/128 is its IPv6 counterpart. These addresses only mean something inside the tunnel; on the wider internet, the server's own address stands in for them.

DNS names the server the laptop should ask when it turns a name like example.com into an address while the tunnel is up. Here it's the VPN server's inside address, which works only if the server runs a resolver; a public resolver's address works too. Leave the line out and the laptop keeps using whatever DNS server the local network handed it, so that resolver still sees every name you look up.

MTU is a line our example leaves out, as most files do. It's the largest packet the tunnel will carry, which must sit a bit below the network's own limit because WireGuard wraps every packet in a little extra. Left out, wg-quick works it out from the network. People set it by hand when a network struggles with large packets, which tends to show up as pages that load halfway and stall.

[Peer]: who's on the other end, and where

PublicKey is the server's public key, the other half of the private key in the server's own file. It's how the laptop knows it has the right machine: only the holder of the matching private key can complete the handshake, so an impostor at the same address gets nowhere. How that handshake works is in our WireGuard explainer.

PresharedKey is optional. It's a third key, made with wg genpsk and shared by exactly two machines, which WireGuard mixes into the handshake as an extra layer. The WireGuard documentation describes it as a hedge against future quantum computers breaking today's public-key maths. Both files must hold the same value or the handshake fails; leave it out of both and WireGuard simply runs without that layer.

Endpoint is where to find the server on the internet: a hostname or IP address, a colon, and the UDP port the server listens on. The laptop needs it to send the very first message. The server's file, notice, has no Endpoint for the laptop. It learns the laptop's current address from the first genuine packet and updates it whenever the laptop moves, which is why a phone can hop from Wi-Fi to mobile data without anyone editing anything.

AllowedIPs and PersistentKeepalive: what to send, and keeping in touch

AllowedIPs does the most work of any line. 0.0.0.0/0 matches every IPv4 address and ::/0 every IPv6 address, so this line says: send everything through this peer, and accept whatever comes back from it. That's two jobs in one line, a routing rule on the way out and a filter on the way in, and it has a guide of its own. For now: a narrower range sends only those addresses through the tunnel, and everything else goes the usual way.

PersistentKeepalive = 20 asks the laptop to send a tiny, empty, encrypted packet every 20 seconds whenever it has nothing else to say. WireGuard is silent when idle, and many home routers and mobile networks forget a quiet connection after a while. Once they have, the server can't reach the laptop until the laptop speaks first.

It's off unless you ask for it. A device that has to stay reachable wants it on, with an interval well under a minute, and the cost is one small packet each time.

The other end: the server's file

The server's file mirrors the laptop's. Its [Interface] has the server's own private key, its own inside address, and a ListenPort: the UDP port it waits on, which must match the port in every device's Endpoint. 51820 is the number most examples use, and any free UDP port works. The laptop's file has no ListenPort, so the laptop picks a random one; the server needs a fixed one so that devices know where to knock.

Then there's one [Peer] block per device, each with that device's public key and, in AllowedIPs, the single address that device may use: 10.0.0.2/32 for the laptop, 10.0.0.3/32 for a phone. It's the narrow mirror image of the laptop's catch-all, and it's what stops the phone sending packets that claim to come from the laptop. None of the blocks has an Endpoint.

The phone's block has no PresharedKey, and that's allowed: each pair of machines decides for itself. A real server also has to pass the tunnel's traffic on to the internet under its own address. That's the operating system's job rather than WireGuard's, often set up with PostUp and PostDown lines in this same file, which wg-quick runs as the tunnel comes up and goes down.

The server's file: wg0.conf
[Interface]
# The server
PrivateKey = <the server's private key>
Address = 10.0.0.1/24, 2001:db8::1/64
ListenPort = 51820

[Peer]
# The laptop
PublicKey = <the laptop's public key>
PresharedKey = <the same shared secret>
AllowedIPs = 10.0.0.2/32, 2001:db8::2/128

[Peer]
# A phone
PublicKey = <the phone's public key>
AllowedIPs = 10.0.0.3/32, 2001:db8::3/128

Bringing it to life: wg-quick on a computer, a QR code on a phone

On Linux the file usually lives at /etc/wireguard/wg0.conf, and the tunnel takes its name from the file: wg0. Running wg-quick up wg0 does the chores for you. It creates the interface, gives it the Address, sets the MTU, hands the keys and peers to WireGuard, turns every AllowedIPs range into a route, and points the system's DNS at the DNS line. When a route is a catch-all, it uses the system's routing rules to take over the default route, while making sure WireGuard's own packets to the server still go out the normal way.

That's why Address, DNS and MTU feel different from the rest. They aren't part of WireGuard's own format: wg-quick handles them itself, along with extras like PostUp, and passes the rest to the wg tool. The official WireGuard apps understand those three too, so a file like the laptop's moves between them.

Phones skip the typing. The official WireGuard apps for iPhone and Android can scan a QR code, and that code is simply the text of the file; the apps themselves suggest the qrencode tool for drawing one on a computer screen. That also means the QR code contains the private key. Anyone who photographs it has your device's identity, so show it, scan it and close it.

To check the result, wg show lists each peer with its latest handshake and how much data has passed. A recent handshake is the clearest sign that both ends agree on the keys.

Commands
# Bring the tunnel up, check it, take it down
sudo wg-quick up wg0
sudo wg show
sudo wg-quick down wg0

# Show a phone's own config file as a QR code
qrencode -t ansiutf8 < phone.conf

The mistakes everyone makes once

Most broken files fail in one of three ways, two of them in total silence. WireGuard doesn't answer anything it can't authenticate, so these mistakes don't produce an error message. They produce nothing: no handshake, and wg show never reports one.

  • Keys in the wrong place. Each [Peer] PublicKey must be the other machine's, and the only private key in a file belongs in its own [Interface]. Pasting the laptop's own public key into its [Peer] section is the classic version.
  • A wrong Endpoint. An old address, a hostname that points at the wrong machine, a port that doesn't match the server's ListenPort, or a firewall in front of the server that doesn't let that UDP port in. The first message goes somewhere that will never reply.
  • A missing ::/0. This one is quieter, because everything seems to work. With only 0.0.0.0/0, IPv4 goes through the tunnel and IPv6 carries on over your normal connection, so on a network with IPv6 some sites still see your real address. If you mean everything, list both.

Where this file is in WrapVPN

If you use WrapVPN, you'll never see any of this. There's no file to import and no key to copy: you sign in with Apple or Google, pick a location and tap Connect. When you tap Connect, the app asks our servers for a configuration for the location you chose and builds the tunnel from it, on iPhone, iPad, Mac, Android and Windows alike.

It's the same kind of configuration you've just read, sending all of your traffic, IPv4 and IPv6 alike, through the tunnel. The difference is that nobody has to paste anything, which rules out most of the mistakes above. Install WrapVPN and try it on the free plan's three one-hour sessions a week.

Plans and prices

Weekly and monthly plans renew automatically until cancelled, and there is no annual commitment. You can cancel at any time in your App Store or Google Play subscription settings.

$1.99per week

$3.99per month

There is no annual or multi-year plan.

The monthly plan may include a 7-day free trial for eligible new subscribers.

See all plans

Common questions

Where is the WireGuard config file stored?

On Linux, wg-quick looks in /etc/wireguard first, so a tunnel called wg0 lives at /etc/wireguard/wg0.conf. The official apps for Windows, macOS, iPhone and Android import the file and keep it in their own storage, where you edit it through the app. Wherever it lives, it contains a private key, so it should be readable only by you.

Can I use the same WireGuard config on more than one device?

Not at the same time. Both machines would hold the same private key and claim the same address, so the server would treat them as one peer and send replies to whichever spoke last. Give each device its own key pair, its own address and its own [Peer] block on the server.

Do I need PersistentKeepalive in WireGuard?

Often not. It's off by default, and a device that only starts connections can manage without it. Turn it on when a device has to stay reachable from the other end while it sits behind a home router or a mobile network that forgets quiet connections.

How do I apply changes to a WireGuard config file?

wg-quick reads the file when the tunnel comes up, so the simple way is wg-quick down followed by wg-quick up. To apply peer changes without dropping the tunnel, wg-quick strip produces a version of the file the wg tool understands, and wg syncconf applies it to the running interface.

Do I need a WireGuard config file to use WrapVPN?

No. The app builds the configuration for the location you pick when you tap Connect, and you never see it. You sign in with Apple or Google, choose a location and tap Connect.

Download WrapVPN

One account works on your phone, tablet and computer, with no device limit on any plan. Every server location is available on every plan, including the free plan.