Connecting WireGuard and OpenVPN

If you have an existing OpenVPN network, it’s easy to hook up a WireGuard network to it, allowing traffic to flow between the two. Here’s how to do it under four common scenarios:

Shared Hub

The most basic scenario is where we use the same OpenVPN server as the hub for both our OpenVPN and WireGuard networks, and we simply want to allow our OpenVPN clients to access our WireGuard clients, and vice versa.

For example, we have an OpenVPN network using the 10.8.0.0/24 IP address range, and a WireGuard network using the 10.0.0.0/24 range. The OpenVPN server and the hub of the WireGuard network share the same server (with a public IP address of 192.0.2.3):

Shared OpenVPN Server / WireGuard Hub Scenario

We want to be able to connect from Endpoint A (at IP address 10.8.0.2 on the OpenVPN network) to Endpoint B (at IP address 10.0.0.2 on the WireGuard network), and vice versa.

This case looks like a basic hub-and-spoke OpenVPN network, paired with a basic WireGuard hub-and-spoke network. Our OpenVPN server configuration will just use the default settings:

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
tls-auth ta.key
cipher AES-256-CBC
persist-key
persist-tun
verb 3
explicit-exit-notify 1

In particular, notice we are not using the dev tap or client-to-client directives in our OpenVPN config — we are using the dev tun directive, so all traffic from the OpenVPN clients to the server will be routed through the server’s tun0 network interface.

Our WireGuard configuration on the OpenVPN server will look just like the hub configuration in the WireGuard Hub and Spoke Configuration guide (the hub is Host C in that guide), except that in this simple example we’ll connect only one WireGuard spoke to it (Endpoint B):

# /etc/wireguard/wg0.conf

# local settings for WireGuard hub
[Interface]
PrivateKey = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGA=
Address = 10.0.0.3/32
ListenPort = 51823

PreUp = sysctl -w net.ipv4.ip_forward=1

# remote settings for Endpoint B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 10.0.0.2/32

To enable the WireGuard and OpenVPN networks to talk to each other, we just need to do these four things:

Add Routes to WireGuard Clients

First, we need to update our WireGuard client configuration to add the route for the OpenVPN network to it (10.8.0.0/24). This just means adding an AllowedIPs = 10.8.0.0/24 entry to the [Peer] section for the WireGuard hub.

After adding that entry, the WireGuard configuration on Endpoint B would look like this (compare this to the Endpoint B configuration from the WireGuard Hub and Spoke Configuration guide):

# /etc/wireguard/wg0.conf

# local settings for Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25

Add Routes to OpenVPN Clients

Next, we need to update our OpenVPN server configuration to push the route for the WireGuard network (10.0.0.0/24) to its clients. This just means adding a push "route 10.0.0.0 255.255.255.0" entry to the server config file.

After adding that entry, the OpenVPN server configuration would look like this:

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
topology subnet
server 10.8.0.0 255.255.255.0
push "route 10.0.0.0 255.255.255.0"
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
tls-auth ta.key
cipher AES-256-CBC
persist-key
persist-tun
verb 3
explicit-exit-notify 1

Allow Connections Between Networks

Finally, we need to allow traffic to be forwarded between the tun0 and wg0 interfaces on the OpenVPN server. If we are not using a host-based firewall on the OpenVPN server, we actually don’t need to do anything for this step.

However, if we’re using iptables for our firewall, we’d need to add two iptables rules like the following to allow clients from our OpenVPN network to initiate connections to clients in our WireGuard network, and vice versa:

-I FORWARD -i tun0 -o wg0 -j ACCEPT
-I FORWARD -i wg0 -o tun0 -j ACCEPT

If we used the Simple Stateful Firewall example from the Arch Linux wiki to set up our firewall, this is how we’d configure iptables:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
:fw-interfaces - [0:0]
:fw-open - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j fw-interfaces
-A FORWARD -j fw-open
-A FORWARD -j REJECT --reject-with icmp-host-unreachable
-A TCP -p tcp --dport 22 -j ACCEPT
-A UDP -p udp --dport 1194 -j ACCEPT
-A UDP -p udp --dport 51823 -j ACCEPT
-A fw-interfaces -i tun0 -o tun0 -j ACCEPT
-A fw-interfaces -i wg0 -o wg0 -j ACCEPT
-A fw-interfaces -i tun0 -o wg0 -j ACCEPT
-A fw-interfaces -i wg0 -o tun0 -j ACCEPT
COMMIT

Alternatively, if we’re using nftables for our firewall, we’d need to add two nftables rules like the following to allow clients from our OpenVPN network to initiate connections to clients in our WireGuard network, and vice versa:

iifname tun0 oifname wg0 accept
iifname wg0 oifname tun0 accept

If we used the How to Use WireGuard With Nftables guide to set up our firewall, this is how we’d configure nftables:

#!/usr/sbin/nft -f
flush ruleset

define pub_iface = "eth0"
define vpn_iface = "tun0"
define vpn_port = 1194
define wg_iface = "wg0"
define wg_port = 51823

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        iif "lo" accept
        meta l4proto { icmp, ipv6-icmp } accept
        ct state vmap { invalid : drop, established : accept, related : accept }
        ct state new limit rate over 1/second burst 10 packets drop
        iifname $pub_iface tcp dport ssh accept
        iifname $pub_iface udp dport $vpn_port accept
        iifname $pub_iface udp dport $wg_port accept
        reject
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
        iifname $vpn_iface oifname $vpn_iface accept
        iifname $wg_iface oifname $wg_iface accept
        iifname $vpn_iface oifname $wg_iface accept
        iifname $wg_iface oifname $vpn_iface accept
        reject with icmpx type host-unreachable
    }
}

Test It Out

To test it out, if we have a network service like an HTTP server running on Endpoint B, we should be able to connect to it from Endpoint A using Endpoint B’s WireGuard IP address:

$ curl 10.0.0.2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
...

And similarly, if we a have a network service like an HTTP server running on Endpoint A, we should be able to connect to it from Endpoint B using Endpoint A’s OpenVPN address:

$ curl 10.8.0.2
<!DOCTYPE html>
<html>
...

If this doesn’t work, see the “Basic Troubleshooting” tips for hub-and-spoke networks in the WireGuard Hub and Spoke Configuration guide. If you’re using an iptables firewall on the OpenVPN server, check out “Iptables Errors” section of the WireGuard Access Control With Iptables guide; or if you’re using an nftables firewall, see the “Troubleshooting” section of the How to Use WireGuard With Nftables guide.

Hub to Hub

The next scenario we’ll cover is similar to the previous, where we simply want to allow our OpenVPN clients to access or WireGuard clients, and vice versa. In this scenario, however, we’ll use two separate servers: one for the OpenVPN server, and one for the WireGuard hub.

We’ll connect our OpenVPN server to our WireGuard hub by setting up a WireGuard client on the OpenVPN server, and routing our cross-network traffic through it:

Separate OpenVPN Server / WireGuard Hub Scenario

Our OpenVPN server will be a spoke on our WireGuard network, using an IP address of 10.0.0.1 within the WireGuard network’s IP address range of 10.0.0.0/24. The OpenVPN server will also use an IP address of 10.8.0.1 for its OpenVPN interface on the OpenVPN network (within the IP address range 10.8.0.0/24).

Just like the previous scenario, we want to be able to connect from Endpoint A, with an IP address of 10.8.0.2 on the OpenVPN network, to Endpoint B, with an IP address of 10.0.0.2 on the WireGuard network, and vice versa.

And just like the above Shared Hub scenario, make sure to not use the dev tap or client-to-client directives in the OpenVPN config — use the dev tun directive instead, so that all traffic from the OpenVPN clients to the server will be routed through the server’s tun0 network interface.

To enable the WireGuard and OpenVPN networks to talk to each other, we need to do these six things:

Set Up WireGuard Client On OpenVPN Server

First, set up a WireGuard client on the OpenVPN server. This client can be configured exactly like the other WireGuard spokes (compare this to the Endpoint A configuration from the WireGuard Hub and Spoke Configuration guide):

# /etc/wireguard/wg0.conf

# local settings for OpenVPN server
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25

Make sure you include a PersistentKeepalive setting if you want WireGuard clients to be able to initiate connections OpenVPN clients.

Connect OpenVPN Server to WireGuard Hub

Next, add a [Peer] entry for the OpenVPN server to the WireGuard hub’s configuration. This should be configured exactly like the [Peer] sections for other WireGuard spokes — except it should also include the OpenVPN network (10.8.0.0/24) in its AllowedIPs setting (compare this to the Host C configuration from the WireGuard Hub and Spoke Configuration guide):

# /etc/wireguard/wg0.conf

# local settings for WireGuard hub
[Interface]
PrivateKey = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGA=
Address = 10.0.0.3/32
ListenPort = 51823

PreUp = sysctl -w net.ipv4.ip_forward=1

# remote settings for OpenVPN server
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32
AllowedIPs = 10.8.0.0/24

# remote settings for Endpoint B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 10.0.0.2/32

Add Routes to WireGuard Clients

Next, we need to update the configuration of all our other WireGuard clients to add the OpenVPN network (10.8.0.0/24) to the AllowedIPs setting for their connection to the hub:

# /etc/wireguard/wg0.conf

# local settings for Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25

This is exactly the same as the Add Routes to WireGuard Clients step from the Shared Hub scenario above.

Add Routes to OpenVPN Clients

Next, we need to update our OpenVPN server configuration to push the route for the WireGuard network (10.0.0.0/24) to its clients. This just means adding a push "route 10.0.0.0 255.255.255.0" entry.

After adding this entry, the OpenVPN server configuration would look like this (exactly the same as the Add Routes to OpenVPN Clients step from the Shared Hub scenario above):

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
topology subnet
server 10.8.0.0 255.255.255.0
push "route 10.0.0.0 255.255.255.0"
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
tls-auth ta.key
cipher AES-256-CBC
persist-key
persist-tun
verb 3
explicit-exit-notify 1

Allow Connections Between Networks

We don’t have to update any firewall settings on the WireGuard hub or WireGuard clients for this, since they already allow traffic to and from the WireGuard network. We just have to modify the firewall settings on the OpenVPN server to allow traffic to be forwarded between its tun0 and wg0 interfaces. These adjustments are exactly the same as the Allow Connections Between Networks from the Shared Hub scenario above, so refer to it.

Test It Out

To test it out, if we have a network service like an HTTP server running on Endpoint B, we should be able to connect to it from Endpoint A using Endpoint B’s WireGuard IP address:

$ curl 10.0.0.2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
...

And similarly, if we a have a network service like an HTTP server running on Endpoint A, we should be able to connect to it from Endpoint B using Endpoint A’s OpenVPN address:

$ curl 10.8.0.2
<!DOCTYPE html>
<html>
...

If this doesn’t work, see the “Basic Troubleshooting” tips for hub-and-spoke networks in the WireGuard Hub and Spoke Configuration guide. If you’re using an iptables firewall on the OpenVPN server, check out “Iptables Errors” section of the WireGuard Access Control With Iptables guide; or if you’re using an nftables firewall, see the “Troubleshooting” section of the How to Use WireGuard With Nftables guide.

To WireGuard Site

The next scenario we’ll cover is similar to the previous, where we use separate hosts for the OpenVPN server and the WireGuard hub. But in this case, we want to allow the OpenVPN clients from the OpenVPN network to access a LAN (Local Area Network) behind one of the WireGuard spokes. This scenario is very similar to the Site Gateway as a Spoke scenario from the Multi-Hop WireGuard article — differing only in that Endpoint A in this scenario is an OpenVPN client, and its connection to the WireGuard network is indirect, routed through the OpenVPN server.

Like the previous scenario, we’ll connect our OpenVPN server to our WireGuard hub by setting up a WireGuard client on the OpenVPN server, and routing our cross-network traffic through it:

OpenVPN Server to WireGuard Site Scenario

And like the previous scenario, our OpenVPN server will be a spoke on our WireGuard network, using an IP address of 10.0.0.1 within the WireGuard network’s IP address range of 10.0.0.0/24. The OpenVPN server will also use an IP address of 10.8.0.1 for its OpenVPN interface on the OpenVPN network (within the IP address range 10.8.0.0/24).

But differing from the previous scenario, we want access to a different network — the Site B LAN, which uses the 192.168.200.0/24 IP address range. We want to be able to connect from Endpoint A, with an IP address 10.8.0.2 on the OpenVPN network, through the WireGuard network to Endpoint B, with an IP address 192.168.200.22 on the Site B LAN.

Just like the above scenarios, make sure to not use the dev tap or client-to-client directives in the OpenVPN config — use the dev tun directive instead, so that all traffic from the OpenVPN clients to the server will be routed through the server’s tun0 network interface.

To enable the OpenVPN network to access the LAN behind the WireGuard network, we need to do these six things:

Set Up WireGuard Client On OpenVPN Server

First, set up a WireGuard client on the OpenVPN server. This client can be configured like the other WireGuard spokes that have access to the Site B gateway:

# /etc/wireguard/wg0.conf

# local settings for OpenVPN server
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
AllowedIPs = 192.168.200.0/24

This is similar to the Set Up WireGuard Client On OpenVPN Server step from the Hub to Hub scenario above — but note that it also includes the Site B LAN (192.168.200.0/24) in its AllowedIPs setting. (And it doesn’t need a PersistentKeepalive setting, because in this scenario, no WireGuard clients need to initiate connections to OpenVPN clients.) Compare this to the Endpoint A configuration from the Site Gateway as a Spoke scenario from the Multi-Hop WireGuard article.

Connect OpenVPN Server to WireGuard Hub

Next, add a [Peer] entry for the OpenVPN server to the WireGuard hub’s configuration. This should be configured similarly to the [Peer] sections for other WireGuard spokes — but it should include the OpenVPN network (10.8.0.0/24) in its AllowedIPs setting:

# /etc/wireguard/wg0.conf

# local settings for WireGuard hub
[Interface]
PrivateKey = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGA=
Address = 10.0.0.3/32
ListenPort = 51823

PreUp = sysctl -w net.ipv4.ip_forward=1

# remote settings for OpenVPN server
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32
AllowedIPs = 10.8.0.0/24

# remote settings for Site B gateway
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 10.0.0.2/32
AllowedIPs = 192.168.200.0/24

This is the same as the Connect OpenVPN Server to WireGuard Hub step from the Hub to Hub scenario above — except in this case, we also have a [Peer] entry for the Site B gateway (Host β). Note the [Peer] entry for this gateway includes an AllowedIPs setting for the Site B LAN (192.168.200.0/24). Compare this config file to the Host C configuration from the Site Gateway as a Spoke scenario from the Multi-Hop WireGuard article.

Add Routes to WireGuard Site Gateway

Next, we need to update the configuration of the WireGuard client that serves as the Site B gateway to add the OpenVPN network (10.8.0.0/24) to the AllowedIPs setting for the WireGuard hub:

# /etc/wireguard/wg0.conf

# local settings for Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# IP forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# IP masquerading
PreUp = iptables -t mangle -A PREROUTING -i wg0 -j MARK --set-mark 0x30
PreUp = iptables -t nat -A POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE
PostDown = iptables -t mangle -D PREROUTING -i wg0 -j MARK --set-mark 0x30
PostDown = iptables -t nat -D POSTROUTING ! -o wg0 -m mark --mark 0x30 -j MASQUERADE

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25

This configuration change is exactly the same as the Add Routes to WireGuard Clients step from the Shared Hub scenario above. However, this particular WireGuard client configuration is a bit different than the examples above in that it allows for packets to be forwarded and masqueraded to Site B; compare it to the Host β configuration from the Site Gateway as a Spoke scenario from the Multi-Hop WireGuard article.

Add Routes to OpenVPN Clients

Next, we need to update our OpenVPN server configuration to push the route for the Site B network (192.168.200.0/24) to its clients. This just means adding a push "route 192.168.200.0 255.255.255.0" entry.

After adding this entry, the OpenVPN server configuration would look like this (very similar to the Add Routes to OpenVPN Clients step from the Shared Hub scenario above, just with a different route):

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
topology subnet
server 10.8.0.0 255.255.255.0
push "route 192.168.200.0 255.255.255.0"
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
tls-auth ta.key
cipher AES-256-CBC
persist-key
persist-tun
verb 3
explicit-exit-notify 1

Allow Connections Between Networks

We don’t have to update any firewall settings on the WireGuard hub or the WireGuard clients for this, since they already allow traffic to and from the WireGuard network. We just have to modify the firewall settings on the OpenVPN server to allow traffic to be forwarded between its tun0 and wg0 interfaces. These adjustments are exactly the same as the Allow Connections Between Networks from the Shared Hub scenario above, so refer to it.

Test It Out

To test it out, if we have a network service like an HTTP server running on Endpoint B, we should be able to connect to it from Endpoint A using Endpoint B’s IP address on the Site B LAN:

$ curl 192.168.200.22
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
...

If this doesn’t work, see the “Basic Troubleshooting” tips for hub-and-spoke networks in the WireGuard Hub and Spoke Configuration guide. If you’re using an iptables firewall on the OpenVPN server, check out “Iptables Errors” section of the WireGuard Access Control With Iptables guide; or if you’re using an nftables firewall, see the “Troubleshooting” section of the How to Use WireGuard With Nftables guide.

To OpenVPN Site

The last scenario we’ll cover is similar to the previous; however, in this scenario, instead of exposing a LAN behind one of the WireGuard spokes to OpenVPN clients, we want to expose a LAN behind an OpenVPN client to the WireGuard spokes.

From the perspective of the WireGuard network, this scenario is similar to the Site Gateway as a Spoke scenario from the Multi-Hop WireGuard article — just flipping things around a bit so that Endpoint A in that scenario is like Endpoint B in this scenario, and vice versa.

Like the previous scenario, we’ll connect our OpenVPN server to our WireGuard hub by setting up a WireGuard client on the OpenVPN server, and routing our cross-network traffic through it:

WireGuard Hub To OpenVPN Site Scenario

And like the previous scenario, our OpenVPN server will be a spoke on our WireGuard network, using an IP address of 10.0.0.1 within the WireGuard network’s IP address range of 10.0.0.0/24. The OpenVPN server will also use an IP address of 10.8.0.1 for its OpenVPN interface on the OpenVPN network (within the IP address range 10.8.0.0/24).

But unlike the previous scenario, we want to reverse the direction of access — allowing access to the Site A LAN, which uses the 192.168.1.0/24 IP address range, from the WireGuard network. We want to be able to connect from Endpoint B, with an IP address of 10.0.0.2 on the WireGuard network, through the OpenVPN network to Endpoint A, with an IP address of 192.168.1.101 on the Site A LAN.

Just like the above scenarios, make sure to not use the dev tap or client-to-client directives in the OpenVPN config — use the dev tun directive instead, so that all traffic from the OpenVPN clients to the server will be routed through the server’s tun0 network interface.

To enable the WireGuard network to access the LAN behind the OpenVPN network, we need to do these six things:

Set Up WireGuard Client On OpenVPN Server

First, set up a WireGuard client on the OpenVPN server. This is exactly the same as the Set Up WireGuard Client On OpenVPN Server step from the Hub to Hub scenario above:

# /etc/wireguard/wg0.conf

# local settings for OpenVPN server
[Interface]
PrivateKey = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE=
Address = 10.0.0.1/32
ListenPort = 51821

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25

Connect OpenVPN Server to WireGuard Hub

Next, add a [Peer] entry for the OpenVPN server to the WireGuard hub’s configuration. This should be configured similarly to the [Peer] sections for other WireGuard spokes — except it should also include the Site A network (192.168.1.0/24) in its AllowedIPs setting:

# /etc/wireguard/wg0.conf

# local settings for WireGuard hub
[Interface]
PrivateKey = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCGA=
Address = 10.0.0.3/32
ListenPort = 51823

PreUp = sysctl -w net.ipv4.ip_forward=1

# remote settings for OpenVPN server
[Peer]
PublicKey = /TOE4TKtAqVsePRVR+5AA43HkAK5DSntkOCO7nYq5xU=
AllowedIPs = 10.0.0.1/32
AllowedIPs = 192.168.1.0/24

# remote settings for Endpoint B
[Peer]
PublicKey = fE/wdxzl0klVp/IR8UcaoGUMjqaWi3jAd7KzHKFS6Ds=
AllowedIPs = 10.0.0.2/32

This is almost the same as the Connect OpenVPN Server to WireGuard Hub step from the Hub to Hub scenario above, but uses the Site A network (192.168.1.0/24) for the OpenVPN server’s AllowedIPs setting instead of the OpenVPN network itself (10.8.0.0/24).

Add Routes to WireGuard Clients

Next, we need to update the configuration of all our other WireGuard clients to add the Site A network (192.168.1.0/24) to the AllowedIPs setting for the hub:

# /etc/wireguard/wg0.conf

# local settings for Endpoint B
[Interface]
PrivateKey = ABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFA=
Address = 10.0.0.2/32
ListenPort = 51822

# remote settings for WireGuard hub
[Peer]
PublicKey = jUd41n3XYa3yXBzyBvWqlLhYgRef5RiBD7jwo70U+Rw=
Endpoint = 192.0.2.3:51823
AllowedIPs = 10.0.0.0/24
AllowedIPs = 192.168.1.0/24

This is almost the same as the Add Routes to WireGuard Clients step from the Shared Hub scenario above — except we add the Site A network (192.168.1.0/24) instead of the OpenVPN network (10.8.0.0/24) to the AllowedIPs setting.

Add Routes to OpenVPN Site Gateway

Next, we need to update our OpenVPN server configuration to push the route for the WireGuard network (10.0.0.0/24) to the Site A gateway. Unlike the other scenarios, where we configured the server to push a new route to all of its clients, in this scenario, we just want to configure the server to push the route to just one of its clients.

If we had configured the rest of the OpenVPN clients to be able to access Site A (192.168.1.0/24), we’d have an OpenVPN server config that looks like this (note the client-config-dir and route directives):

# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
topology subnet
server 10.8.0.0 255.255.255.0
client-config-dir ccd
route 192.168.1.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
keepalive 10 120
tls-auth ta.key
cipher AES-256-CBC
persist-key
persist-tun
verb 3
explicit-exit-notify 1

And if the OpenVPN client certificate for Host α uses a CN (Common Name) of host-alpha, we’d have a client config file named host-alpha in the server’s ccd directory that looked like this:

# /etc/openvpn/server/ccd/host-alpha
iroute 192.168.1.0 255.255.255.0

To that config file, we need to add the following push-route entry so that Host α knows to route traffic to the WireGuard network (10.0.0.0/24) back through the OpenVPN server:

# /etc/openvpn/server/ccd/host-alpha
iroute 192.168.1.0 255.255.255.0
push "route 10.0.0.0 255.255.255.0"

Assuming Host α is already set up to masquerade traffic from its OpenVPN interface (tun0) to Site A, we don’t need to make any routing changes for the Site A LAN itself.

Allow Connections Between Networks

We don’t have to update any firewall settings on the WireGuard hub or WireGuard clients for this, since they already allow traffic to and from the WireGuard network. We just have to modify the firewall settings on the OpenVPN server to allow traffic to be forwarded between its tun0 and wg0 interfaces. These adjustments are exactly the same as the Allow Connections Between Networks from the Shared Hub scenario above, so refer to it.

Test It Out

To test it out, if we a have a network service like an HTTP server running on Endpoint A, we should be able to connect to it from Endpoint B using Endpoint A’s IP address on the Site A LAN:

$ curl 192.168.1.101
<!DOCTYPE html>
<html>
...

If this doesn’t work, see the “Basic Troubleshooting” tips for hub-and-spoke networks in the WireGuard Hub and Spoke Configuration guide. If you’re using an iptables firewall on the OpenVPN server, check out “Iptables Errors” section of the WireGuard Access Control With Iptables guide; or if you’re using an nftables firewall, see the “Troubleshooting” section of the How to Use WireGuard With Nftables guide.