Mastodon

January 20, 2023

832 words 4 mins read

VXLAN over WireGuard

VXLAN over WireGuard

Tunnelling VXLAN over WireGuard

What is a VXLAN, I’m just going to Quote Juniper

“VXLAN is an encapsulation protocol that provides data center connectivity using tunneling to stretch Layer 2 connections over an underlying Layer 3 network.

In data centers, VXLAN is the most commonly used protocol to create overlay networks that sit on top of the physical network, enabling the use of virtual networks. The VXLAN protocol supports the virtualization of the data center network while addressing the needs of multi-tenant data centers by providing the necessary segmentation on a large scale."

So it’s a way to stretch a Layer 2 network between data centers and sites. This is great but what if you don’t have a leased line between sites or an existing VPN, can we bundle it all into one config/pair of devices. A VXLAN server at Site A and a VXLAN Client at Site B, with Site A having the network you’d like to extend into Site B:

Image

Here’s a representation of how the NICs are arranged and used in both the server and client. Image

Firstly lets give VXLAN Server IP address on it’s northbound NIC, in this case DHCP:

/etc/hostname.nic0
inet autoconf

Secondly lets setup a WireGuard Server listenning on port 51820 Refer to Man Page for how to generate the keys and how WireGuard works on OpenBSD

/etc/hostname.wg0
wgkey <PrivateKey> 
inet 192.168.100.1/24
wgport 51820
wgpeer <PublicKey> wgpsk <PSK> wgaip 192.168.100.2/32 

  • wgkey is this servers privatekey generated with the openssl rand -base64 32 command
  • inet assignes the IP 192.168.100.1 to the interface wg0
  • wgport is the listen port
  • wgpeer PublicKey is the public key of the client(other end device). You can view this by running this on the client: ifconfig wg0 | grep wgpubkey
  • PSK is a PreShared Key that is identical on both the Server and the Client again you can generate that with this command: openssl rand -base64 32
  • wgaip is the IPs allowed in via the tunnel, I’ve kept this to the single IP of the opposing peer, as we’re only going to talking on those single IPs, no need to route more traffic than is needed.

For the Client again lets give it a DHCP IP:

/etc/hostname.nic0
inet autoconf

/etc/hostname.wg0
inet 192.168.100.2/24
wgkey <PrivateKey>
wgpeer <PublicKey> wgendpoint <Public IP of Server> 51820 wgpsk <PSK> wgaip 192.168.100.1/32
up

Note on the Client side of the config you need to set the wgendpoint IP address and port, this should be the publically reachable IP address of the server, which could be behind a NAT.
At this point you shoule be able to ping both ends of the WireGuard Tunnel, 192.168.100.1 and 192.168.100.2 from both the Server and the Client device.
If you can’t your config is wrong. Be sure you have Your Private key in the wgkey setting and you have the other ends Public key in the peer settings. Similarly the inet IP address should be your IP but the wgaip should be the other ends IP. The only shared information should be the PSK.

Now we can setup the VXLAN over the VPN, on the server we need:

/etc/hostname.vxlan0
tunnel 192.168.100.1 192.168.100.2 vnetid 5
up
The tunnel line above the first IP is our(the Server’s IP) the second IP is the destination(Client IP) The vnetid is just an identifier in much the same way as a VLAN ID number - both ends should use the same vnetid

At the Client end we need:

/etc/hostname.vxlan0
tunnel 192.168.100.2 192.168.100.1 vnetid 5
up
This is the same as the server config but with the IP destination and source swapped.

At this point we have vxlan0 at both the client and server replicating each others ethernet traffic but they’re both virtual and so not connected to anything outside the servers.

Firstly lets bring up the southbound NIC:

/etc/hostname.nic1
up
This is the same for both the Server and Client.

Now we need to bridge them (Again this is the same on both the Server and the Client):

/etc/hostname.bridge0
add vxlan0
add nic1
up

At this point you should be up and running, you should now be able to DHCP for an address in site B and get a DHCPOFFER from site B and be able to ARP each other.

The order interfaces are brought up with netstart is hardcoded and vxlan is attempted prior to wg - we need wg to come up first.
Previously I was re-running netstart at boot from cron to get around this Florian kindly suggested adding:

!sh /etc/netstart vxlan0 to /etc/hostname.wg0

A couple of points since this got a wider view than I was expecting, yes this isn’t a great idea for a long term solution but it worked for the few weeks it was needed while the Point to Point circuit it was replicating was fixed OpenBSD is clear MTU is going to be a problem Someone also suggested using veb rather than bridge I must admit I’d never heard of veb before but would definately try that in the future