VPN to Azure on PI

From Coolscript
Jump to navigation Jump to search



This is howto setup an OpenVPN between your Home-LAN and Azure in less than 15 Minutes!!!



Introduction

This Tutorial is about to create a VPN running OpenVPN between your Home-LAN (On-premises) and Azure.

The Setup allows you to route any traffic from your Home-LAN into Azure and vice versa.

The setup is using SNAT on both VPN Server which is the quickest way to solve routing and security issues (eg NSG) and is therefore less secure and has a lower performance because of NAT, but depending on the proposed solution it is possible to skip the SNAT / Netfilter setup.

Optional it is possible to use the Home-OpenVPN Server as default gateway for Home-Clients, this way the home client is adapting the Azure Public IP Address. This is very useful if a public IP address is needed within another country. Note that this configuration requires SNAT for sure. Also note that this can result in a high traffic usage for which you get charged extra by Azure.

The setup is using Port 443 to communicate between the VPN Server because this port is almost alwyas open on WLans but any other port can be chosen too.




Requirements

  • Your Home LAN with internet
  • Raspberry-PI or alternative another Linux Server
  • Azure Subscription
  • Azure CLI Tools installed somewhere
  • Logged on terminal into AZ





Quick installations steps

  • The following steps are needed to setup the VPN:
    • Create an Azure Network using the Azure CLI
    • Create Routing between the networks using the Azure CLI
    • Create VM using the Azure CLI
    • Install OpenVPN on a VM within Azure
    • Setup both OpenVPN Server
    • Setup Home LAN
    • Setup the Home LAN routing





Overview








Azure

Create a custom Resurce-ID

Create the Resource-ID VPN-Test. This Resource-ID is used through all command samples below.

az group create --name VPN-Test --location eastus
root@rb01:~# az group create --name VPN-Test --location eastus
{
  "id": "/subscriptions/727d7068-94e3-494a-965a-xxxxx/resourceGroups/VPN-Test",
  "location": "eastus",
  "managedBy": null,
  "name": "VPN-Test",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}

Setup Vnet

Create a Custom Virtual Net

Create the Virtual-Net VNet01. This Name is used through all command samples below.

az network vnet create --name VNet01 \
--resource-group VPN-Test \
--location eastus \
--address-prefix 10.0.0.0/16
root@rb01:~# az network vnet create --name VNet01 --resource-group VPN-Test --location eastus --address-prefix 10.0.0.0/16
{
"newVNet": {
  "addressSpace": {
    "addressPrefixes": [
      "10.0.0.0/16"
    ]
  },
  "bgpCommunities": null,
  "ddosProtectionPlan": null,
  "dhcpOptions": {
    "dnsServers": []
  },
  "enableDdosProtection": false,
  "enableVmProtection": false,
  "etag": "W/\"38ff6021-dede-4633-a431-de744603f625\"",
  "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/virtualNetworks/VNet01",
  "ipAllocations": null,
  "location": "eastus",
  "name": "VNet01",
  "provisioningState": "Succeeded",
  "resourceGroup": "VPN-Test",
  "resourceGuid": "ab5d3b7d-4c7e-4243-aba5-a30a72017666",
  "subnets": [],
  "tags": {},
  "type": "Microsoft.Network/virtualNetworks",
  "virtualNetworkPeerings": []
 }
}







Create a Subnet SN01

az network vnet subnet create \  
--address-prefix 10.0.1.0/24 \
--name SN01 \
--resource-group VPN-Test \
--vnet-name VNet01 
root@rb01:~# az network vnet create --name VNet01 --resource-group VPN-Test --location eastus --address-prefix 10.0.0.0/16
{
 "newVNet": {
   "addressSpace": {
     "addressPrefixes": [
       "10.0.0.0/16"
     ]
   },
   "bgpCommunities": null,
   "ddosProtectionPlan": null,
   "dhcpOptions": {
     "dnsServers": []
   },
   "enableDdosProtection": false,
   "enableVmProtection": false,
   "etag": "W/\"38ff6021-dede-4633-a431-de744603f625\"",
   "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/virtualNetworks/VNet01",
   "ipAllocations": null,
   "location": "eastus",
   "name": "VNet01",
   "provisioningState": "Succeeded",
   "resourceGroup": "VPN-Test",
   "resourceGuid": "ab5d3b7d-4c7e-4243-aba5-a30a72017666",
   "subnets": [],
   "tags": {},
   "type": "Microsoft.Network/virtualNetworks",
   "virtualNetworkPeerings": []
 }
}






Create a Subnet SN02

az network vnet subnet create \  
--address-prefix 10.0.2.0/24 \
--name SN02 \
--resource-group VPN-Test \
--vnet-name VNet01 
root@rb01:~# az network vnet subnet create --address-prefix 10.0.2.0/24 --name SN02 --resource-group VPN-Test --vnet-name VNet01
{
 "addressPrefix": "10.0.2.0/24",
 "addressPrefixes": null,
 "delegations": [],
 "etag": "W/\"1930d1f7-7d54-4642-bc87-c73173238b76\"",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/virtualNetworks/VNet01/subnets/SN02",
 "ipAllocations": null,
 "ipConfigurationProfiles": null,
 "ipConfigurations": null,
 "name": "SN02",
 "natGateway": null,
 "networkSecurityGroup": null,
 "privateEndpointNetworkPolicies": "Enabled",
 "privateEndpoints": null,
 "privateLinkServiceNetworkPolicies": "Enabled",
 "provisioningState": "Succeeded",
 "purpose": null,
 "resourceGroup": "VPN-Test",
 "resourceNavigationLinks": null,
 "routeTable": null,
 "serviceAssociationLinks": null,
 "serviceEndpointPolicies": null,
 "serviceEndpoints": null,
 "type": "Microsoft.Network/virtualNetworks/subnets"
}






Create a Route Table

az network route-table create \
 --name MyRouteTable \
--resource-group VPN-Test
root@rb01:~# az network route-table create \
>  --name MyRouteTable \
>  --resource-group VPN-Test
{- Finished ..
 "disableBgpRoutePropagation": false,
 "etag": "W/\"3fca8554-5b01-4201-9ed2-1c55dc55244d\"",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/routeTables/MyRouteTable",
 "location": "eastus",
 "name": "MyRouteTable",
 "provisioningState": "Succeeded",
 "resourceGroup": "VPN-Test",
 "routes": [],
 "subnets": null,
 "tags": null,
 "type": "Microsoft.Network/routeTables"
}








Create VPN Route


az network route-table route create \ 
 --name ToVPNTun \ 
 --resource-group VPN-Test \ 
 --route-table-name myRouteTable \  
 --address-prefix 10.9.0.0/24 \ 
 --next-hop-type VirtualAppliance \ 
 --next-hop-ip-address 10.0.1.4 
root@rb01:~# az network route-table route create \
>   --name ToVPNTun \
>   --resource-group VPN-Test \
>   --route-table-name myRouteTable \
>   --address-prefix 10.9.0.0/24 \
>   --next-hop-type VirtualAppliance \
>   --next-hop-ip-address 10.0.1.4

{- Finished ..
 "addressPrefix": "10.9.0.0/24",
 "etag": "W/\"00429bd4-3e32-440d-8163-c543d9781c56\"",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/routeTables/myRouteTable/routes/ToVPNTun",
 "name": "ToVPNTun",
 "nextHopIpAddress": "10.0.1.4",
 "nextHopType": "VirtualAppliance",
 "provisioningState": "Succeeded",
 "resourceGroup": "VPN-Test",
 "type": "Microsoft.Network/routeTables/routes"
}






Create Home Route

az network route-table route create \
 --name ToPrivateSubnet \
 --resource-group VPN-Test \
 --route-table-name myRouteTable \
 --address-prefix 192.168.178.0/24 \
 --next-hop-type VirtualAppliance \
 --next-hop-ip-address 10.0.1.4
root@rb01:~# az network route-table route create \
>   --name ToPrivateSubnet \
>   --resource-group VPN-Test \
>   --route-table-name myRouteTable \
>   --address-prefix 192.168.178.0/24 \
>   --next-hop-type VirtualAppliance \
>   --next-hop-ip-address 10.0.1.4

{- Finished ..
 "addressPrefix": "192.168.178.0/24",
 "etag": "W/\"6f85a76c-1969-4f9e-9190-ba419c7f4436\"",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/routeTables/myRouteTable/routes/ToPrivateSubnet",
 "name": "ToPrivateSubnet",
 "nextHopIpAddress": "10.0.1.44",
 "nextHopType": "VirtualAppliance",
 "provisioningState": "Succeeded",
 "resourceGroup": "VPN-Test",
 "type": "Microsoft.Network/routeTables/routes"
}






Associate Subnet SN01

az network vnet subnet update \ 
 --name SN01 \ 
 --vnet-name Vnet01 \ 
 --resource-group VPN-Test \ 
 --route-table MyRouteTable 
root@rb01:~# az network vnet subnet update \
>   --name SN01 \
>   --vnet-name Vnet01 \
>   --resource-group VPN-Test \
>   --route-table MyRouteTable
{
 "addressPrefix": "10.0.1.0/24",
 "addressPrefixes": null,
 "delegations": [],
 "etag": "W/\"437692a4-54c5-4cb9-b9c5-8216f36ed6da\"",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/virtualNetworks/Vnet01/subnets/SN01",
 "ipAllocations": null,
 "ipConfigurationProfiles": null,
 "ipConfigurations": [
   {
     "etag": null,
     "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/networkInterfaces/vm-az-vpngw01VMNic/ipConfigurations/ipconfigvm-az-vpngw01",
     "name": null,
     "privateIpAddress": null,
     "privateIpAllocationMethod": null,
     "provisioningState": null,
     "publicIpAddress": null,
     "resourceGroup": "VPN-Test",
     "subnet": null
   }
 ],
 "name": "SN01",
 "natGateway": null,
 "networkSecurityGroup": null,
 "privateEndpointNetworkPolicies": "Enabled",
 "privateEndpoints": null,
 "privateLinkServiceNetworkPolicies": "Enabled",
 "provisioningState": "Succeeded",
 "purpose": null,
 "resourceGroup": "VPN-Test",
 "resourceNavigationLinks": null,
 "routeTable": {
   "disableBgpRoutePropagation": null,
   "etag": null,
   "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/routeTables/MyRouteTable",
   "location": null,
   "name": null,
   "provisioningState": null,
   "resourceGroup": "VPN-Test",
   "routes": null,
   "subnets": null,
   "tags": null,
   "type": null
 },
 "serviceAssociationLinks": null,
 "serviceEndpointPolicies": null,
 "serviceEndpoints": null,
 "type": "Microsoft.Network/virtualNetworks/subnets"
}






Associate Subnet SN02

az network vnet subnet update \
 --name SN02 \
 --vnet-name Vnet01 \
 --resource-group VPN-Test \
 --route-table MyRouteTable
root@rb01:~# az network vnet subnet update \
>   --name SN02 \
>   --vnet-name Vnet01 \
>   --resource-group VPN-Test \
>   --route-table MyRouteTable

{
 "addressPrefix": "10.0.2.0/24",
 "addressPrefixes": null,
 "delegations": [],
 "etag": "W/\"1fa47832-5492-4c2b-b7e4-ea0a7a4e2e7e\"",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/virtualNetworks/Vnet01/subnets/SN02",
 "ipAllocations": null,
 "ipConfigurationProfiles": null,
 "ipConfigurations": [
   {
     "etag": null,
     "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/networkInterfaces/vm-sn02-client01VMNic/ipConfigurations/ipconfigvm-sn02-client01",
     "name": null,
     "privateIpAddress": null,
     "privateIpAllocationMethod": null,
     "provisioningState": null,
     "publicIpAddress": null,
     "resourceGroup": "VPN-Test",
     "subnet": null
   }
 ],
 "name": "SN02",
 "natGateway": null,
 "networkSecurityGroup": null,
 "privateEndpointNetworkPolicies": "Enabled",
 "privateEndpoints": null,
 "privateLinkServiceNetworkPolicies": "Enabled",
 "provisioningState": "Succeeded",
 "purpose": null,
 "resourceGroup": "VPN-Test",
 "resourceNavigationLinks": null,
 "routeTable": {
   "disableBgpRoutePropagation": null,
   "etag": null,
   "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/routeTables/MyRouteTable",
   "location": null,
   "name": null,
   "provisioningState": null,
   "resourceGroup": "VPN-Test",
   "routes": null,
   "subnets": null,
   "tags": null,
   "type": null
 },
 "serviceAssociationLinks": null,
 "serviceEndpointPolicies": null,
 "serviceEndpoints": null,
 "type": "Microsoft.Network/virtualNetworks/subnets"
}







Setup the OpenVPN Port (443) to our Azure Gateway

az vm open-port --resource-group VPN-Test \
 --name  vm-az-vpngw01 \
 --port 443 \
 --priority 910
root@rb01:~# az vm open-port --resource-group VPN-Test --name  vm-az-vpngw01 --port 443 --priority 910
{- Finished ..
 "defaultSecurityRules": [
   ....
   ....

   {
     "access": "Allow",
     "description": null,
     "destinationAddressPrefix": "*",
     "destinationAddressPrefixes": [],
     "destinationApplicationSecurityGroups": null,
     "destinationPortRange": "443",
     "destinationPortRanges": [],
     "direction": "Inbound",
     "etag": "W/\"5373a937-ddaf-4392-b364-5a720fdf3723\"",
     "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Network/networkSecurityGroups/vm-az-vpngw01NSG/securityRules/open-port-443",
     "name": "open-port-443",
     "priority": 910,
     "protocol": "*",
     "provisioningState": "Succeeded",
     "resourceGroup": "VPN-Test",
     "sourceAddressPrefix": "*",
     "sourceAddressPrefixes": [],
     "sourceApplicationSecurityGroups": null,
     "sourcePortRange": "*",
     "sourcePortRanges": [],
     "type": "Microsoft.Network/networkSecurityGroups/securityRules"
   }
 ],
 "subnets": null,
 "tags": {},
 "type": "Microsoft.Network/networkSecurityGroups"
}






Create Virtual Machines

Create vm-az-vpngw01 with Static Public IP

Note that this sample includes a static public IP address


az vm create --resource-group VPN-Test \ 
 --name vm-az-vpngw01 --location eastus \ 
 --image "Debian:debian-10:10:latest" \ 
 --vnet-name VNet01 \ 
 --subnet SN01 \ 
 --admin-username azadmin --admin-password xxxxxxxxx \ 
 --size Standard_B2s \ 
 --public-ip-address myPublicIpAddress \ 
 --public-ip-address-allocation static 


root@rb01:~# az vm create --resource-group VPN-Test \
>  --name vm-az-vpngw01 --location eastus \
>  --image "Debian:debian-10:10:latest" \
>  --vnet-name VNet01 \
>  --subnet SN01 \
>  --admin-username azadmin --admin-password xxxxxxxxxx \
>  --size Standard_B2s \
>  --public-ip-address myPublicIpAddress \
>  --public-ip-address-allocation static
{- Finished ..
 "fqdns": "",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Compute/virtualMachines/vm-az-vpngw01",
 "location": "eastus",
 "macAddress": "00-0D-3A-8C-CC-FB",
 "powerState": "VM running",
 "privateIpAddress": "10.0.1.4",
 "publicIpAddress": "52.188.151.230",
 "resourceGroup": "VPN-Test",
 "zones": ""
}






Create a Client within SN02. No Static Public IP

Note that this sample does not includes a public IP address


 az vm create --resource-group VPN-Test \ 
 --name vm-sn02-client01 --location eastus \ 
 --image "Debian:debian-10:10:latest" \ 
 --vnet-name VNet01 \ 
 --subnet SN02 \ 
 --admin-username azadmin --admin-password xxxxxxxx \ 
 --size Standard_B2s \ 
 --public-ip-address  ""
root@rb01:~# az vm create --resource-group VPN-Test \
>  --name vm-sn02-client01 --location eastus \
>  --image "Debian:debian-10:10:latest" \
>  --vnet-name VNet01 \
>  --subnet SN02 \
>  --admin-username azadmin --admin-password xxxxxxxxxxx \
>  --size Standard_B2s \
>  --public-ip-address 
{- Finished ..
 "fqdns": "",
 "id": "/subscriptions/727d7068-94e3-494a-965a-XXXXX/resourceGroups/VPN-Test/providers/Microsoft.Compute/virtualMachines/vm-sn02-client01",
 "location": "eastus",
 "macAddress": "00-0D-3A-8B-C7-33",
 "powerState": "VM running",
 "privateIpAddress": "10.0.2.4",
 "publicIpAddress": "",
 "resourceGroup": "VPN-Test",
 "zones": ""
}







Setup the Azure OpenVPN Gateway

Install

Install and setup

Install openvpn, nftables and other required tools

# apt-get install openvpn nftables mc dnsutils net-tools dnsutils curl lynx

Setup IP Forward

  • Allow IP Forward next to other features. Edit /etc/sysctl.conf
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
net.ipv4.ip_forward=1
  • Run sysctl to apply the above changes
sysctl -p

Setup Nftables

#!/usr/sbin/nft -f

flush ruleset

table ip filter_v4 {
      chain INPUT {
              type filter hook input priority 0; policy accept;
      }

      chain OUTPUT {
              type filter hook output priority 0; policy accept;
      }

      chain FORWARD {
              type filter hook output priority 0; policy accept;
      }
}

table ip nat {
 
      chain PREROUTING {
              type nat hook prerouting priority -100; policy accept;
      }

      chain POSTROUTING {
              type nat hook postrouting priority 100; policy accept;
              ip saddr 10.9.0.0/24 oifname "eth0" counter snat to 10.0.1.4  comment "SNAT for TUN"
              ip saddr 192.168.178.0/24 oifname "eth0" counter snat to 10.0.1.4  comment "SNAT for HOME"
      }
}
  • Alternative you could set masquerade which is easier to configurate but has a less performance than snat
              ip saddr 10.9.0.0/24 oif "eth0" counter masquerade comment "VPN Masq Rule"
              ip saddr 192.168.178.0/24 oif "eth0" counter masquerade comment "Home Masq Rule"

Start/Stop/Enable Nftables

  • Run to manual start (apply) the script:
nft -f /etc/nftables.conf
  • Run to manual stop nft:
nft flush ruleset
  • To enable at system start run:
systemctl enable nftables

Setup OpenVPN

Server Key

Get the existing static key file or create a new one using:

openvpn --genkey --secret /etc/openvpn/static.key

Configuration

  • Setup the configuration in /etc/openvpn/server.conf
dev tun
proto tcp-server
port 443
ifconfig 10.9.0.1 10.9.0.2
route 192.168.178.0 255.255.255.0
cipher AES-256-CBC
comp-lzo
keepalive 10 60
persist-key
persist-tun
secret /etc/openvpn/static.key
log /var/log/openvpn.log
verb 6

Apply the new configuration to systemctl

systemctl daemon-reload 

Restart OpenVPN

systemctl restart openvpn
  • Key permissions must be 600 depending on the running user which is root in our case
root@vm-az-vpngw01:/etc/openvpn# ls static.key -all
-rw------- 1 root root 636 Nov 14 19:37 static.key
  • Ifconfig after openvpn has been started, see tun0
root@vm-az-vpngw01:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
       inet 10.0.1.4  netmask 255.255.255.0  broadcast 10.0.1.255
       inet6 fe80::20d:3aff:fe8c:ccfb  prefixlen 64  scopeid 0x20<link>
       ether 00:0d:3a:8c:cc:fb  txqueuelen 1000  (Ethernet)
       RX packets 3997  bytes 1924662 (1.8 MiB)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 4123  bytes 835293 (815.7 KiB)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
       inet 127.0.0.1  netmask 255.0.0.0
       inet6 ::1  prefixlen 128  scopeid 0x10<host>
       loop  txqueuelen 1000  (Local Loopback)
       RX packets 0  bytes 0 (0.0 B)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 0  bytes 0 (0.0 B)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
       inet 10.9.0.1  netmask 255.255.255.255  destination 10.9.0.2
       inet6 fe80::6243:a0d0:cf55:78f7  prefixlen 64  scopeid 0x20<link>
       unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (UNSPEC)
       RX packets 0  bytes 0 (0.0 B)
       RX errors 0  dropped 0  overruns 0  frame 0
       TX packets 0  bytes 0 (0.0 B)
       TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Setup the Raspery-PI OpenVPN Gateway

Install

Install and setup

Install openvpn, nftables and other required tools

sudo apt-get install openvpn nftables mc dnsutils net-tools dnsutils curl lynx

Setup IP Forward

  • Allow IP Forward next to other features. Edit /etc/sysctl.conf
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
net.ipv4.ip_forward=1
  • Run sysctl to apply the above changes
sysctl -p

Setup Nftables

#!/usr/sbin/nft -f

flush ruleset

table ip filter_v4 {
      chain INPUT {
              type filter hook input priority 0; policy accept;
      }

      chain OUTPUT {
              type filter hook output priority 0; policy accept;
      }

      chain FORWARD {
              type filter hook output priority 0; policy accept;
      }
}

table ip nat {
 
      chain PREROUTING {
              type nat hook prerouting priority -100; policy accept;
      }

      chain POSTROUTING {
              type nat hook postrouting priority 100; policy accept;
              ip saddr 10.0.0.0/16 oifname "eth0" counter snat to 10.0.1.4  comment "SNAT for Azure VNet01"
      }
}


  • Alternative you could set masquerade which is easier to configurate but has a less performance than snat
ip saddr 10.0.1.0/24 oif "eth0" counter masquerade comment "SN01 Masq Rule"
ip saddr 10.0.2.0/24 oif "eth0" counter masquerade comment "SN02 Masq Rule"

Start/Stop/Enable Nftables

  • Run to manual start (apply) the script:
nft -f /etc/nftables.conf
  • Run to manual stop nft:
nft flush ruleset
  • To enable at system start run:
systemctl enable nftables

Setup OpenVPN

Server Key

Get the existing static key file or create a new one using:

openvpn --genkey --secret /etc/openvpn/static.key

Configuration

Setup the configuration in /etc/openvpn/server.conf


remote 52.188.151.230
proto tcp-client
port 443
dev tun
ifconfig 10.9.0.2 10.9.0.1
cipher AES-256-CBC
comp-lzo
keepalive 10 60
persist-key
persist-tun
secret /etc/openvpn/static.key
log /var/log/openvpn.log
verb 6
#Default Routing
route 10.0.1.0 255.255.255.0
route 10.0.2.0 255.255.255.0

Apply the new configuration to systemctl

systemctl daemon-reload 

Restart OpenVPN

systemctl restart openvpn

Setup Routing

The quickest way to setup routing within the Home-LAN is to do this on your ISP Router, the following is showing the static route table on a Fritz Box


Standard Route

Home-LAN RB01

The standard route allows the HOME-LAN clients to access the Azure Subnet01 and Subnet01 via RB01, all other packages will pass the default gateway of 192.168.179.1.
This setup will work without SNAT in most cases.
Within the OpenVPN configuration it is needed to define the routing like this:

root@rb01 ~ # cat /etc/openvpn/server.conf  | grep route
route 10.0.1.0 255.255.255.0
route 10.0.2.0 255.255.255.0
root@rb01 ~ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.178.1   0.0.0.0         UG    0      0        0 eth0
10.0.1.0        10.9.0.1        255.255.255.0   UG    0      0        0 tun0
10.0.2.0        10.9.0.1        255.255.255.0   UG    0      0        0 tun0
10.9.0.1        0.0.0.0         255.255.255.255 UH    0      0        0 tun0
192.168.178.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0
Home-LAN VM-WIN01
  • Within the standard setup the windows home-client keeps his default gateway
C:\Windows\system32>route print
 
===========================================================================
Persistent Routes:
 Network Address          Netmask  Gateway Address  Metric
         0.0.0.0          0.0.0.0  192.168.178.1         1
===========================================================================
  • The standard setup alows the Windows Home-Client to reach machines within AZ SN1
C:\Windows\system32>tracert 10.0.2.4

Tracing route to 10.0.2.4 over a maximum of 30 hops

 1    <1 ms    <1 ms    <1 ms  FRITZ-NAS [192.168.178.1]
 2     1 ms   219 ms   118 ms  10.9.0.1
 3   111 ms   108 ms   107 ms  10.0.2.4

Trace complete.


Obtain your public IP Address, it should be the one from your ISP Router

C:\Windows\system32>curl ipconfig.io
37.x.y.z

Route through Azure

Home-LAN RB01

This setup allows the Home-LAN VPN Server to become a default gateway for clients,
to do this setup the redirect-gateway autolocal option and remove the static route options

root@rb01 ~ # cat /etc/openvpn/server.conf  | grep gateway
#route 10.0.1.0 255.255.255.0
#route 10.0.2.0 255.255.255.0
redirect-gateway autolocal

Then restart openvpn (# systemctl restart openvpn) and see the kernel route:

root@rb01 ~ # route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.9.0.1        0.0.0.0         UG    0      0        0 tun0
10.9.0.1        0.0.0.0         255.255.255.255 UH    0      0        0 tun0
192.168.178.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0

Changing the default route on the Home-LAN Windows client:

C:\Windows\system32> route -p change 0.0.0.0 mask 0.0.0.0 192.168.178.201

Obtain again your public IP Address, it should now be the one from Azure

C:\Windows\system32>curl ipconfig.io
52.188.151.230