VPN / Networking

WireGuard Mesh VPN

Connecting Vultr, Oracle Cloud, and AWS into one private network. DC01 on Vultr is the hub. Every other machine connects to it as a peer. All machines use the DC as their DNS server so Active Directory works across all three clouds.

WireGuard mesh VPN connecting multi-cloud AD infrastructure
WireGuard mesh stitching Vultr, Oracle, and AWS into one private network
WireGuard 0.5.3
Windows Server 2022
Ubuntu 24.04
Oracle Linux 8
Multi-Cloud Mesh
Ed25519 Keys
Kernel Module
Hub & Spoke

Why WireGuard

Vultr, Oracle Cloud, and AWS are completely separate networks. By default they cannot reach each other at all. Active Directory relies on constant communication — LDAP, Kerberos, DNS, replication — between all machines. Without a VPN, a machine on Oracle Cloud has no way to contact the Domain Controller on Vultr.

WireGuard creates an encrypted Layer 3 tunnel. Each machine gets a private IP in the 10.10.0.0/24 range. DC01 at 10.10.0.1 is the hub — every other machine connects to it as a peer. The hub routes traffic between all peers.

graph TB HUB["STARK-TOWER
10.10.0.1
WireGuard Hub
Vultr"] P2["VOUGHT-HQ
10.10.0.2
Oracle Cloud"] P3["BATCAVE
10.10.0.3
Oracle Cloud"] P4["FLATIRON
10.10.0.4
Vultr"] P5["WATCHTOWER
10.10.0.5
AWS EC2"] HUB <-->|"UDP 51820"| P2 HUB <-->|"UDP 51820"| P3 HUB <-->|"UDP 51820"| P4 HUB <-->|"UDP 51820"| P5 style HUB fill:#1a3a1a,stroke:#a4ff91,color:#fff

Step 1 — Install WireGuard on DC01 (Windows)

Downloaded and installed WireGuard on the Windows Server from PowerShell:

PowerShell
PS> Invoke-WebRequest -Uri "https://download.wireguard.com/windows-client/wireguard-installer.exe" -OutFile "C:\wireguard-installer.exe" PS> Start-Process "C:\wireguard-installer.exe" -Wait

After installation, opened the WireGuard GUI. The first step is creating a new tunnel from the dropdown.

WireGuard GUI on Windows showing the empty interface with the dropdown menu to add a tunnel
WireGuard opened — using the dropdown to create a new tunnel

Step 2 — Key Generation

WireGuard uses public/private key pairs. Each machine generates its own pair. On Windows, the GUI generates keys automatically when you create a new tunnel. On Linux, you generate them manually.

The keys used for DC01 in this lab:

DC01 Keys — for reference
PublicKey  = /qe58vBz5fDxhCmq9OQ3Nc+CjVHWluCsD7IQfb+UsAc=
# PrivateKey stays on the server — never share it
Key Generation on Linux

On Linux machines, generate keys with: wg genkey | sudo tee /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key — then copy the public key and add it as a peer on DC01.

Step 3 — Create the Hub Tunnel on DC01

In WireGuard on DC01, clicked "Add Tunnel" → "Create New Tunnel". The interface section was filled in like this:

WireGuard Config — DC01 [Interface] section
[Interface]
PrivateKey = <DC01-PRIVATE-KEY>
Address = 10.10.0.1/24
ListenPort = 51820
DNS = 127.0.0.1
WireGuard new tunnel dialog on Windows DC01 showing the Interface section with Address 10.10.0.1 and ListenPort 51820
Tunnel config on DC01 — Address is 10.10.0.1/24, ListenPort is 51820

After saving and activating, the tunnel shows as active with the public key, listener port, and address.

WireGuard GUI showing the tunnel is active with its public key and 10.10.0.1 address displayed
Tunnel active — public key shown, address confirmed at 10.10.0.1

Step 4 — Verify the Interface on Windows

Ran ipconfig to confirm the WireGuard virtual adapter appeared with the right IP:

ipconfig output on Windows showing WireGuard adapter with IP address 10.10.0.1
ipconfig confirms WireGuard adapter is up at 10.10.0.1
PowerShell — list adapters
PS> Get-NetAdapter | Format-Table Name, Status, InterfaceDescription
PowerShell Get-NetAdapter output listing WireGuard Tunnel adapter alongside the main Ethernet adapter, both showing Up status
WireGuard adapter visible alongside the main Ethernet — both showing Up

Also confirmed the Windows Firewall had the WireGuard inbound rule enabled:

Windows Firewall advanced rules showing WireGuard inbound rule is enabled and set to Allow
Firewall rule for WireGuard — inbound, allow, enabled

Step 5 — Oracle Machine Peer Config

For the Oracle Windows machine (VOUGHT-HQ), a tunnel was created pointing back at DC01. The Oracle machine gets WireGuard IP 10.10.0.2.

WireGuard Config — Oracle peer (/etc/wireguard/wg0.conf or GUI)
[Interface]
PrivateKey = <ORACLE-MACHINE-PRIVATE-KEY>
Address = 10.10.0.2/24
ListenPort = 51820

[Peer]
PublicKey = /qe58vBz5fDxhCmq9OQ3Nc+CjVHWluCsD7IQfb+UsAc=
AllowedIPs = 10.10.0.0/24
Endpoint = <DC01-VULTR-PUBLIC-IP>:51820
PersistentKeepalive = 25
WireGuard GUI on the Oracle machine showing tunnel config with DC01 as the peer and address 10.10.0.2
WireGuard configured on the Oracle machine — peers with DC01 at 10.10.0.1

Both machines' WireGuard GUIs side by side — machine 1 at 10.10.0.1 and machine 2 at 10.10.0.2:

WireGuard on DC01 showing active tunnel with address 10.10.0.1
DC01 WireGuard — hub at 10.10.0.1
WireGuard on Oracle machine showing active tunnel with address 10.10.0.2 and DC01 listed as peer
Oracle machine WireGuard — peer at 10.10.0.2

Step 6 — Add Oracle Machine as Peer on DC01

Back on DC01, edited the existing tunnel and added the Oracle machine as a peer. Each new machine you add gets its own [Peer] block:

DC01 wg0 — add Oracle peer
[Peer]
PublicKey = OVSXZgFPNAVYFGWiAiZX+1ZO+wtFZs7fLeePju9eAB0=
AllowedIPs = 10.10.0.2/32
Endpoint = <ORACLE-PUBLIC-IP>:51820
PersistentKeepalive = 25

# Add one [Peer] block per machine:
# 10.10.0.3/32 = BATCAVE (Oracle Linux)
# 10.10.0.5/32 = WATCHTOWER (AWS Jenkins)

Step 7 — Verify the Tunnel is Working

Pinged from DC01 to the Oracle machine and back. Both should reply through the tunnel.

PowerShell ping from DC01 to 10.10.0.2 showing successful replies with 14ms latency
Ping from DC01 to Oracle machine — tunnel is working
Terminal ping from Oracle machine back to DC01 at 10.10.0.1 showing successful replies
Ping back from Oracle to DC01 — both directions working

Step 8 — DNS Configuration for Active Directory

WireGuard only creates a routed tunnel — it does not handle DNS. Every machine that needs to contact AD must use the DC's WireGuard IP (10.10.0.1) as its primary DNS server. Without this, the machine cannot resolve hq.apex-corp.xyz and domain join will fail.

# Point DNS at DC01 via WireGuard IP
$adapter = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select-Object -First 1
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex `
  -ServerAddresses "10.10.0.1","8.8.8.8"

# Verify it resolves AD names
nslookup stark-tower.hq.apex-corp.xyz
# Create /etc/netplan/99-custom-dns.yaml
network:
  version: 2
  ethernets:
    enp39s0:          # replace with your interface name (ip link show)
      nameservers:
        addresses: [10.10.0.1, 8.8.8.8]
        search: [hq.apex-corp.xyz]
      dhcp4-overrides:
        use-dns: false
        use-domains: false

# Apply
sudo chmod 600 /etc/netplan/99-custom-dns.yaml
sudo netplan try
# /etc/krb5.conf — required for Linux AD domain join
[libdefaults]
    default_realm = HQ.APEX-CORP.XYZ
    rdns = false       # ← without this, domain join fails silently

[realms]
    HQ.APEX-CORP.XYZ = {
        kdc = stark-tower.hq.apex-corp.xyz
        admin_server = stark-tower.hq.apex-corp.xyz
    }

[domain_realm]
    .hq.apex-corp.xyz = HQ.APEX-CORP.XYZ
    hq.apex-corp.xyz = HQ.APEX-CORP.XYZ

Full Tunnel Map

Machine WireGuard IP Cloud Role
STARK-TOWER (DC01)10.10.0.1VultrHub — all peers connect here
VOUGHT-HQ (DC02)10.10.0.2Oracle CloudChild DC peer
BATCAVE (LINUX01)10.10.0.3Oracle CloudAD-joined Linux peer
FLATIRON (WS01)10.10.0.4VultrWorkstation peer
WATCHTOWER (LINUX02)10.10.0.5AWS EC2Jenkins server peer
All peers reachable from BATCAVE (Oracle Linux)
$ ping -c 2 10.10.0.1 && ping -c 2 10.10.0.2 && ping -c 2 10.10.0.5
64 bytes from 10.10.0.1: icmp_seq=1 ttl=128 time=14.2 ms ← DC01 Vultr
64 bytes from 10.10.0.2: icmp_seq=1 ttl=128 time=17.8 ms ← VOUGHT Oracle
64 bytes from 10.10.0.5: icmp_seq=1 ttl=64 time=48.3 ms ← WATCHTOWER AWS
[+] All three cloud providers reachable through WireGuard hub
$ nslookup stark-tower.hq.apex-corp.xyz
Server: 10.10.0.1
Address: 10.10.0.1#53

Name: stark-tower.hq.apex-corp.xyz
Address: 10.10.0.1
[+] DNS working — AD domain resolves through VPN

Mesh Verification Checklist