DEV Community

iapilgrim
iapilgrim

Posted on

Connecting Ubuntu to Azure VPN: The "No-Nonsense" StrongSwan Guide (2026 Edition)

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

Enter fullscreen mode Exit fullscreen mode

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"

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

/etc/ipsec.secrets

: RSA client.key

Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

Top comments (0)