Road warrior VPN with WireGuard

I wanted to have a “road warrior” VPN that would give me access to my entire network. I used to have an OpenVPN server running on a pfSense virtual firewall at my colo. I recently switched that over to OPNSense so I no longer had a working VPN solution. This was also over complicated. Here’s essentially how it worked:

The laptop is representative of me outside my home. Whether I was at family’s homes, AirBNB, or even out at Target. The red line is the connection I’d take to get to the resources at my home. The green line was the VPN connection. Now of course, this is simplified. I have servers in colo I’d need to access, and it became a mess with the firewall rules and IPSec tunnels that I needed to create for my OpenVPN subnet. I wanted something simple.

As much as I like OpenVPN, it’s a pain. It works really well, but I just needed access to my inside resources and a full tunnel to protect my internet especially in unfamiliar places – like AirBNBs.

WireGuard – it’s good at guarding your wires

I’ve been hesitant on setting up WireGuard because it’s new and it seems confusing. But I wanted something simple. I debated using ZeroTier like I had in the past, but that wasn’t “simple” (at least doing a network bridge). So WireGuard it is.

I setup a CentOS 7 server on my home network and followed a guide to install WireGuard and generate the keys. I created my wg0.conf file as instructed and placed in some standard stuff:

[Interface]Address = 10.125.37.1/24PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADEListenPort = 51845PrivateKey = [SNIP!]

Address = this should be a subnet not in use to avoid conflict.

PostUp = this is a forwarding command with NAT. I’m not an iptables expert so I can’t tell you everything. I just know it works.

PostDown = Similar to PostUp but it tears down the rules.

ListenPort = This is the port WireGuard listens on.

PrivateKey = This is your server’s private key that you generated. Do not share this with anyone!

Next, add some clients. So I wanted to use this on my laptop that I take everywhere with me. So I installed the WireGuard client and then I added an empty tunnel. WireGuard will give you a template. There’s a public key (copy this!) and a private key, but that’s it. You’ll need to add some details.

Under [Interface] and the PrivateKey line, type in Address = and then an address from the subnet you gave your server. So for example, I have: Address = 10.125.37.20/24. Now on a new line below that, type in DNS = and the IPs of your local DNS servers or DNS servers you want to use. I have internal DNS servers, so I typed in: DNS = 10.204.1.254,10.200.2.254. If you don’t have any internal DNS, you can leave off the DNS option. Now put in a blank like and then another line. On the second new line, type in [Peer] and hit enter. This is going to be the connection to the server. You’re going to need your server’s PUBLIC key. Let me show you what I have:

[Peer]PublicKey = G6nFXi1z7YYV0uVvS8KsW+ZygK7VsEzH/3EwIsUFDFg=AllowedIPs = 0.0.0.0/0Endpoint = XX.XX.XX.XX:51845

PublicKey = This is your WireGuard server’s public key. This can be shared. I’ve modified mine for privacy reasons.

AllowedIPs = This tripped me up. I want a full tunnel so I added 0.0.0.0/0 which is networking for “everything”. Otherwise, you add the subnets you want to access. Like if you just want to access your home network, put in your home network’s subnet. Only that traffic will go across WireGuard.

Endpoint = This is the public IP and port number of your WireGuard server. You’ll need to port forward this from your home router.

Now you can save your WireGuard config on your laptop. For reference, here’s my full config (just with parts changed or removed):

[Interface]PrivateKey = [MY LOCAL PRIVATE KEY]Address = 10.125.37.21/24DNS = 10.204.1.254[Peer]PublicKey = G6nFXi1z7YYV0uVvS8KsW+ZygK7VsEzH/3EwIsUFDFg=AllowedIPs = 0.0.0.0/0Endpoint = IP-OR-DYNDNS-NAME-HERE:51845

Final touches on WireGuard Server

On your WireGuard server, open up your wg0.conf file. You’re now going to add a [Peer] section like you did on your computer. This one is short though. It’s just the public key and the IP address. For example:

[Peer] # LaptopPublicKey = G6nFXi1z7YYV0uVvS8KsW+ZygK7VsEzH/3EwIsUFDFg=AllowedIPs = 10.125.37.20/32

You’ll notice I have a comment there to help me identify my devices. I was only able to get this to work by using a /32 in AllowedIPs.

Adjust your server’s firewall to allow the WireGuard port (or other port), setup the WireGuard service, and now you’ll have a fast VPN where ever you go. I also have WireGuard on my phone and the nice thing about the iOS mobile client is that if I switch over to cellular or my phone connects to a WiFi network that isn’t my home, WireGuard automatically connects. My internal IP is that of my WireGuard server so I automatically have access to all resources over my IPSec VPNs. My internet comes from my home so it’s protected from snooping eyes of Starbucks.

For those who are visual, here’s how my VPN now looks:

Traffic now comes right to my WireGuard server in my house and that’s it. I’m NATted to my WireGuard server’s IP, but that’s it. It’s simple and fast!

Leave a Comment

Your email address will not be published. Required fields are marked *