Introduction

This guide explains VXLAN vs WireGuard: a simple setup on Ubuntu in a production-aware way, including the design choices, implementation checks, and operational safeguards that matter for Linux environments.

Prerequisites

Use a supported release, a tested backup, administrative access, a maintenance window when required, and a rollback plan. Validate DNS, time synchronization, firewall rules, storage, and monitoring before implementation.

Architecture and Core Concepts

Understand the data flow, trust boundaries, dependencies, and the expected state before changing a live environment. Separate control-plane configuration from data-plane traffic and document every external dependency.

Security Considerations

Production safety

  • Do not expose management interfaces or databases to the public Internet.
  • Store passwords, tokens, and private keys outside the article and source repository.
  • Patch dependencies, restrict administrative access, and retain audit logs.

VXLAN or WireGuard?

These tools solve different problems. VXLAN carries Ethernet frames over an IP network. WireGuard creates an encrypted IP tunnel. Choose VXLAN when you need a shared layer-two network; choose WireGuard for secure IP connectivity.

VXLAN does not encrypt traffic by itself. It can run over WireGuard when both Ethernet connectivity and encryption are required. Here we configure each separately so the first setup stays easy to follow.

Before you start

Use two Ubuntu 24.04 servers, A and B, with sudo access. For the VXLAN lab, their existing private addresses are 192.168.10.11 and 192.168.10.12. They must already reach each other; check with ping before creating a tunnel.

BASH
sudo apt update
sudo apt install -y iproute2 iputils-ping wireguard
ip -br address
ip route

Run this on both servers. Find the interface used to reach the other host; the examples use ens18. Use unused tunnel subnets that do not overlap your existing networks.

Set up VXLAN

On server A, create VNI 100 and give the tunnel address 10.20.0.1. VXLAN support is in the Linux kernel; iproute2 supplies the configuration commands. Allow UDP 4789 only between the two private endpoints if a firewall is active.

BASH
sudo ip link add vxlan100 type vxlan id 100 local 192.168.10.11 remote 192.168.10.12 dev ens18 dstport 4789
sudo ip link set dev vxlan100 mtu 1450
sudo ip address add 10.20.0.1/24 dev vxlan100
sudo ip link set dev vxlan100 up

On B, reverse the endpoint addresses and use 10.20.0.2 for the tunnel. Both sides must use VNI 100 and destination port 4789.

BASH
sudo ip link add vxlan100 type vxlan id 100 local 192.168.10.12 remote 192.168.10.11 dev ens18 dstport 4789
sudo ip link set dev vxlan100 mtu 1450
sudo ip address add 10.20.0.2/24 dev vxlan100
sudo ip link set dev vxlan100 up

From A, test the other tunnel address. MTU 1450 assumes an IPv4 underlay with MTU 1500; a smaller path needs a smaller tunnel MTU. This connects the two hosts without bridging their physical LANs.

BASH
ping -c 4 10.20.0.2
ip -d link show vxlan100

These ip commands are temporary and disappear after reboot. For this first lab, rerun them after reboot. For a permanent setup, recreate the same settings through your network manager. To remove this lab interface, use sudo ip link delete vxlan100.

Create WireGuard keys

On each server, create a separate key pair. Use a new folder and do not overwrite keys from an existing installation. Share only public.key with the other server; private.key stays on its owner.

BASH
mkdir -m 700 ~/wg-lab
cd ~/wg-lab
umask 077
wg genkey | tee private.key | wg pubkey > public.key
cat public.key
sudo install -d -m 700 /etc/wireguard

Configure WireGuard

A is the reachable endpoint: it needs a public IP or port forwarding for UDP 51820. B may sit behind NAT. In this example we connect only their tunnel addresses, so no IP forwarding or internet NAT is needed.

On A, edit /etc/wireguard/wg0.conf with sudo nano. Replace A_PRIVATE_KEY with the contents of A private.key and B_PUBLIC_KEY with B public.key. Do not leave placeholders in the file.

INI
[Interface]
Address = 10.30.0.1/24
ListenPort = 51820
PrivateKey = A_PRIVATE_KEY

[Peer]
PublicKey = B_PUBLIC_KEY
AllowedIPs = 10.30.0.2/32

On B, create the same file with the following contents. Replace the keys, and change 203.0.113.10 to the real public address of A; that address is reserved for documentation.

INI
[Interface]
Address = 10.30.0.2/24
PrivateKey = B_PRIVATE_KEY

[Peer]
PublicKey = A_PUBLIC_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.30.0.1/32
PersistentKeepalive = 25

AllowedIPs here routes only the remote tunnel IP. PersistentKeepalive on B maintains its NAT mapping. If UFW is already active on A, run sudo ufw allow 51820/udp; also permit the port in any cloud firewall. Do not enable a new firewall remotely without preserving SSH access.

Start and test WireGuard

On both servers, protect the configuration file and start the service. Do not run wg-quick up separately after starting it through systemd.

BASH
sudo chmod 600 /etc/wireguard/wg0.conf
sudo systemctl enable --now wg-quick@wg0
sudo wg show

From B, ping A to initiate traffic, then check wg show again. A recent handshake and increasing transfer counters indicate the peers are exchanging encrypted traffic. Unlike our temporary VXLAN commands, this WireGuard service starts after reboot.

BASH
ping -c 4 10.30.0.1
sudo wg show

When the connection fails

For VXLAN, check the original endpoint reachability, interface name, VNI and UDP 4789 rules. For WireGuard with no handshake, check the public endpoint, UDP 51820 and swapped public keys. If a handshake exists but ping fails, check AllowedIPs, tunnel addresses and ICMP firewall rules.

BASH
sudo systemctl status wg-quick@wg0 --no-pager
sudo journalctl -u wg-quick@wg0 -n 30 --no-pager

Once this works, extend it only for a concrete need: remote LAN access needs routing, while Ethernet extension needs a bridge design. Avoid adding either before you have tested the basic connection.

Troubleshooting

SymptomCause / CheckResolution
Service does not startCheck service status, logs, ports, permissions, and configuration syntax.Fix the reported dependency or syntax error, then restart and verify health checks.
Clients cannot connectValidate DNS, routing, firewall policy, TLS, and listening address from both endpoints.Allow only the required source and destination, reload safely, and retest with a controlled client.
Change caused an outageCompare the change with the last known-good version and inspect audit and application logs.Rollback the smallest possible change, restore service, then document the root cause and prevention.

Best Practices

  • Version-control configuration and review changes.
  • Use least privilege and explicit allow-lists.
  • Automate repeatable checks and monitor the expected state.
  • Test upgrades and restores before production rollout.

Conclusion

A reliable implementation of VXLAN vs WireGuard: a simple setup on Ubuntu is more than a successful first run. Keep the configuration documented, observable, recoverable, and aligned with the team's change-management process.

Frequently Asked Questions

Can this procedure be used in production without a maintenance window?

Only when the platform documents a safe reload or the change is isolated and rollback-tested; otherwise schedule a maintenance window.

What should be backed up before making the change?

Back up configuration, credentials held by the service, application data, and the current version of the deployment. Test the restore path.

How do I verify that the change really took effect?

Check the service health endpoint or status, inspect logs and metrics, and run a representative client-side test from the intended network zone.

What is the first check for a timeout or connection refusal?

Check listening ports, routing, firewall policy, DNS resolution, and whether the service is bound to the expected interface.

How should secrets and tokens be handled?

Use a secret manager or protected environment configuration, rotate them after exposure, and never commit them to Git or paste them into tickets.

How can this be automated safely?

Automate idempotent checks first, add dry-run support, require review for destructive operations, and emit logs and exit codes suitable for monitoring.

What should be monitored after deployment?

Monitor availability, error rate, latency, resource saturation, certificate expiry, failed jobs, and configuration drift.

When should I roll back instead of troubleshooting in place?

Rollback when the service is unavailable, data integrity is at risk, or the blast radius is growing faster than you can isolate it. Preserve logs first.

References

Linux kernel VXLAN documentation

ip-link command reference

WireGuard installation

WireGuard quick start and keys

wg-quick configuration reference

Share

Meet AJInfrastructure & DevOps
Loading…