Skip to content
Network Servers

WireGuard Isn’t a VPN — It’s a Superpower

Control your home network from a cabin, coffee shop, or coworking space. No paid services, no sketchy workarounds.

Ever wish your home network followed you around? Not just some remote login or a janky web portal full of sketchy port forwards. I mean real access — like you never left home.

Ever wish all your servers were on the same local network? Even if they live on opposite sides of the planet?

Ever wish you could connect two remote Docker networks like they were on the same machine? You can.

That’s what WireGuard does — securely. It’s not about hiding your IP (though you can do that). It’s about creating a fast, simple, rock-solid tunnel between machines or networks you control.

If you’ve had those thoughts — you’re in the right place. We’re going to walk through how WireGuard works, how to set it up, and the game-changing things you can do with it.

WireGuard isn’t just another VPN tool. It’s kernel-level encryption and networking — fast, minimal, secure. But take a moment to appreciate what that means:

WireGuard is baked into the Linux kernel. It’s not a plugin or a package — it’s part of the OS. That means it runs as close to the metal as possible, with near-zero overhead.

By extension, it’s also part of Android. Microsoft added it to the Windows kernel starting in Windows 10 version 2004. Apple didn’t — on macOS and iOS, it runs in user space. Still fast, but not quite the same.

The point is: this thing is legit. Let’s dive in.

The Peer Concept

Before we go further, there’s one thing you should know: WireGuard isn’t your typical client-server setup.
All devices are peers.

You might say you’re “connecting to a server,” but in WireGuard terms, that “server” is just another peer. Why? Because any device can act as a server — including a device that’s technically a client. It all depends on how you route traffic.

A Raspberry Pi at home? It can be the central hub.
Your laptop? It can be both a client and a relay to something else.

You’ll see what I mean the moment you configure your first connection:
There’s no special “client” or “server” software.
The config files look the same on both sides.
That tripped me up at first — but it’s part of what makes WireGuard so flexible.

And to be clear: WireGuard isn’t about hiding your IP or spoofing your location.
That said… you can use it like a traditional VPN. Many commercial VPNs give you WireGuard config files — and you can roll your own, too, by generating your own keys, setting up peer endpoints, and defining how traffic should be routed.

The key takeaway?
Once you’ve set up one WireGuard connection, you’ve basically learned them all.


Quick Concepts

WireGuard doesn’t use a traditional client-server model. Every device is a peer. But what makes a peer a “server” or a “client” depends entirely on which direction traffic flows — and who initiates it.

So before we move on, here’s a mental model that helps:

You’ll see this come up again when we get to [Interface] vs [Peer] blocks.

Also: WireGuard isn’t just encryption — it’s networking too. Let’s explore how that works.

WireGuard Is Both Encryption and Networking

Part of learning WireGuard is learning Linux networking principles — because WireGuard doesn’t reinvent networking for itself. It builds on what’s already there.

It’s a VPN, sure. But it’s also a network interface. You bring up a WireGuard tunnel the same way you bring up any other network interface, and your system can route packets through it just like a regular NIC. The only difference? Those packets get wrapped — like a dark-tinted van, encrypted and unreadable from the outside.

Network interface? NIC?
These are what you see when you run ip link show, or when you look at your network settings. They include WiFi, Ethernet, LTE, bridges (e.g., Docker networks), and more.

In most WireGuard examples, the go-to interface name is wg0 — but you can name it whatever you want. When decision fatigue hits, you’ll default to wg0, wg1, and so on.

So before we go deeper, let’s take a peek at the parts that make up a WireGuard config.

ATTENTION
The key thing about WireGuard is that not all fields are used.
I should probably type that twice.

ATTENTION
Depending on the peer’s role — like client or server — and whether you’re routing internet traffic or just linking two networks, different fields apply. There’s no one-size-fits-all recipe. But don’t worry — I’ll give you the pointers you need to feel confident in most real-world setups.

Interface

This is the section WireGuard uses to create the network interface
(e.g. wg0).

IMPORTANT
The Interface section on a “client” corresponds to a Peer section on the “server”.

Peers

This is who you talk to. You can have one, or you can have a whole list.

From the perspective of a “client”
you can route different IP ranges to different peers — maybe one peer handles internet traffic, another handles your home network, and so on.

From the perspective of a “server”
the peer list is like a user list — it authenticates who’s allowed in and what network resources they can access.

Each peer has these fields:


Once you see this format, it clicks:
Each device configures itself, lists its peers, and that’s it.

You’re now doing secure, peer-to-peer encrypted networking.

Advanced Fields: PostUp and PostDown

If you’re using wg-quick to manage your interface, you get two powerful helpers: PostUp and PostDown.

These are shell commands that run after the interface is brought up (PostUp) and before it’s taken down (PostDown).

They’re often used to:

Example:

[Interface]
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT

%i is a placeholder for the interface name (like wg0).

You don’t need these for simple setups, but once you start doing things like routing all traffic through WireGuard or linking networks, PostUp and PostDown are essential.

So What Can You Do With WireGuard?

VPN stands for Virtual Private Network — but it’s not just about hiding your IP.

A VPN is any secure connection between two points. That’s it. Once that’s in place, what you do with it is up to you.

WireGuard is one way to do it — and a very good one — but it’s not the only tool. Open-source alternatives include IPSec, SSH tunneling, OpenVPN, and SoftEther. All of them can securely connect two devices, or even two entire networks.

There’s no hard limit. You can get as creative as you want.
Once you understand the basics, you can repeat the setup wherever and whenever you need it.

I’ll give you a few practical examples to get the ideas flowing.

Cloudflare Tunnel — Argo Tunnel

It used to be called Argo Tunnel, but now it’s just Cloudflare Tunnel. You’ll find it packaged as cloudflared in most Linux distros — the “d” stands for daemon, since it typically runs as a systemd service.

This isn’t a WireGuard example per se — but it’s the same pattern. And you could absolutely build something like this yourself using WireGuard — see below.

A Cloudflare Tunnel creates a secure connection between any device you own and the Cloudflare network. More specifically, it connects to a Cloudflare reverse proxy — a server that handles incoming HTTP requests on ports 80 and 443.


Cloudflare Proxy Example
Let’s say you run a WordPress site. You point your domain to your server’s IP in the Cloudflare dashboard and flip the Proxy switch. Now Cloudflare acts as a middleman: it receives requests from the internet, fetches pages from your server, and delivers them to visitors.


What’s the advantage?


But what about Cloudflare Tunnel?
A tunnel does the same job — but flips the flow.
Instead of Cloudflare pulling content from your server, your server pushes a secure connection up to Cloudflare.

Requests hit Cloudflare → get routed through the tunnel → reach your local app → response goes back the same way.


You could replicate this whole pattern with WireGuard:

In fact, why don’t we do that now?

Your Own Tunnel with a Proxy

Let’s say you’ve got a home server — just a basic PC running a web server for Wordpress.

You set up a WireGuard connection to a free VPS (yes, they exist — search around).
You configure the corresponding peer on the VPS.

Now that VPS can reverse proxy your home server.
Clean, private, and entirely under your control.

I have left out the actual conf because we focus on that below.


This might be a little outside the scope of this article, but here’s what it could look like:

Believe it or not — that’s it.


I know, I know — you probably want all the config examples, step-by-step guides, and systemd service files. That’s fair. But here’s the move:

Get the WireGuard connection working first.
Don’t overwhelm yourself by cramming everything in at once.

The first time you set up WireGuard will take a bit more head-scratching than the second time. But once it clicks, you’ll be reusing the pattern everywhere.

And yeah, I’m adding context here — because understanding how this fits into the bigger picture makes everything less abstract. But the nitty-gritty? Save it for when you’re actually implementing it.

Your Very Own Hide-My-IP VPN

I don’t recommend this for a few reasons — but who cares.
What we care about right now is understanding how WireGuard works.

Here’s why I wouldn’t recommend it:

But let’s implement it anyway — for the sake of learning.


Take the same free VPS from earlier and the same peer-to-peer WireGuard config.
This time, on your home PC, you tweak the config to route internet traffic through the VPS.

How?

By adding a specific IP range to AllowedIPs:

AllowedIPs = 0.0.0.0/0, ::/0

With that in place, your home PC will route all outbound traffic through the WireGuard tunnel to the VPS.

On the VPS side, as long as IP forwarding is enabled and no firewall is blocking traffic, it will forward your packets to the internet as if they originated from the VPS itself.

You’ve effectively hidden your IP.

Congratulations — you’ve just built your own VPN exit node.

Lazy Phone VPN — With Added Benefits

I’m still on the fence about naming this section Lazy Phone VPN — but now that I have, here we are.
The real point is: being permanently connected to home.

Install the official WireGuard app on your smartphone — it’s available on both Android and iOS. The icon looks like a dragon wrapped into a figure 8. There are other good apps too, but the official one works well.

The goal: as soon as you leave the house, your phone connects back home.

If you’ve got WireGuard running on your router or a home server, your phone can tunnel straight into your LAN.

But listen up — there’s more.
If your home network itself connects to the internet through a VPN (like Mullvad or Proton), then your phone will not only get access to your LAN, but also inherit your home’s VPN connection:

Phone via LTE → Home → VPN → Internet

You don’t need an extra VPN app on your phone. You can:


I personally discovered another benefit:
My mobile carrier didn’t offer IPv6, but my home VPN provider did.
So by routing traffic through home, my phone got IPv6 too.
Sure, global IPv6 rollout has been slow — but it felt great dunking on my carrier.


If you want to route all phone traffic through WireGuard, use this in your config:

AllowedIPs = 0.0.0.0/0, ::/0

This captures everything: IPv4 and IPv6.

But if you only want LAN access and want the rest to go out over your phone’s LTE? Split the traffic:

AllowedIPs = 10.0.0.0/24, 192.168.0.0/24, fd00::/64

Assumptions:

Anything else — websites, cloud apps, etc. — goes out your normal mobile connection.

Yes, this may raise more questions than it answers. CIDR notation can be a rabbit hole. But here’s a quick primer:

You can even get clever and split traffic between two peers — half to one, half to the other.

I’ll be honest:
I’m resisting the urge to keep going down the CIDR path, because it’s a whole topic on its own. But know this:

CIDR notation is a more compact version of the subnet mask format you might’ve seen before.
192.168.0.1/24 is the same as 192.168.0.1 with subnet mask 255.255.255.0.

Oh, and why not add that 192.168.0.1/32 refers to that single IP address.

I’m confident some of you are starting to piece it together.
There’s still so much more about CIDR — but we march forward, friends.

Actual Config Examples — Finally

You might be wondering why I didn’t drop these earlier.
The answer is simple: we shouldn’t get bogged down by implementation details before we understand what we’re doing.

That said — you might still feel like there’s more to it. And… you’re both right and wrong.


Why that’s false
Because the config fields we covered earlier are really all you need to set up a working WireGuard connection.
It’s that simple.

Why that’s true
Because the “more to it” parts come from Linux networking, not WireGuard itself.

WireGuard is relatively simple.
But if you want to do clever things — like selective routing, traffic segmentation, or multihop VPN — then concepts like CIDR, routing tables, and nftables start to matter.

Also, while you probably know what a firewall is, be aware that cloud providers, home routers, and VPS dashboards don’t always call it that.

Instead, you’ll see terms like:

They’re all doing the same thing: controlling what traffic gets through.


The good news?

You generally just need to forward UDP port 51820 to your WireGuard server.
Once that’s done, all tunnel traffic is allowed — one config to rule them all.

WireGuard doesn’t complicate networking — it simplifies it.

Linux Networking Primer

Didn’t I say we’d do examples now?
Um, sorry?

Before we dive into more configs, we need to peek under the hood — just a little.

To get started with Linux networking, try the ip route command. It shows how Linux routes traffic.


Start by noticing the default via line.
This is your system’s fallback — when no other route matches, packets go there.
That usually means: “send it to the internet.”


Now, after you bring up a WireGuard interface, run ip route again.
You’ll see a new line for your WireGuard subnet — like 10.0.0.0/24, if you’ve followed the earlier examples.

What does that mean?
It means: “if a packet’s destination IP falls in this range, send it through this interface.”

If that interface is a WireGuard tunnel, then the packet gets encrypted — the payload is scrambled using your private key.
The result isn’t an IP packet anymore — it’s wrapped inside a UDP packet that acts as a sealed envelope.


Where does that UDP packet go?
It’s sent to the Endpoint of the first peer that matches — based on the AllowedIPs.

AllowedIPs can overlap between peers, so order matters.
It’s up to you to keep routing clean and predictable.

When the peer receives that UDP packet, it decrypts it, extracts the original packet, and routes it to its original destination.


Yes, it sounds like magic. But it’s just solid networking, wrapped in crypto, wrapped in UDP.

The WireGuard Config — Starter

Finally — take two.

Let’s walk through the basics.
We’ll cover how to generate those private and public keys in the next section.

# example.conf

[Interface]
PrivateKey = gLGoLUmtdK7iYu+TBVmwKCIgupdu8bA9F30ETa/1Kks=
Address = 10.0.0.2/32
DNS = 10.0.0.1

[Peer]
PublicKey = gMu/QIGmYeoKlSvjgX8qy1g7YcSCjNHKiI6MfDhFkB4=
AllowedIPs = 0.0.0.0/0
Endpoint = 119.225.114.28:51820

The file above can be used in mobile apps, desktop clients, or directly from the command line. We’ll focus on the command line.

When used, this config will create a new network interface and set up IP routes automatically.

sudo wg-quick up example.conf
ip address show wg0
ip route
wg show

A note about wg show: If there’s no active WireGuard peer listening at the configured Endpoint, or the keys don’t match, then wg show will indicate that the connection hasn’t been established (e.g., latest handshake: never).

wg show is your go-to command to confirm whether things are working or not.

A Complete P2P Example

We begin by creating the keys.

The following must be done on both peers.
Then you exchange public keys.

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

You can run these commands as many times as you want — the keys are throwaway unless used.
Just make sure the private and public keys you actually use match up.


Next, decide which peer will be the “server”.


On the “server”:

# server-example.conf

[Interface]
PrivateKey = gLGoLUmtdK7iYu+TBVmwKCIgupdu8bA9F30ETa/1Kks=
Address = 10.0.0.1/32
ListenPort = 51820

[Peer]
PublicKey = gMu/QIGmYeoKlSvjgX8qy1g7YcSCjNHKiI6MfDhFkB4=
AllowedIPs = 10.0.0.2/32

On the “client”:

# client-example.conf

[Interface]
PrivateKey = ABDTf9fhUJjJh/LEHDujtCveNvTTo1hJi+6dpfn9LHw=
Address = 10.0.0.2/32

[Peer]
PublicKey = W9x4MU3bWPOsB1TRj8CfOZ9V9E0M8aMy7aqkIQNgaFU=
AllowedIPs = 0.0.0.0/0
# AllowedIPs = 10.0.0.0/24
Endpoint = 119.225.114.28:51820

The client’s AllowedIPs = 0.0.0.0/0 means:
“send all traffic through this peer” — making this a hide-your-IP style connection.
For LAN-only access, you’d just list the internal subnet (e.g., 10.0.0.0/24).

“Client” and “Server” Mindset

When you’re tuning those config files, try shifting your perspective:
Position yourself as either the client or the server.
Even though WireGuard treats all devices as peers, the way you fill out the config gives each one a role.


In a “server” config:


In a “client” config:


This “role mindset” helps when you’re troubleshooting or extending your setup.
Even though both sides are peers, thinking like a client or server keeps things sane.

The Hybrid Config

We haven’t talked yet about configs that act as both “client” and “server.”
I’m calling it a hybrid, but that’s not an official term.

If a config sets up both a listener and a connection initiator, it can act as a relay — a bridge between otherwise unreachable peers.


Why would you need this?
Because some network setups just won’t let two peers talk directly.
But if:

Then B can relay traffic between them.

WireGuard makes this not just possible — but simple.
You’re just adding peers and adjusting routing.


I’m not giving specific examples here because:

Once you understand how roles, AllowedIPs, and routing work, you can build anything.

Extra Stuff You Might Need

Here are a few extras that didn’t quite fit earlier, but matter depending on what you’re building:


🔁 IP Forwarding + NAT

If your server acts as a gateway (e.g., AllowedIPs = 0.0.0.0/0 on the client), you’ll need to:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Replace eth0 with your actual outbound interface.
Without this, traffic reaches the tunnel but dies on the way out.

🔐 Preshared Keys

For an extra layer of encryption:

wg genpsk > psk

Then add this to both [Peer] blocks:

PresharedKey = <contents of psk>

People
This is entirely optional — and most times completely unnecessary. WireGuard’s core cryptography (Curve25519, ChaCha20, Poly1305) is already top-tier and well-audited.
It comes down to:

Are you the kind of organization (or person) that gets targeted?

If the answer is “yes”, then use preshared keys.

🧩 Multiple Interfaces

You can have wg0, wg1, etc.
Use the ip rule and ip route commands to keep routing tables separate if needed. Does that open a can of worms again?

In fact,
you can leave the Name field out.
They will automatically get sequential wg names.

🔎 A Note About DNS

The DNS field in your WireGuard config is widely supported — mobile apps, desktop clients, and GUI tools usually respect it.

Do they use wg-quick under the hood? Or reimplement it?
Doesn’t really matter — the key thing is: it often works, but not always the same way.

DNS behavior can vary depending on:

If DNS breaks after the tunnel comes up, it might not be WireGuard — it might be your system’s DNS handling.

Some practical tips:


You Know More Than You Think

If you’ve made it this far, you’re no longer just kicking the tires — you’ve seen under the hood.
You’ve learned how WireGuard works, what config fields actually mean, how to route traffic, and how to use it for more than just hiding your IP.

But maybe more importantly:
You’ve seen how a simple, clean protocol like WireGuard can unlock massive flexibility — remote access, internal mesh networks, relays, reverse proxies, and secure tunnels that Just Work™.

You don’t need to memorize every command.
You just need to understand the mental model.
And now you do.

So take a break. Try a small setup. Break it. Fix it. Then build something a little bigger.
This is where self-hosting becomes self-empowering.

WireGuard isn’t just a VPN. It’s a lever.
You now know how to pull it.

Let’s go.

Discussion

This happens on our forum (Discourse), but the comments are shown here. Posting a reply requires signing in or creating an account. Follow the link if you wish to participate.