VyOS - Site-to-Site VPN Using Wireguard and OSPF

Connecting two sites securely and efficiently is essential for many businesses and individuals.

In this post, we’ll explore how to achieve seamless connectivity between two locations using the powerful combination of WireGuard, a modern and high-performance VPN protocol, and VyOS, a robust and versatile network operating system.

Whether you’re looking to enhance communication between remote offices, create a secure link between your data center and a cloud-based infrastructure, or simply want to connect two geographically separated sites, this guide will walk you through the process, ensuring a reliable and secure connection every step of the way.

To illustrate this process, I will use my own use case as an example. I manage equipment hosted in a colocation data center, which I affectionately refer to as my ‘colo-lab’, and I also maintain a ‘home-lab’.

Previously, I relied on GRE over IPsec for connectivity between the two sites, but I’ve recently migrated these over to WireGuard.

WireGuard boasts a slew of compelling advantages over traditional IPsec, including speed, security, and a refreshingly straightforward setup. Its minimalist design significantly simplifies the configuration process, especially when compared to the complexity of GRE over IPsec.

Throughout this post, I’ll walk you through the precise steps I took to configure two VyOS routers to seamlessly integrate with WireGuard while enabling efficient route distribution through OSPF. By the end, you’ll be equipped with the knowledge to configure your own WireGuard based site-to-site VPN.

Topology

Colo Lab

  • WireGuard Interface IP: 10.254.2.0/31
  • Internal Networks:
    • 10.254.112.0/24
    • 10.254.113.0/24
    • 10.254.114.0/24
  • Internal Network Aggregate: 10.254.112.0/21
  • Public IP: Refered to as ${COLO_LAB_PUBLIC_IP}

Home Lab

  • WireGuard Interface IP: 10.254.2.1/31
  • Internal Networks:
    • 10.254.88.0/24
    • 10.254.89.0/24
    • 10.254.90.0/24
  • Internal Network Aggregate: 10.254.88.0/21
  • Public IP: None (It’s behind CGNAT)

Generate Keypairs

First things first, let’s generate keypairs for both routers. Make note of these, and keep them safe.

First the cololab router:

mhamzahkhan@cololab-gw:~$ generate pki wireguard key-pair
Private key: <- OMITTED - USE YOUR OWN ONE - I will refer to this as ${COLOLAB_PRIVATE_KEY} ->
Public key: <- OMITTED - USE YOUR OWN ONE - I will refer to this as ${COLOLAB_PUBLIC_KEY} ->

Then the homelab router:

mhamzahkhan@homelab-gw:~$ generate pki wireguard key-pair
Private key: <- OMITTED - USE YOUR OWN ONE - I will refer to this as ${HOMELAB_PRIVATE_KEY} ->
Public key: <- OMITTED - USE YOUR OWN ONE - I will refer to this as ${HOMELAB_PUBLIC_KEY} ->

Configure WireGuard Interfaces

Next, let’s set up the WireGuard interfaces.

For these interfaces, I’ve chosen a private /31 range, which gives us precisely two IP addresses, perfect for a point-to-point link. In my example, we’ll use 10.254.2.0/31 and 10.254.2.1/31.

Colo Lab Router Configuration

Please note that because my home lab’s internet connection is behind CGNAT, I haven’t specified the peer address on the Colo Lab router. This means that the connection will be initiated from the home-lab side. If you have a static IP address (or dynamic IP address that doesn’t change much), it would be a good idea to specify the peer address so the connection can be initiated from either side.

mhamzahkhan@cololab-gw:~$ configure
[edit]
set interfaces wireguard wg0 address '10.254.2.0/31'
set interfaces wireguard wg0 description 'Connection to Home-Lab'
set interfaces wireguard wg0 ip adjust-mss '1380'
set interfaces wireguard wg0 mtu '1420'
set interfaces wireguard wg0 peer home-lab allowed-ips '0.0.0.0/0'
set interfaces wireguard wg0 peer home-lab persistent-keepalive '10'
set interfaces wireguard wg0 peer home-lab public-key '${HOMELAB_PUBLIC_KEY}'
set interfaces wireguard wg0 port '51820'
set interfaces wireguard wg0 private-key '${COLOLAB_PRIVATE_KEY}'

Home Lab Router Configuration

mhamzahkhan@homelab-gw:~$ configure
[edit]
set interfaces wireguard wg0 address '10.254.2.1/31'
set interfaces wireguard wg0 description 'Connection to Colo-Lab'
set interfaces wireguard wg0 ip adjust-mss '1380'
set interfaces wireguard wg0 mtu '1420'
set interfaces wireguard wg0 peer colo-lab address '${COLO_LAB_PUBLIC_IP}'
set interfaces wireguard wg0 peer colo-lab allowed-ips '0.0.0.0/0'
set interfaces wireguard wg0 peer colo-lab persistent-keepalive '10'
set interfaces wireguard wg0 peer colo-lab port '51820'
set interfaces wireguard wg0 peer colo-lab public-key '${COLOLAB_PUBLIC_KEY}'
set interfaces wireguard wg0 port '51820'
set interfaces wireguard wg0 private-key '${HOMELAB_PRIVATE_KEY}'

Test WireGuard connection

At this point, both routers should be able to ping each other via the VPN link:

mhamzahkhan@cololab-gw:~$ ping 10.254.2.1 count 4
PING 10.254.2.1 (10.254.2.1) 56(84) bytes of data.
64 bytes from 10.254.2.1: icmp_seq=1 ttl=64 time=0.339 ms
64 bytes from 10.254.2.1: icmp_seq=2 ttl=64 time=0.382 ms
64 bytes from 10.254.2.1: icmp_seq=3 ttl=64 time=0.344 ms
64 bytes from 10.254.2.1: icmp_seq=4 ttl=64 time=0.347 ms

--- 10.254.2.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3106ms
rtt min/avg/max/mdev = 0.339/0.353/0.382/0.017 ms

mhamzahkhan@homelab-gw:~$ ping 10.254.2.0 count 4
PING 10.254.2.0 (10.254.2.0) 56(84) bytes of data.
64 bytes from 10.254.2.0: icmp_seq=1 ttl=64 time=0.290 ms
64 bytes from 10.254.2.0: icmp_seq=2 ttl=64 time=0.227 ms
64 bytes from 10.254.2.0: icmp_seq=3 ttl=64 time=0.404 ms
64 bytes from 10.254.2.0: icmp_seq=4 ttl=64 time=0.380 ms

--- 10.254.2.0 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3078ms
rtt min/avg/max/mdev = 0.227/0.325/0.404/0.070 ms

To gauge the bandwidth between our networks, we can use iPerf3.

First start start iPerf3 in server mode on either side of the VPN. I’m running it on the colo lab router:

mhamzahkhan@cololab-gw:~$ iperf3 -s
-----------------------------------------------------------
Server listening on 5201 (test #1)
-----------------------------------------------------------

Next, start iPerf3 on the home lab router. Let’s start with an upload bandwidth test from the home-lab router to the colo-lab router:

mhamzahkhan@homelab-gw:~$ iperf3 -c 10.254.2.0
Connecting to host 10.254.2.0, port 5201
[  5] local 10.254.2.1 port 33008 connected to 10.254.2.0 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  20.8 MBytes   174 Mbits/sec   99    207 KBytes
[  5]   1.00-2.00   sec  20.7 MBytes   174 Mbits/sec    0    269 KBytes
[  5]   2.00-3.00   sec  19.8 MBytes   166 Mbits/sec  131    194 KBytes
[  5]   3.00-4.00   sec  22.1 MBytes   185 Mbits/sec    0    263 KBytes
[  5]   4.00-5.00   sec  17.3 MBytes   145 Mbits/sec  195   18.7 KBytes
[  5]   5.00-6.00   sec  16.4 MBytes   137 Mbits/sec   63    224 KBytes
[  5]   6.00-7.00   sec  19.9 MBytes   167 Mbits/sec   95    168 KBytes
[  5]   7.00-8.00   sec  11.3 MBytes  95.2 Mbits/sec  123    123 KBytes
[  5]   8.00-9.00   sec  18.9 MBytes   158 Mbits/sec    0    202 KBytes
[  5]   9.00-10.00  sec  20.2 MBytes   169 Mbits/sec   35    207 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec   187 MBytes   157 Mbits/sec  741             sender
[  5]   0.00-10.01  sec   186 MBytes   156 Mbits/sec                  receiver

iperf Done.

I’m not sure why there are retransmissions. I still need to investigate that, but it’s maxing out my home connection upload.

Now, let’s reverse the test, with the colo-lab router sending data to the home-lab router. Use the -R flag for this:

mhamzahkhan@homelab-gw:~$ iperf3 -c 10.254.2.0 -R
Connecting to host 10.254.2.0, port 5201
Reverse mode, remote host 10.254.2.0 is sending
[  5] local 10.254.2.1 port 52016 connected to 10.254.2.0 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  14.8 MBytes   124 Mbits/sec
[  5]   1.00-2.00   sec  17.4 MBytes   145 Mbits/sec
[  5]   2.00-3.00   sec  17.6 MBytes   148 Mbits/sec
[  5]   3.00-4.00   sec  15.5 MBytes   130 Mbits/sec
[  5]   4.00-5.00   sec  16.3 MBytes   137 Mbits/sec
[  5]   5.00-6.00   sec  12.2 MBytes   102 Mbits/sec
[  5]   6.00-7.00   sec  9.33 MBytes  78.3 Mbits/sec
[  5]   7.00-8.00   sec  7.86 MBytes  65.9 Mbits/sec
[  5]   8.00-9.00   sec  14.7 MBytes   124 Mbits/sec
[  5]   9.00-10.00  sec  15.3 MBytes   128 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.01  sec   142 MBytes   119 Mbits/sec  282             sender
[  5]   0.00-10.00  sec   141 MBytes   118 Mbits/sec                  receiver

iperf Done.

Some tuning may be needed, but for now, these numbers should suffice.

Configure OSPF

Now, let’s dive into OSPF configuration. Note that I use OSPF route summarization, which means we summarize individual subnets on each side into a single summary route, simplifying the routing table.

Colo Lab Router

set protocols ospf area 0.0.0.0 network '10.254.2.0/31'
set protocols ospf area 0.0.0.1 network '10.254.112.0/24'
set protocols ospf area 0.0.0.1 network '10.254.113.0/24'
set protocols ospf area 0.0.0.1 network '10.254.114.0/24'
set protocols ospf area 0.0.0.1 range 10.254.112.0/21
set protocols ospf interface eth0 passive
set protocols ospf log-adjacency-changes
set protocols ospf parameters router-id '10.254.2.0'

Home Lab Router

set protocols ospf area 0.0.0.0 network '10.254.2.0/31'
set protocols ospf area 0.0.0.1 network '10.254.88.0/24'
set protocols ospf area 0.0.0.1 network '10.254.89.0/24'
set protocols ospf area 0.0.0.1 network '10.254.90.0/24'
set protocols ospf area 0.0.0.1 range 10.254.88.0/21
set protocols ospf interface eth0 passive
set protocols ospf log-adjacency-changes
set protocols ospf parameters router-id '10.254.2.1'

And magically your routes should be in your routing table!

Colo Lab Router

mhamzahkhan@cololab-gw:~$ show ip route 10.254.88.0
Routing entry for 10.254.88.0/21
  Known via "ospf", distance 110, metric 2, best
  Last update 11:58:19 ago
  * 10.254.2.1, via wg0, weight 1

Home Lab Router

mhamzahkhan@homelab-gw:~$ show ip route 10.254.88.0
Routing entry for 10.254.112.0/21
  Known via "ospf", distance 110, metric 2, best
  Last update 12:00:02 ago
  * 10.254.2.0, via wg0, weight 1

Conclusion

With the successful implementation of WireGuard VPN and OSPF routing, your two sites can now seamlessly communicate, marking a significant step in enhancing your network capabilities. While this guide has laid a solid foundation for your site-to-site VPN, there’s more to explore and build upon in future configurations.

In my next post, we will discuss configuring a VyOS-based WireGuard VPN for road-warrior style clients. This will enable secure remote access to your network, allowing you to connect from virtually anywhere with an internet connection. I will guide you through the setups, ensuring you have the tools to establish a secure and efficient network for remote users.

Stay tuned for this next installment, where we continue to harness the power of WireGuard and VyOS to expand the horizons of your network. Elevate your connectivity and security to new heights, and don’t miss out on future updates and valuable networking insights—subscribe and stay connected!

Posts in this series

Related Posts

comments