OSPF routing with GRE over Wireguard with VyOS router

Today we will have a look at how to run dynamic routing protocol over Wireguard. Due to some design choices how Wireguard works, there is no good mechanism of running directly dynamic protocols like OSPF over Wireguard tunnels when more than two (2) sites are involved in the routing domain. Readers are welcome to have  a look at this to know more about about it and the warning
Warning: The protocol design of WireGuard requires that 'allowed-ips' must not overlap on a single interface. To add another OSPF link to the server, you will need to create wg02 on a different port.
Instead we will use our good old friend - GRE to the rescue. We will use the concept of passenger/carrier protocol. Routing or data traffic will be encapsulated in GRE (passenger), then it will be encrypted and carried by Wireguard to the final destination.

When we are doing two levels of encapsulation, it was always better to know about the protocol overheads involved, so that we can avoid packet fragmentation. Let's have a look at a data packet and try to understand how it is tunneled -

IP packet (1500) = IP Header Wireguard (20) + UDP (8) + Wireguard Header (16) + IP Header GRE (20) + GRE Header (4) + Original IP Header (20) + Original TCP Header (20) + Original Data Payload (1392).

In above all the calculation is shown in 'bytes', using a standard 1500 bytes packet and form the outermost to the innermost encapsulation of a packet. In our setup we can carry at most 1392 bytes of actual data payload when using TCP without fragmentation.

For introduction of how Wireguard works and basic configuration steps I refer to my previous blog post.

Network Topology

Our physical topology looks like below and the router in the middle (Internet-Router) just does the gateway responsibility for different sites.
01 - Physical Topology and Addressing

Now we will look at the logical topology from GRE perspective. At this layer/tunnel the actual data/routing information passes. And our routing topology is hub and spoke. Everyone will from routing neighbor relation will with the Hub (Site-A) and traffic between spokes (Site-B and Site-C) goes through the Hub.
02 - GRE Tunnels and OSPF Topology

Then comes the Wireguard part. In our topology, we are using Wireguard tunnels to just encrypt GRE tunnel traffic. It does not do anything else. Wireguard's sole responsibility here is to encrypt and carry GRE traffic, deliver it to the final destination; nothing else. Hub (Site-A) will not actively create any wireguard tunnel to the Spokes (Site-B and Site-C). The Hub will act as responder only. It is the spokes are initiators and will try actively to create a wireguard tunnel with the hub.
03 - Wireguard Tunnels Topology

Network Configuration
  
Site-A (Hub) configuration

Basic IP address and routing configuration so that Site-A can reach other sites.

vyos@Site-A-Vyos# show interfaces 
 ethernet eth0 {
     address 192.168.254.2/30
     description Internet
 }
 ethernet eth3 {
     address 10.203.1.1/24
     description Lan-Site-A
 }
 loopback lo {
     address 10.203.4.1/32
 }

vyos@Site-A-Vyos# show protocols static 
 route 0.0.0.0/0 {
     next-hop 192.168.254.1 {
     }
 }

Now we will configure the Wireguard tunnel - 

vyos@Site-A-Vyos# show interfaces wireguard 
 wireguard wg0 {
     address 10.203.5.1/24
     description Wireguard-Vpn
     !!! Configuration for Site-B
     peer Site-B {
         allowed-ips 10.203.5.2/32
         persistent-keepalive 15
         pubkey FYrhCXZfyV8mj1P8oTxuTFJHv6lUZxnck8dfKfwhbQQ=
     }
     !!! Configuration for Site-C
     peer Site-C {
         allowed-ips 10.203.5.3/32
         persistent-keepalive 15
         pubkey ZWL68uHuWGTm/sXRecGC3L7zZSb+uykQnsnEGjQr4TI=
     }
     port 55555
 }

Now will create two GRE tunnels (Site-B and Site-C).

vyos@Site-A-Vyos# show interfaces tunnel 
 tunnel tun0 {
     address 10.203.6.1/30
     description Gre-Site-B
     encapsulation gre
     !!! Local and remote IP for GRE is our respective Wireguard IP addresses
     !!! This makes sure traffic is encrypted through Wireguard  
     local-ip 10.203.5.1
     remote-ip 10.203.5.2
     !!! Manually setting MTU to avoid fragmentation 
     mtu 1400
 }
 tunnel tun1 {
     address 10.203.6.5/30
     description Gre-Site-C
     encapsulation gre
     local-ip 10.203.5.1
     remote-ip 10.203.5.3
     !!! Manually setting MTU to avoid fragmentation
     mtu 1400
 }

vyos@Site-A-Vyos# show firewall options 
 interface tun0 {
     !!! Manually setting TCP MSS to avoid fragmentation
     adjust-mss 1360
 }
 interface tun1 {
     !!! Manually setting TCP MSS to avoid fragmentation
     adjust-mss 1360
 }

Now we will configure OSPF routing over GRE tunnels -

vyos@Site-A-Vyos# show protocols ospf 
 area 0 {
     !!! Advertising loopback network
     network 10.203.4.0/24
     !!! Advertising Lan network     
     network 10.203.1.0/24
     !!! Advertising GRE network
     network 10.203.6.0/24
 }
 log-adjacency-changes {
     detail
 }
 parameters {
     abr-type cisco
     router-id 10.203.4.1
 }
 passive-interface default
 !!! Active interfaces in OSPF are tun0 and tun1 only
 passive-interface-exclude tun0
 passive-interface-exclude tun1


vyos@Site-A-Vyos# show interfaces tunnel tun0
 ip {
     ospf {
         !!! Ignoring MTU size for OSPF neighbor selection
         mtu-ignore
     }
 }
vyos@Site-A-Vyos# show interfaces tunnel tun1
 ip {
     ospf {
         !!! Ignoring MTU size for OSPF neighbor selection
         mtu-ignore
     }
 }

Site-B Configuration

As spoke sites have the exact same configuration, only difference is in IP address assignment. We will look at Site-B configuration only.

First basic IP connectivity and routing -
 
vyos@Site-B-Vyos# show interfaces 
 ethernet eth0 {
     address 192.168.254.6/30
     description Internet
 }
 ethernet eth3 {
     address 10.203.2.1/24
     description Lan-Site-B
 }
 loopback lo {
     address 10.203.4.2/32
 }

vyos@Site-B-Vyos# show protocols static 
 route 0.0.0.0/0 {
     next-hop 192.168.254.5 {
     }
 }

Then wireguard configuration -

vyos@Site-B-Vyos# show interfaces wireguard wg0 
 address 10.203.5.2/24
 description Wireguard-Site-A
 peer Site-A {
     allowed-ips 10.203.5.1/32
     !!! With endpoint Spoke will try to create Wireguard tunnel as initiator 
     endpoint 192.168.254.2:55555
     persistent-keepalive 15
     pubkey kqSUjEWBBWDmrwjGhoECNIQPyL82V7pveApQn8kmJTk=
 }
 
Now GRE tunnel configuration - 

vyos@Site-B-Vyos# show interfaces tunnel tun0 
 address 10.203.6.2/30
 description Gre-Site-A
 encapsulation gre
 local-ip 10.203.5.2
 remote-ip 10.203.5.1
 !!! Manual MTU setting
 mtu 1400

vyos@Site-B-Vyos# show firewall options 
 interface tun0 {
     !!! Manual TCP MSS adjustment
     adjust-mss 1360
 }

The last part is configuring OSPF -

vyos@Site-B-Vyos# show protocols ospf 
 area 0 {
     !!! Advertising loopback network
     network 10.203.4.0/24
     !!! Advertising GRE tunnel network
     network 10.203.6.0/24
     !!! Advertising Local network
     network 10.203.2.0/24
 }
 log-adjacency-changes {
     detail
 }
 parameters {
     abr-type cisco
     router-id 10.203.4.2
 }
 passive-interface default
 !!! Only GRE tunnel will participate in OSPF routing
 passive-interface-exclude tun0 

vyos@Site-B-Vyos# show interfaces tunnel tun0 
 ip {
     ospf {
        !!! Ignoring MTU size for OSPF neighbor selection
         mtu-ignore
     }
 }

Verification

Let's verify OSPF connectivity from Site-A - 

vyos@Site-A-Vyos:~$ show ip ospf neighbor 

Neighbor ID     Pri State           Dead Time Address         Interface       
10.203.4.2        1 Full/DR           35.901s 10.203.6.2      tun0:10.203.6.1 
10.203.4.3        1 Full/DR           39.082s 10.203.6.6      tun1:10.203.6.5 

As expected we have two neighbors (Site-B and Site-C) and those relationships are form over their respective GRE tunnels.

Site-A has got all the remote routes from the spokes through OSPF.

vyos@Site-A-Vyos:~$ show ip route ospf 

O>* 10.203.2.0/24 [110/11] via 10.203.6.2, tun0, 10:39:02
O>* 10.203.3.0/24 [110/11] via 10.203.6.6, tun1, 10:38:59
O>* 10.203.4.2/32 [110/10] via 10.203.6.2, tun0, 10:39:02
O>* 10.203.4.3/32 [110/10] via 10.203.6.6, tun1, 10:38:59

Let's do a final sanity check, a ping from Site-A LAN (10.203.1.1) to Site-C LAN (10.203.3.1).

vyos@Site-A-Vyos:~$ sudo ping -I 10.203.1.1 10.203.3.1
PING 10.203.3.1 (10.203.3.1) from 10.203.1.1 : 56(84) bytes of data.
64 bytes from 10.203.3.1: icmp_seq=1 ttl=64 time=1.45 ms
64 bytes from 10.203.3.1: icmp_seq=2 ttl=64 time=0.996 ms
64 bytes from 10.203.3.1: icmp_seq=3 ttl=64 time=1.26 ms

We can also verify all these communications (routing and user data traffic) is encrypted by using packet capture. A picture from a wireshark is given below.
04 - Wireguard Packet Capture

So we have achieved our goal - run dynamic routing protocols with Wireguard. But in our example routing is done by GRE and encryption is provided by Wireguard.

Comments

Popular posts from this blog

Fortigate firewall AAA Configuration for management with TACACS+ protocol and Cisco ISE

Stacking switches Part - VI (Dell OS10 VLT - Virtual Link Trunking)

Network device configuration management with Oxidized (Basic)