Self-Hosting Your Own Cloud – Part 7: Building a Personal Private Network with WireGuard

About a year ago, I wrote about how to use OpenVPN to provide secure remote access to your home network and its resources to start building your own private cloud. I have been incrementally adding network services since.

Recently, I’ve started using WireGuard instead of OpenVPN. I’ve found that the configuration is far simpler, while also letting me create what I’ve started to call my “Personal Virtual Private Network” (PVPN).

Instead of simply connecting into your home network, you can use WireGuard to build out a new subnet without regard to the physical location of devices or which networks they’re physically connected to. This allows you to access your personal devices and services from anywhere you have an Internet connection. The devices (peers) are all accessible to one another on your PVPN.

1. Configure Your DNS

The first step is to define which hosts you want on your PVPN. Since I’m using Pi-Hole to block trackers and ads, I was able to define the hosts simply by editing the /etc/pihole/lan.list file on my Pi-Hole Raspberry Pi system. This file is set up like a standard hosts file on any modern system.

In my lan.list file, I already had DNS configuration for the hosts on my “home” network:

# ---------- Home Network ----------

## Home PC
10.10.10.50     desktop.home  media.home

# Cellular Connected via Wi-Fi
10.10.10.51     phone.private
10.10.10.52     laptop.private

## Data Backup Devices
10.10.10.100    onsite-backup.home

## Network Service Devices
10.10.10.252    dns.home
10.10.10.254    router.home

If this is the first time you are setting up DNS records for your home network, make sure the DHCP server on your router (or within Pi-Hole) points the MAC addresses of the machines to the corresponding IP addresses referenced in your DNS configuration.

To define the landscape of my PVPN, I can simply use a different domain name (“private”) to easily differentiate my home and private networks. Make sure to choose a different subnet; we’ll use it later when configuring WireGuard.

# ---------- Personal Private Network ----------
## Network Service Devices
192.168.99.10   wireguard.private
192.168.99.11   dns.private

## Data Backup Devices
192.168.99.20   onsite-backup.private
192.168.99.21   offsite-backup.private

## Cellular Devices
192.168.99.30   phone.private
192.168.99.31   laptop.private

## Home PC
192.168.99.40   home-desktop.private  media.private

## Work PC
192.168.99.50   work-desktop.private

Remember that it doesn’t matter where your devices are located physically or what network they’re directly connected to. In my case, I have devices that are on my home network, at work, at an offsite location, and on cellular networks.

After you make changes, you’ll need to run $ sudo pihole restartdns to restart Pi-Hole and make the changes active.

2. Install WireGuard

For each peer that will be part of your PVPN, install the WireGuard software:

3. Configure Peers

Generating Public and Private Keys for Peers

There are scripts available to manage peers on your PVPN.
I’ve chosen to manage my peers manually, including generating public and private keys, because the configuration is pretty easy.

I use a simple script (generate-keys.sh) to generate a public/private key pair:

#!/bin/sh

PRIVATE_KEY=`wg genkey`
PUBLIC_KEY=`echo $PRIVATE_KEY | wg pubkey`

echo Private Key: $PRIVATE_KEY
echo Public Key: $PUBLIC_KEY

Every time I want to generate the public/private key pair for a peer on my PVPN, I simply run $ ./generate-keys.sh. Running the script yields output in this format:

Private Key: GOBOeE6LNY6eBDSl/BNX0a6tsMl4I3ggkcBcjoo5wVU=
Public Key: 3+2GmFwqhKrjA6f5r83uNUl3YO+BtNwpDYh+HMJwYAI=

For each peer on my PVPN, I can simply copy and paste these keys to the appropriate places (which I’ll cover in the next section).

Primary Peer Configuration

The primary peer (analogous in my mind to a “server”) needs to be accessible on the Internet. Let’s call this machine pvpn.example.com. In my case, it’s a Raspberry Pi 4 on my home network that’s accessible on my home cable network connection through a port-foward on my home router (port 51820). I set up a CNAME for my domain name to point to the dynamic hostname of my home network cable Internet connection.

As long as the machines on your PVPN have the ability to get to pvpn.example.com, they will be able to connect. This could be machines far away from your home network or directly connected to it — it does not matter.

After installing WireGuard on my Raspberry Pi 4 (my primary peer), I setup my /etc/wireguard/wg0.conf configuration as follows:

[Interface]
Address = 192.168.99.10/32
ListenPort = 51820
PrivateKey = PRIVATE KEY for wireguard.private

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A
POSTROUTING -o wlan0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -
D POSTROUTING -o wlan0 -j MASQUERADE

[Peer]
PublicKey = PUBLIC KEY FOR dns.private
AllowedIPs = 192.168.99.11/32

[Peer]
PublicKey = PUBLIC KEY FOR dns.private
AllowedIPs = 192.168.99.11/32

[Peer]
PublicKey = PUBLIC KEY FOR onsite-backup.private
AllowedIPs = 192.168.99.20/32

[Peer]
PublicKey = PUBLIC KEY FOR offsite-backup.private
AllowedIPs = 192.168.99.21/32

[Peer]
PublicKey = PUBLIC KEY FOR phone.private
AllowedIPs = 192.168.99.30/32

[Peer]
PublicKey = PUBLIC KEY FOR laptop.private
AllowedIPs = 192.168.99.31/32

[Peer]
PublicKey = PUBLIC KEY FOR home-desktop.private
AllowedIPs = 192.168.99.40/32

[Peer]
PublicKey = PUBLIC KEY FOR work-desktop.private
AllowedIPs = 192.168.99.50/32

The Interface section configures the machine itself, while the Peer sections configure the peers allowed to connect into my PVPN. The PostUp and PostDown directives allow routing traffic out to the other machines on the physical network.

Other Peer Configurations

For each “regular” peer that connects to my WireGuard network, I’ve set up two configurations. My first configuration routes all traffic to the private network, including Internet traffic. This is good for use on untrusted networks. These configurations are setup for my laptop.private peer (192.168.99.31).

“Personal Private Virtual Network” + Internet Traffic

[Interface]
PrivateKey = PRIVATE KEY for laptop.private
Address = 192.168.99.31/24
DNS = 192.168.99.11

[Peer]
PublicKey = PUBLIC KEY for wireguard.private
AllowedIPs = 0.0.0.0/0
Endpoint = pvpn.example.com:51820
PersistentKeepalive = 120

In the WireGuard configuration UI on the peer, ensure that “Block Untunnelled Traffic” is enabled.

“Personal Private Virtual Network” Extension

[Interface]
PrivateKey = PRIVATE KEY for laptop.private
Address = 192.168.99.31/24
DNS = 192.168.99.11

[Peer]
PublicKey = PUBLIC KEY for wireguard.private
AllowedIPs = 192.168.99.0/24
Endpoint = pvpn.example.com:51820
PersistentKeepalive = 120

I want my connection to always be active, so I’ve configured my peers to send a keep-alive message every 120 seconds. Otherwise, my peers could drop off the network and become inaccessible to me. This is especially a problem for remote machines that require physical access to regain the connection.

Conclusion

Once you’ve got everything installed and configured, you should be able to connect your peers to your new PVPN. All of the existing services you have already hosted should be accessible as before with OpenVPN. In addition, all of the peers should be able to connect directly to one another, which was not possible using the OpenVPN setup.

We’re another step closer to our self-hosting goal. Later in this series, I’ll cover hosting alternatives to Gmail and Google Photos and building up more network services.

Upcoming Posts

  1. Setting up OpenVPN
  2. SMB File Server with Automated Backups using Rsync/Rclone
  3. Note-taking with Nextcloud & Syncthing
  4. Movies and Music using Emby
  5. Protect Yourself Online with Privacy Tools
  6. Ad and Tracker Blocking with Pi-Hole
  7. Building a Personal Private Network with WireGuard
  8. Creating your Own Certificate Authority and Reverse Proxying Services with Caddy
  9. Note-taking with Standard Notes
  10. Email, Contacts, and Calendars
  11. Photos and Home Movies using Custom Tool
Conversation
  • Alex says:

    Hello,
    Firstly, thanks for the comprehensive guide, it is really appreciated.

    In your sample configuration text, I found a few inconsistencies and I’m not sure if they are typo’s or correct (and my understanding of wireguard is incorrect).

    I was hoping you could take a look and comment on the following.

    1) In lan.list you have phone.private and laptop.private down twice in both Home Network and Personal Private Network lists. I assume two of those should be .home.

    2) In the /etc/wireguard/wg0.conf for the ‘primary peer’ you have [Peer] dns.private entry listed twice?

    3) In /etc/wireguard/wg0.conf for the ‘primary peer’, should the [Interfce] Address entry be /24 or /32? The wireguard documentation suggest /24 for nodes that are routing between nodes, and /32 for connected ‘client’ type nodes (https://github.com/pirate/wireguard-docs#Address)

    4) Similar to 3, should the other Peer nodes /etc/wireguard/wg0.conf have a /32 rather than /24 in their [Interface] Address sections?

    I will be testing all this soon and will probably stumble across the answers, but thought I should seek clarification here first to save me a few hours! ;)

    Thanks again for your great articles.

    Cheers,

    alex

  • Tanner says:

    Hi, first off great guide! I did have one question about this sentence.

    “I set up a CNAME for my domain name to point to the dynamic hostname of my home network cable Internet connection.”

    What exactly did setting up that CNAME entail? Did you have to register it with some web service like GoDaddy or is there some other option?

    Thanks!

  • This article provides details about the private network wireguard. I enjoyed reading this article and would suggest others it as well. Thank you for this article! This is really very informative for us and look forward to more such in future for all of us.

  • Comments are closed.