Tired of OpenVPN "Connection Reset" loops and OpenSSL 3.4 compatibility nightmares? In this guide, we skip the fluff and use strongSwan to build a rock-solid IKEv2 tunnel between Ubuntu and Azure.
1. Provisioning the Network with Azure CLI
First, let's build the infrastructure. We need a VNet and a Gateway with a Point-to-Site (P2S) configuration.
# 1. Create Resource Group and VNet
az group create -n RG-VPN-Lab -l eastus
az network vnet create -g RG-VPN-Lab -n VNet-Main --address-prefix 10.0.0.0/16 --subnet-name snet-workload --subnet-prefix 10.0.1.0/24
# 2. Add the Gateway Subnet (Required for the VPN Gateway)
az network vnet subnet create -g RG-VPN-Lab --vnet-name VNet-Main -n GatewaySubnet --address-prefix 10.0.255.0/27
# 3. Request a Public IP for the Gateway
az network public-ip create -g RG-VPN-Lab -n pip-vnet-gw --allocation-method Static --sku Standard
# 4. Create the Gateway (This takes ~20-30 mins)
az network vnet-gateway create -g RG-VPN-Lab -n VPNGateway --public-ip-address pip-vnet-gw --vnet VNet-Main --gateway-type Vpn --sku VpnGw1 --vpn-type RouteBased --client-protocol IKEv2 OpenVPN
2. Generating & Configuring Certificates
Azure needs to trust your Root CA. We’ll generate a self-signed pair.
# Generate Root CA
openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt -subj "/CN=VPNGW-ROOT"
# Generate Client Cert signed by Root
openssl req -new -nodes -newkey rsa:2048 -keyout client.key -out client.csr -subj "/CN=VPN-USER-ACC"
openssl x509 -req -days 365 -in client.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out client.crt
# Get the Clean DER string for Azure
CLEAN_DATA=$(openssl x509 -in rootCA.crt -outform der | base64 -w0)
# Upload to Azure
az network vnet-gateway update -g RG-VPN-Lab -n VPNGateway --address-prefixes 172.16.0.0/24 --root-cert-name FinalRootCA --root-cert-data "$CLEAN_DATA"
3. Installing strongSwan on Ubuntu
StrongSwan uses the native Linux kernel IPsec stack.
sudo apt update && sudo apt install strongswan libcharon-extra-plugins libstrongswan-standard-plugins -y
# Move certs to the right place
sudo cp rootCA.crt /etc/ipsec.d/cacerts/
sudo cp client.crt /etc/ipsec.d/certs/
sudo cp client.key /etc/ipsec.d/private/
sudo chmod 600 /etc/ipsec.d/private/client.key
4. Configuring the Client
Edit two files to bring the tunnel to life.
/etc/ipsec.conf
conn azure
keyexchange=ikev2
type=tunnel
leftauth=pubkey
leftcert=client.crt
leftsourceip=%config
right=YOUR_GATEWAY_FQDN.vpn.azure.com
rightauth=pubkey
rightid=%any
rightsubnet=10.0.0.0/16
auto=add
/etc/ipsec.secrets
: RSA client.key
5. Troubleshooting Tips (The "Gotchas")
❌ Fingerprint Mismatch
If you get AUTHENTICATION_FAILED, verify your fingerprints match.
-
Azure side:
az network vnet-gateway show ... --query "vpnClientConfiguration.vpnClientRootCertificates[0].publicCertData" -o tsv | base64 -d | openssl x509 -inform der -fingerprint -noout -
Local side:
openssl x509 -in /etc/ipsec.d/cacerts/rootCA.crt -fingerprint -noout
❌ "No Trusted RSA Public Key Found" (G2 Cert)
Ubuntu might not trust Microsoft's gateway. Download the DigiCert root into your cacerts folder:
sudo wget https://cacerts.digicert.com/DigiCertGlobalRootG2.crt.pem -O /etc/ipsec.d/cacerts/DigiCert_Global_Root_G2.crt
❌ "No Private Key Found"
Ensure your /etc/ipsec.secrets points exactly to the file in /etc/ipsec.d/private/ and that the permissions are 600.
Final Test
sudo ipsec restart
sudo ipsec up azure
ping 10.0.0.4
--- 10.0.0.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 175.319/175.319/175.319/0.000 ms
Top comments (0)