Table of Contents
Introduction
Setting up a Site-to-Site VPN is a powerful way to securely link two remote networks—such as a home lab and a cloud environment—so they behave as if they’re on the same local network. While there are several technologies available to achieve this, choosing the right one often comes down to your specific network constraints and goals.
In my case, I initially used strongSwan (IPSec) for my Site-to-Site VPN. It’s a robust and widely respected solution, and I’d still recommend it in many scenarios. However, I ran into a common limitation: IPSec requires UDP ports 500 and 4500, which were then needing to be used by my Always-on VPN. With only a single public IP address available, I couldn’t dedicate those ports to strongSwan and Always On VPN without breaking other services.
So that’s when I turned to OpenVPN.
Unlike IPSec, OpenVPN only requires a single port to be open on the server side. This makes it ideal for asymmetric setups like mine where the OpenVPN server runs on a home lab network, and the client is deployed in Azure. The client can initiate the connection from behind NAT or firewalls without needing any inbound ports open. I chose to run OpenVPN on UDP port 1294, since 1194 (the default) was already in use by my UDM’s OpenVPN service.
This guide walks through the exact steps I took to build a reliable, secure, and flexible Site-to-Site VPN using OpenVPN on Ubuntu, tailored to real-world constraints like overlapping port usage and limited public IPs. Whether you’re connecting a cloud environment to your home lab or linking two branch offices, this setup can serve as a solid foundation.
Network Overview
To successfully configure a Site-to-Site VPN, it’s essential to understand the network topology on both ends of the tunnel. This setup connects a home lab environment to a cloud-based Azure network, allowing devices on either side to communicate securely and directly.
The table below outlines the key subnets involved in this configuration. Each network segment is isolated with non-overlapping IP ranges to ensure clean routing and avoid conflicts. The OpenVPN tunnel uses its own dedicated subnet to facilitate encrypted communication between the two sites.
Site | Description | Subnet |
---|---|---|
Home Site | LAN (Primary internal network) | 192.168.8.0/22 |
Always-on VPN | 172.16.10.0/24 | |
Azure Site | Azure Virtual Network | 192.168.144.0/20 |
VPN Tunnel | OpenVPN Tunnel Subnet | 192.168.254.0/24 |
Installing OpenVPN, Easy-RSA & Enabling IP Forwarding
Before we can establish a secure Site-to-Site VPN tunnel, we need to install the necessary software and configure the system to allow traffic to be routed between networks.
What is OpenVPN?
OpenVPN is the core software that creates and manages the encrypted tunnel between two endpoints. It handles:
- Encryption and decryption of traffic
- Authentication between peers
- Routing of packets between networks
- Tunnel interface creation (via
tun
ortap
)
You’ll need to install OpenVPN on both the server and the client, as both ends of the tunnel must be able to send and receive encrypted traffic.
What is Easy-RSA?
Easy-RSA is a command-line utility that simplifies the process of creating and managing a Public Key Infrastructure (PKI). It’s used to:
- Generate a Certificate Authority (CA)
- Create and sign server and client certificates
- Manage private keys and certificate revocation lists
You only need to install Easy-RSA on the server, because the server is responsible for generating and signing all certificates. Once the certificates and keys are created, they can be securely transferred to the client.
Once connected to each server run the following commands: this will check for updates, install any updates and then install Open VPN on the Server and the Client
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install openvpn -y
Additionally on the server run the following command to install Easy-RSA:
sudo apt-get install easy-rsa -y
Enabling IP Forwarding
For the VPN server to route traffic between networks, it must be configured to forward IP packets. This is a critical step in enabling communication between the remote subnets.
To enable IP forwarding permanently:
- Open the system configuration file:
sudo nano /etc/sysctl.conf
- Find the following line:
#net.ipv4.ip_forward=1
- Uncomment it by removing the
#
:net.ipv4.ip_forward=1
- Apply the changes immediately:
sudo sysctl -p
Why this matters: Without IP forwarding, the server will receive traffic from the VPN tunnel but won’t pass it on to the internal networks—effectively breaking the Site-to-Site functionality.
Prepare Certificates and Keys (on the Server)
To establish a secure and trusted connection between the OpenVPN server and client, we need to use TLS-based authentication. This is where certificates and keys come into play.
Why Are Certificates and Keys Needed?
OpenVPN uses mutual TLS authentication, meaning both the server and the client must prove their identity using digital certificates. This ensures:
- Encryption: All traffic is encrypted using strong cryptographic algorithms.
- Authentication: Only trusted clients (with valid certificates) can connect to the VPN server.
- Integrity: Data cannot be tampered with in transit without detection.
To achieve this, we need to set up a Public Key Infrastructure (PKI) using Easy-RSA. This involves creating a Certificate Authority (CA), generating private keys, and issuing signed certificates for both the server and the client.
Steps to Generate Certificates and Keys
Run the following commands on the server only:
make-cadir ~/easy-rsa
cd ~/easy-rsa
# Initialize the PKI directory
./easyrsa init-pki
# Build the Certificate Authority (CA)
./easyrsa build-ca
# Generate a certificate request for the server
./easyrsa gen-req vpn.kemponline.co.uk nopass
# Sign the server certificate with the CA
./easyrsa sign-req server vpn.kemponline.co.uk
# Generate a certificate request for the Azure client
./easyrsa gen-req azure nopass
# Sign the client certificate with the CA
./easyrsa sign-req client azure
# Generate a static TLS key for additional security
openvpn --genkey secret ta.key
Note: The
ta.key
is used for TLS Crypt, which adds an extra layer of protection to the TLS handshake, helping to prevent certain types of attacks (e.g., port scanning and DoS).
Copy Certificates and Keys to the OpenVPN Server Directory
Once the certificates and keys are generated, copy them to the appropriate OpenVPN configuration directory:
sudo mkdir -p /etc/openvpn/server
sudo cp ~/easy-rsa/pki/ca.crt /etc/openvpn/server/
sudo cp ~/easy-rsa/pki/issued/vpn.kemponline.co.uk.crt /etc/openvpn/server/
sudo cp ~/easy-rsa/pki/private/vpn.kemponline.co.uk.key /etc/openvpn/server/
sudo cp ~/easy-rsa/ta.key /etc/openvpn/server/
sudo mkdir -p /etc/openvpn/ccd
Certificate & Key File Summary
File | Location | Purpose |
---|---|---|
ca.crt | /etc/openvpn/server/ | The Certificate Authority certificate. Used to verify client and server certificates. |
vpn.kemponline.co.uk.crt | /etc/openvpn/server/ | The server certificate, signed by the CA. Identifies the OpenVPN server. |
vpn.kemponline.co.uk.key | /etc/openvpn/server/ | The server’s private key. Must be kept secure. Used to decrypt traffic and prove identity. |
azure.crt | Transferred to client | The client certificate, signed by the CA. Identifies the Azure client. |
azure.key | Transferred to client | The client’s private key. Must be kept secure. Used to authenticate to the server. |
ta.key | /etc/openvpn/server/ and client | A static TLS key used for tls-crypt . Adds an extra layer of security to the TLS handshake. |
This table helps clarify the role of each file and where it should be placed. Let me know if you’d like a second table for the client-side files or a visual diagram of the certificate trust chain!
Create the OpenVPN Server Configuration
Now that the certificates and keys are in place, it’s time to configure the OpenVPN server. This configuration file defines how the server behaves, which networks it connects, and how it handles security, routing, and client connections.
Create the Configuration File
Open the server configuration file for editing:
sudo nano /etc/openvpn/server.conf
Paste in:
port 1294
proto udp
dev tun
ca ca.crt
cert vpn.kemponline.co.uk.crt
key vpn.kemponline.co.uk.key
dh none
ecdh-curve prime256v1
tls-crypt ta.key
server 192.168.254.0 255.255.255.0 # VPN subnet (does not overlap with others)
client-config-dir /etc/openvpn/ccd
# Route for Azure site
route 192.168.144.0 255.255.240.0
# Push routes for home networks (LAN, Always-on VPN)
push "route 192.168.8.0 255.255.252.0"
push "route 172.16.10.0 255.255.255.0"
keepalive 10 120
persist-key
persist-tun
user nobody
group nogroup
cipher AES-256-GCM
auth SHA256
ncp-ciphers AES-256-GCM:AES-128-GCM
topology subnet
verb 3
explicit-exit-notify 1
Configuration Breakdown
To help you better understand the purpose of each directive in the OpenVPN server configuration file, the table below provides a detailed explanation of the most important settings. These options control everything from encryption and authentication to routing and logging. Understanding what each line does will make it easier to troubleshoot issues, customize your setup, and ensure your VPN is both secure and functional.
Directive | Explanation |
---|---|
port 1294 | The UDP port OpenVPN will listen on. You chose 1294 to avoid conflicts with other services (e.g., UDM using 1194). |
proto udp | UDP is preferred for VPNs due to lower latency and better performance. |
dev tun | Creates a routed IP tunnel (as opposed to tap , which is for Ethernet bridging). |
ca , cert , key | These point to the server’s certificate authority, certificate, and private key. |
dh none | Disables Diffie-Hellman since you’re using Elliptic Curve Diffie-Hellman (ECDH) instead. |
ecdh-curve prime256v1 | Specifies the elliptic curve used for key exchange—secure and efficient. |
tls-crypt ta.key | Adds an extra layer of security to the TLS handshake, protecting against port scanning and DoS attacks. |
server 192.168.254.0 255.255.255.0 | Defines the VPN subnet used for tunnel interfaces. Must not overlap with internal networks. |
client-config-dir /etc/openvpn/ccd | Enables per-client routing rules (e.g., iroute for Azure). |
route 192.168.144.0 255.255.240.0 | Adds a static route to the Azure subnet so the server knows how to reach it. |
push "route ..." | Tells connected clients how to reach the home LAN and Always-on VPN subnets. |
keepalive 10 120 | Sends a ping every 10 seconds and assumes the peer is down after 120 seconds of silence. |
persist-key , persist-tun | Keeps keys and tunnel interface active across restarts. |
user nobody , group nogroup | Drops privileges after startup for better security. |
cipher AES-256-GCM , auth SHA256 | Specifies strong encryption and authentication algorithms. |
ncp-ciphers ... | Allows negotiation of ciphers between server and client. |
topology subnet | Ensures each client gets a unique IP in the VPN subnet. |
verb 3 | Sets log verbosity level (3 = recommended for general use). |
explicit-exit-notify 1 | Notifies the client when the server shuts down cleanly. |
Configure Per-Client Routing
In a Site-to-Site VPN setup, the OpenVPN server needs to know which remote subnets are accessible through which clients. This is especially important when multiple clients connect to the server, each representing different networks.
To achieve this, OpenVPN uses per-client routing via the client-config-dir
(CCD) mechanism. This allows the server to define static routes for each client, ensuring that traffic destined for a specific subnet is routed through the correct VPN tunnel.
Without this step, the server would not know how to reach the Azure subnet (192.168.144.0/20
), and traffic from the home network to Azure would be dropped or misrouted.
Create the Client-Specific Configuration File
Create a file named after the Common Name (CN) of the client certificate—in this case, azure
:
sudo mkdir -p /etc/openvpn/ccd
sudo nano /etc/openvpn/ccd/azure
Add:
iroute 192.168.144.0 255.255.240.0
Why This Matters
The table below explains the purpose of the iroute
directive and why it’s a critical part of enabling proper routing in a Site-to-Site VPN. Without it, the OpenVPN server wouldn’t know which client is responsible for which remote subnet, breaking connectivity between sites.
Directive | Purpose |
---|---|
iroute | Tells the OpenVPN server that the subnet 192.168.144.0/20 is reachable through the client named azure . This is essential for routing traffic from the home site to Azure. |
Note: This works in conjunction with the
client-config-dir
directive in the server config, which points to the/etc/openvpn/ccd/
directory. OpenVPN matches the connecting client’s certificate CN to a file in this directory and applies the routing rules defined within.
Start and Enable OpenVPN Server
With your configuration complete and certificates in place, it’s time to bring the OpenVPN server to life. This step launches the VPN service and ensures it starts automatically on boot—so your Site-to-Site tunnel stays up even after a reboot.
Commands to Start and Enable the Server
Run the following commands on the OpenVPN server:
sudo systemctl start openvpn-server@server
sudo systemctl enable openvpn-server@server
sudo systemctl status openvpn-server@server
What These Commands Do
Command | Purpose |
---|---|
sudo systemctl start openvpn-server@server | Starts the OpenVPN service using the configuration file located at /etc/openvpn/server.conf . The @server part matches the filename (server.conf ). |
sudo systemctl enable openvpn-server@server | Enables the service to start automatically at boot, ensuring your VPN tunnel is persistent across reboots. |
sudo systemctl status openvpn-server@server | Displays the current status of the OpenVPN service, including whether it started successfully and any errors or logs. |
What to Look For
After running status
, you should see output indicating that the service is active (running). If there are any issues (e.g., misconfigured paths, missing certificates, or port conflicts), they’ll be shown here.
Tip: If the service fails to start, check the logs with:
journalctl -xeu openvpn-server@server
This is a crucial step—without the service running, no VPN tunnel will be established, and your client won’t be able to connect.
Configure iptables for All Networks
Once the VPN tunnel is up and running, the next critical step is to ensure that traffic can flow between the VPN subnet and your internal networks. By default, Linux systems with OpenVPN won’t forward packets between interfaces unless explicitly allowed. This is where iptables comes in.
Why This Matters
OpenVPN creates a virtual interface (typically tun0
) for encrypted traffic. However, without proper firewall rules, traffic from the VPN clients won’t be able to reach your internal networks (Home LAN, Always-on VPN, Azure), and vice versa.
These iptables rules explicitly allow forwarding between the VPN tunnel and each internal subnet, enabling full bidirectional communication across the Site-to-Site VPN.
Allow forwarding between the VPN and all internal subnets (Home LAN, Always-on VPN, Azure):
# Home LAN
sudo iptables -A FORWARD -i tun0 -o eth0 -s 192.168.254.0/24 -d 192.168.8.0/22 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun0 -s 192.168.8.0/22 -d 192.168.254.0/24 -j ACCEPT
# Always-on VPN
sudo iptables -A FORWARD -i tun0 -o eth0 -s 192.168.254.0/24 -d 172.16.10.0/24 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun0 -s 172.16.10.0/24 -d 192.168.254.0/24 -j ACCEPT
# Azure Site
sudo iptables -A FORWARD -i tun0 -o eth0 -s 192.168.254.0/24 -d 192.168.144.0/20 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun0 -s 192.168.144.0/20 -d 192.168.254.0/24 -j ACCEPT
Iptables Rules Breakdown
The table below outlines each iptables rule and its role in enabling secure, bidirectional traffic flow between the VPN tunnel and your internal networks.
Network | Direction | Command | Purpose |
---|---|---|---|
Home LAN | VPN → LAN | -i tun0 -o eth0 -s 192.168.254.0/24 -d 192.168.8.0/22 | Allow VPN clients to access the home LAN. |
LAN → VPN | -i eth0 -o tun0 -s 192.168.8.0/22 -d 192.168.254.0/24 | Allow home LAN devices to respond to VPN clients. | |
Always-on VPN | VPN → VPN Net | -i tun0 -o eth0 -s 192.168.254.0/24 -d 172.16.10.0/24 | Allow VPN clients to access the Always-on VPN subnet. |
VPN Net → VPN | -i eth0 -o tun0 -s 172.16.10.0/24 -d 192.168.254.0/24 | Allow Always-on VPN devices to respond to VPN clients. | |
Azure Site | VPN → Azure | -i tun0 -o eth0 -s 192.168.254.0/24 -d 192.168.144.0/20 | Allow VPN clients to access Azure resources. |
Azure → VPN | -i eth0 -o tun0 -s 192.168.144.0/20 -d 192.168.254.0/24 | Allow Azure resources to respond to VPN clients. |
Make iptables Rules Persistent
To ensure these rules survive a reboot, install the persistence package and save the configuration:
sudo apt-get install iptables-persistent
sudo netfilter-persistent save
Client (Azure Side) Configuration
Now that the OpenVPN server is up and running, it’s time to configure the Azure VM to act as the VPN client. This client will initiate the connection to your home lab and route traffic between Azure and your internal networks.
To do this, we need to:
- Transfer the necessary certificates and keys from the server
- Place them in the correct directories on the client
- Ensure IP forwarding is enabled
- Configure the Azure VM with a static IP and enable IP forwarding in the Azure portal
Transfer Certificates and Keys from the Server
From your OpenVPN server, run the following scp
commands to copy the required files to the Azure client (replace azureuser@<azure-ip>
with your actual username and IP):
scp /etc/openvpn/server/ca.crt azureuser@<azure-ip>:~
scp ~/easy-rsa/pki/issued/azure.crt azureuser@<azure-ip>:~
scp ~/easy-rsa/pki/private/azure.key azureuser@<azure-ip>:~
scp /etc/openvpn/server/ta.key azureuser@<azure-ip>:~
Move Files to the OpenVPN Client Directory
Once logged into the Azure client, move the files to the appropriate OpenVPN directory:
sudo mkdir -p /etc/openvpn/client
sudo mv ~/ca.crt ~/azure.crt ~/azure.key ~/ta.key /etc/openvpn/client/
Enable IP Forwarding on the Client
Just like on the server, the client must be able to forward packets between interfaces. This is essential for routing traffic from Azure to your home network.
- Edit the sysctl configuration:
sudo nano /etc/sysctl.conf
- Uncomment or add the following line:
net.ipv4.ip_forward=1
- Apply the changes:
sudo sysctl -p
Azure VM Network Interface Settings
In the Azure Portal, make sure the following settings are configured for the VM’s network interface:
- IP Forwarding:
Go to your VM’s Network Interface > IP configurations, and ensure IP forwarding is enabled. This allows the VM to route packets between the VPN tunnel and the Azure subnet. - Static Private IP (Recommended):
Assign a static private IP to the VM to ensure its internal address doesn’t change. This is important for consistent routing and firewall rules.
Create the OpenVPN Client Configuration (Azure)
Now that the necessary certificates and keys are in place on the Azure VM, the next step is to create the OpenVPN client configuration file. This file tells the client how to connect to the server, what encryption settings to use, and which routes to establish once connected.
Instead of embedding certificate contents directly in the config file, we’ll reference the certificate and key files by their paths—this keeps the configuration cleaner and easier to manage.
Create the Client Config File
Run the following:
sudo nano /etc/openvpn/client/azure.conf
Paste the following in to the conf file:
client
dev tun
proto udp
remote vpn.kemponline.co.uk 1294
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
auth SHA256
ncp-ciphers AES-256-GCM:AES-128-GCM
verb 3
# Routes to internal networks on the home site
route 192.168.8.0 255.255.252.0
route 172.16.10.0 255.255.255.0
# Certificate and key file paths
ca /etc/openvpn/client/ca.crt
cert /etc/openvpn/client/azure.crt
key /etc/openvpn/client/azure.key
tls-crypt /etc/openvpn/client/ta.key
OpenVPN Client Configuration Reference
To help you understand what each directive in the OpenVPN client configuration file does, the table below provides a breakdown of the most important settings. These options define how the client connects to the server, handles encryption, and routes traffic through the VPN tunnel.
Directive | Purpose |
---|---|
client | Specifies that this is a client configuration. |
dev tun | Uses a routed IP tunnel (TUN) instead of a bridged Ethernet tunnel (TAP). |
proto udp | Uses UDP for better performance and lower latency. |
remote vpn.kemponline.co.uk 1294 | Specifies the server address and port to connect to. |
resolv-retry infinite | Keeps retrying DNS resolution if the server is temporarily unreachable. |
nobind | Allows the client to use any available local port. |
persist-key / persist-tun | Keeps the key and tunnel interface active across restarts. |
remote-cert-tls server | Ensures the server presents a valid certificate signed by the CA. |
cipher AES-256-GCM | Specifies the encryption algorithm for the data channel. |
auth SHA256 | Sets the HMAC authentication algorithm. |
ncp-ciphers ... | Allows negotiation of ciphers between client and server. |
verb 3 | Sets the log verbosity level (3 = recommended for general use). |
route 192.168.8.0 ... | Adds a route to the home LAN via the VPN tunnel. |
route 172.16.10.0 ... | Adds a route to the Always-on VPN subnet. |
ca , cert , key , tls-crypt | Specifies the file paths to the CA certificate, client certificate, private key, and TLS key. |
Start and Enable OpenVPN Client
With the configuration file in place and all required certificates and keys correctly referenced, the final step on the Azure side is to start the OpenVPN client service. This will initiate the connection to your home lab’s OpenVPN server and establish the secure tunnel. Enabling the service ensures that the VPN connection is automatically re-established after a reboot, providing persistent connectivity between your Azure environment and internal networks.
Run the following commands on the Azure VM:
sudo systemctl enable openvpn-client@azure
sudo systemctl start openvpn-client@azure
sudo systemctl status openvpn-client@azure
What These Commands Do
Command | Purpose |
---|---|
start | Launches the OpenVPN client using the config file /etc/openvpn/client/azure.conf . The @azure part matches the filename (azure.conf ). |
enable | Ensures the client starts automatically on boot, maintaining the VPN connection persistently. |
status | Displays the current status of the client service, including connection logs and any errors. |
Tip: If the client fails to connect, check the logs with:
journalctl -xeu openvpn-client@azure
Routing Considerations
Establishing the VPN tunnel is only half the battle—you also need to tell each network how to reach the other. This involves configuring route tables in Azure and potentially adding static routes on your home network.
Azure Route Table Configuration
In Azure, even though the VPN client (your VM) knows how to reach your home network via the tunnel, other Azure resources don’t—unless you explicitly tell them.
To fix this:
- Create a Route Table in the Azure portal.
- Add a custom route:
- Address prefix:
192.168.8.0/22
(Home LAN) and172.16.10.0/24
(Always-on VPN) - Next hop type: Virtual appliance
- Next hop IP address: The private IP of the Azure VM running the OpenVPN client
- Address prefix:
- Associate the route table with the subnet that contains your Azure resources.
This ensures that traffic from Azure VMs destined for your home network is routed through the OpenVPN client VM.
On-Premises Static Route (If Needed)
If your OpenVPN server is not the default gateway on your home network (e.g., it’s just another Linux box on your LAN), then other devices won’t know how to reach the Azure subnet (192.168.144.0/20
) unless you tell them.
To fix this:
- Add a static route on your home router or firewall:
- Destination:
192.168.144.0/20
- Next hop: The LAN IP address of the OpenVPN server
- Destination:
This tells your home network, “If you want to reach Azure, send the traffic to the OpenVPN server—it knows what to do.”
Add a Route for the VPN Tunnel Subnet
The VPN tunnel itself uses a dedicated subnet (192.168.254.0/24
) to assign virtual IPs to the OpenVPN server and client. While this subnet is primarily used internally by OpenVPN, there are scenarios where other devices on your network may need to reach these tunnel IPs—for example, for diagnostics, monitoring, or if you’re using the tunnel IPs as gateways for routing.
On-Premises (Home Network)
If your OpenVPN server is not the default gateway, and you want other devices on your LAN to be able to reach the Azure client’s tunnel IP, you should add a static route:
- Destination:
192.168.254.0/24
- Next hop: The LAN IP address of the OpenVPN server
This tells your home network:
“To reach the VPN tunnel subnet, send traffic to the OpenVPN server—it knows how to handle it.”
Azure (Optional)
In most cases, Azure resources won’t need to talk directly to the tunnel IPs, but if they do (e.g., for pinging the OpenVPN server’s tunnel IP), you can add a route in the Azure route table:
- Address prefix:
192.168.254.0/24
- Next hop type: Virtual appliance
- Next hop IP: The Azure VM’s private IP
Routing Summary
To ensure seamless communication between your home network, Azure, and the VPN tunnel, you need to configure routing on both sides of the connection. This includes:
- Azure route tables to direct traffic from Azure subnets to the VPN client
- Static routes on your home network if the OpenVPN server is not the default gateway
- (Optional) Routes to the VPN tunnel subnet if devices need to communicate with tunnel IPs
The table below summarizes the key routing requirements:
Location | Route Destination | Next Hop / Target | Purpose |
---|---|---|---|
Home Router / Firewall | 192.168.144.0/20 (Azure subnet) | LAN IP of OpenVPN server | Route Azure-bound traffic from home LAN through the VPN server |
Home Router / Firewall | 192.168.254.0/24 (VPN tunnel) | LAN IP of OpenVPN server | (Optional) Allow access to VPN tunnel IPs from home LAN |
Azure Route Table | 192.168.8.0/22 (Home LAN) | Private IP of Azure OpenVPN client VM | Route traffic from Azure to home LAN via the VPN tunnel |
Azure Route Table | 172.16.10.0/24 (Always-on VPN) | Private IP of Azure OpenVPN client VM | Route traffic from Azure to Always-on VPN subnet via the tunnel |
Azure Route Table | 192.168.254.0/24 (VPN tunnel) | Private IP of Azure OpenVPN client VM | (Optional) Allow Azure resources to reach tunnel IPs (e.g., for diagnostics) |
This routing setup ensures that all devices—whether in Azure or on-prem—know how to reach each other through the VPN tunnel. Without these routes, traffic may be dropped or misrouted, even if the VPN connection itself is active.
Test Connectivity
At this point, your Site-to-Site VPN should be fully operational. You’ve configured the server and client, established routing, set up firewall rules, and now it’s time to verify everything is working as expected.
- Try to ping across all subnets (Home LAN, Always-on VPN, Azure)
- Use
traceroute
to verify routing - Check logs:
- Server:
journalctl -xeu openvpn-server@server
- Client:
journalctl -xeu openvpn-client@azure
Troubleshooting Tips
If something isn’t working, here are the most common things to check:
Check | Why It Matters |
---|---|
Subnets do not overlap | Overlapping subnets can break routing and cause traffic to be misrouted or dropped. |
IP forwarding is enabled | Both server and client must have net.ipv4.ip_forward=1 set and applied via sysctl -p . |
iptables rules are present | Ensure forwarding rules exist between tun0 and eth0 for all relevant subnets. |
OpenVPN logs | Logs will show certificate issues, routing problems, or connection failures. |
At this point, your Site-to-Site VPN should be secure, stable, and routing traffic between Azure and your home network. Would you like to wrap this up with a conclusion or next steps (e.g., monitoring, scaling, or adding more sites)?
Troubleshooting Tips
- Ensure subnets do not overlap
- Double-check IP forwarding is on (
sysctl net.ipv4.ip_forward
) - Confirm iptables rules are present (
sudo iptables -L -v -n
) - Check OpenVPN logs for errors
Conclusion
With this setup, your Home and Azure networks are securely linked via OpenVPN, enabling seamless communication between remote environments as if they were part of the same local infrastructure. You’ve built a robust Site-to-Site VPN using strong encryption, certificate-based authentication, and clearly defined routing and firewall rules. This configuration not only ensures secure data transmission but also provides the flexibility to scale and adapt as your network grows.
One of the key strengths of this approach is its resilience and simplicity. By using OpenVPN in a client-server model, you avoid the need for complex NAT traversal or port forwarding on both ends—only the server side requires an open port. This makes it ideal for cloud-to-home lab scenarios, especially when you’re working with a single public IP or have overlapping port requirements, as was the case here.
Additionally, the use of per-client routing, static routes, and Azure route tables ensures that traffic flows correctly between all subnets, regardless of where the devices are located. This level of control is essential for maintaining performance, security, and visibility across your hybrid network.
This setup can easily be extended to support multiple remote sites, additional subnets, or even full mesh VPN topologies if needed. Whether you’re connecting branch offices, integrating cloud services, or simply building a more advanced home lab, this OpenVPN-based Site-to-Site VPN provides a solid, scalable foundation.