Configure Site-to-Site VPN with OpenVPN
Configure site-to-site VPN connection with OpenVPN. No special equipment required other than two machines with OpenVPN community edition installed. Also, no paid software and no static IPs.
Overview
Let there be two private networks: Network A and Network B. With site-to-site VPN we can allow the hosts on those networks to securely communicate with each other. As per the diagram above, Box A and Box B can connect as if they are on the same network. These boxes don’t need OpenVPN to be installed or any other configuration.
The solution consists of an OpenVPN server in one network and an OpenVPN client, connected to the server, in the other one. The server and the client are configured to forward traffic. The Network A LAN gateway knows to route Network B traffic through the server; Network B LAN gateway knows to route Network A traffic through the client.
Here’s a brief summary of what we are going to do:
- Create an OpenVPN server and a client;
- Configure the server and the client to forward traffic between the networks;
- Add routes to the LAN gateways;
Create server and client
I made a short note about a script that you can use to quickly create an OpenVPN server and manage its clients - Set up OpenVPN server in 1 minute. The script configures routed VPN (dev tun), the type of VPN this guide is for.
On the first run, the script also creates the first .ovpn
client config file. Copy this file to your client machine, and you can already connect the client to the server:
# install openvpn on the client machine and connect to the vpn
sudo apt-get install openvpn
sudo openvpn --config /path/to/client-name.ovpn
You are free to choose almost any Linux distro you want. The following instructions will assume Ubuntu 20.04, however, you should be able to follow along if you have something other than Ubuntu as well.
Configure server and client
For this guide, I’ll assume that the server’s network CIDR is 172.24.0.0/20
and the client’s CIDR is 172.25.0.0/20
. We need to let the server and the client know they are responsible for forwarding traffic to each other’s networks. We also need to make sure IP and TUN/TAP forwarding is enabled on both machines.
OpenVPN site-to-site
First, we need to modify the server’s config file. It should be in /etc/openvpn/
dir, e.g. /etc/openvpn/server/server.conf
. Add the following lines to the bottom of the config file:
push "route 172.24.0.0 255.255.240.0"
route 172.25.0.0 255.255.240.0
client-config-dir /etc/openvpn/ccd
The 1st line advertises the server’s network to the VPN clients as being accessible through the VPN. The 2nd line controls the routing from the kernel to the OpenVPN server (via the TUN interface). You have to modify the CIDRs (network masks) if yours are different, which is likely.
The 3rd line introduces a directory that will contain extra client configurations. If the directory doesn’t exist, create it: mkdir -p /etc/openvpn/ccd
.
Now, you need to know the name of the OpenVPN client. You were prompted for a name for the first client if you were using the script described earlier. Use the following command to create a file in the ccd
directory. It assumes that the client’s name is client1
, change it to your client’s name:
echo 'iroute 172.25.0.0 255.255.240.0' >> /etc/openvpn/ccd/client1
This will tell the server to route 172.25.0.0/20
traffic to client1
.
Once all of the above is done, restart the OpenVPN server for the changes to take effect:
systemctl restart [email protected]
This is it. Next, we’ll allow our server and client to forward traffic.
Enable IP and TUN/TAP forwarding
IP and TUN/TAP forwarding has to be enabled to let the server and the client forward traffic from the other machines on their networks.
This enables IP forwarding:
echo 1 > /proc/sys/net/ipv4/ip_forward
And this enables TUN/TAP forwarding:
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables-save
Restart the network service in the end:
systemctl restart systemd-networkd
Run these commands on both the server and the client.
Add LAN gateway routes
With the current setup, Box A and Box B cannot communicate yet. We need to add routes to the networks’ LAN gateways to let them know to route traffic through the OpenVPN server/client.
For the server network, we add a route that directs the client network traffic through the OpenVPN server: 172.25.0.0/20
→ OpenVPN server
. Similarly, for the client network, we add a route that directs the server network traffic through the OpenVPN client: 172.24.0.0/20
→ OpenVPN client
.
How you add these routes depends on the LAN gateway. For AWS VPC route tables, for example, you specify the CIDR blocks as the destination and the EC2 instance as the target.
With the gateway routes configured, any machine on the server network should be able to reach any machine on the client network and vice-versa. Box A and Box B from the diagram can now ping
each other.
Conclusion
We’ve configured a secure connection between two private networks using just two Linux machines and free OpenVPN software.
This setup might be used as an alternative to AWS Site-to-Site VPN. Although, it’s not as resilient as the AWS solution (no redundancy), but it’s a great fit for non-mission-critical use cases.
This guide is based on this OpenVPN how-to. It’s a bit different, but this is what worked for me, I was able to connect an AWS VPC with an on-premise network. If you have any troubles, I suggest that you also check out the original docs.