Building a Private WireGuard Network Over the Internet

WireGuard is often described as a VPN, but it’s just as useful for building a private, encrypted network between machines without routing all of their internet traffic. This article walks through a simple hub-and-spoke design where peers communicate securely over the public Internet while continuing to use their own local internet connections.


Network Design

We’ll use the following private network:

  • VPN subnet: 10.20.0.0/21
  • Usable addresses: 10.20.0.110.20.7.254
  • Total usable hosts: 2046

In this design:

  • One server has a public IP address and acts as the WireGuard hub.
  • Clients can be behind NAT and have dynamic public IPs.
  • Internet traffic stays on each client’s normal connection.
  • Only traffic destined for the VPN subnet is sent through WireGuard.
               Internet

           Public WireGuard Hub
           203.0.113.10
             10.20.0.1
                 |
        ---------------------
        |         |         |
   10.20.0.2 10.20.0.3 10.20.0.4
    Laptop     Server      Phone

Why Use a /21?

A /21 subnet provides:

  • Network: 10.20.0.0
  • Broadcast: 10.20.7.255
  • Usable hosts: 2046

This leaves plenty of room to add peers without redesigning the network.

A suggested addressing scheme:

DeviceVPN Address
Hub10.20.0.1
Peer 110.20.0.2
Peer 210.20.0.3
Peer 310.20.0.4

Generating Keys

Each WireGuard peer requires its own unique key pair.

Generate one with:

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

The generated files are:

  • privatekey — keep secret
  • publickey — share with peers

A common place to store them is:

/etc/wireguard/

Ensure the private key is readable only by root.


Server Configuration

Example /etc/wireguard/wg0.conf:

[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.20.0.1/21
ListenPort = 51820

[Peer]
PublicKey = CLIENT_A_PUBLIC_KEY
AllowedIPs = 10.20.0.2/32

[Peer]
PublicKey = CLIENT_B_PUBLIC_KEY
AllowedIPs = 10.20.0.3/32

Notice that each peer is assigned a single /32 address in AllowedIPs. This tells WireGuard which VPN IP belongs to which peer.


Client Configuration

Example client configuration:

[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.20.0.2/21

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 10.20.0.0/21
PersistentKeepalive = 25

The important setting is:

AllowedIPs = 10.20.0.0/21

This means only traffic destined for the VPN subnet is routed through the tunnel.

Traffic to websites and the public Internet continues to use the client’s normal network connection.


How WireGuard Works Over the Internet

WireGuard uses encrypted UDP packets.

For example:

Outer Packet
-------------
Source:      198.51.100.23
Destination: 203.0.113.10
Protocol:    UDP
Port:        51820

Encrypted Payload
-----------------
Source:      10.20.0.2
Destination: 10.20.0.3

The Internet only sees encrypted UDP traffic between public IP addresses.

The private 10.20.x.x addresses exist only inside the encrypted tunnel.


Clients Behind NAT

Most WireGuard clients don’t have public IP addresses.

Typical examples include:

  • Home computers
  • Laptops
  • Mobile phones
  • Cloud VMs behind provider NAT

This is completely normal.

Clients initiate an outbound UDP connection to the hub, which records the client’s current public IP and UDP port.

Because residential ISPs and mobile networks often assign dynamic public IPs, clients should include:

PersistentKeepalive = 25

This sends a small packet every 25 seconds, keeping the NAT mapping alive and allowing the server to learn a client’s new public endpoint if it changes.


Internet Routing

A common misconception is that a VPN must carry all internet traffic.

It doesn’t.

This design intentionally uses split tunneling.

Destination: 10.20.x.x
    ↓
WireGuard

Destination: Everything Else
    ↓
Normal Internet Connection

This means:

  • Browsing continues through the user’s ISP.
  • Only private network traffic uses WireGuard.

No NAT or internet gateway configuration is required on the WireGuard hub.


Understanding Peers and Servers

WireGuard itself has no concept of “server” and “client.”

Every participant is a peer.

The machine with the public IP is commonly called the “server” simply because it listens for incoming connections and is always online.

From WireGuard’s perspective, however, every node is just another peer with a key pair and a routing configuration.


Protecting Local Services

One common concern is:

“If I connect my machine to WireGuard, can other peers access services running on my computer?”

The answer depends on how those services are configured.

If a service listens on:

0.0.0.0

it accepts connections on every network interface, including the WireGuard interface.

WireGuard itself does not control which services are reachable.

That is the job of your operating system’s firewall.

For example, you can allow only one peer to access a service:

iptables -A INPUT -i wg0 -s 10.20.0.2 -p tcp --dport 8080 -j ACCEPT
iptables -A INPUT -i wg0 -p tcp --dport 8080 -j DROP

Alternatively, many applications can be configured to listen only on their WireGuard address instead of 0.0.0.0.

For example:

10.20.0.2

instead of

0.0.0.0

This limits the service to the VPN interface and avoids exposing it on other network interfaces.


Can the Hub See Everything?

No.

With split tunneling:

  • The hub sees only traffic sent across the VPN.
  • It does not see normal web browsing or other internet traffic that stays on the client’s local network.

However, like any network endpoint, if a client sends data directly to a service running on the hub, that service can see the data it receives. WireGuard encrypts traffic in transit; it does not hide information from the endpoint that is intentionally receiving it.


Final Thoughts

WireGuard makes it straightforward to build a secure private network across the public Internet.

A simple hub-and-spoke topology provides:

  • Encrypted communication between peers
  • Support for clients behind NAT
  • Dynamic public IP handling
  • Split tunneling
  • Simple static addressing
  • Excellent performance

Combined with sensible firewall rules and good service binding practices, this architecture provides a clean, scalable foundation for private networking without forcing all internet traffic through a central VPN server.

Published on: 3 July
Posted by: Sami K.