Navigating Azure Networking: Setting Up OpenVPN for Secure AKS Access
Navigating Azure Networking: Setting Up OpenVPN for Secure AKS Access 🌐🔒 Ensuring secure access to critical infrastructure is more important than ever. In this article, I describe my experience setting up OpenVPN server on an Azure VM to securely connect to an AKS (Azure Kubernetes Service) cluster without exposing sensitive services to the public. 🔍 What’s covered: ✅ Setting up OpenVPN on Ubuntu within a private Azure network ✅ Configuring Azure’s Load Balancer to route traffic securely to the VPN ✅ Solving networking and routing issues (including the infamous VPN quirks) ✅ Split tunnelling: accessing internal resources without losing access to the public internet 💡 The process is detailed with step-by-step instructions, real world challenges, and the solutions that helped me secure my cloud environment and set up seamless access to AKS and other services. If you’re looking to set up your own secure access to Azure or are just curious about networking in Azure, this article might save you hours of trial and error! 👇 Check it out and feel free to drop a comment or question below if you’ve gone through a similar setup. Let’s connect and share our experiences!

Aman Karir
Tech Enthusiast
🔐 Security is paramount, especially when working with critical infrastructure like Kubernetes (AKS) clusters. And if you’re someone who needs secure remote access to internal resources, a Virtual Private Network (VPN) is essential for protecting your connections to the cloud.
Here’s how I set up an OpenVPN Server on a VM to securely connect my Machine to an internal network while leveraging Azure’s load-balancing capabilities. Along the way, I’ll share the challenges I faced, how I overcame them, and the steps that worked for me. Let’s dive in!
The Challenge: Securely Accessing Azure Resources 🚧
My DevOps project started in Docker, moved to Minikube, and eventually was migrated to various cloud services for a complete end-to-end pipeline. It was a great introduction to DevOps, but in my last article, I began transitioning that public project into a private and secure environment. The last missing step? Allowing my machine to access the private network I had set up in Azure.
While Azure Bastion was already in place for accessing the VM, I thought it would be easier to just open Tunnelblick and connect that way. 🎯
I opted to use OpenVPN Server on an Ubuntu VM inside my Azure Virtual Network (VNet). Initially, I thought about using Azure’s Point-to-Site VPN for a secure connection, but as many of us know, that didn’t go as smoothly as expected 😅. Here's what happened next.
The Goals Were Simple 🎯
Set up a VPN server to securely connect to Azure resources.
Ensure secure connections to private services, including APIs and the AKS cluster.
Manage traffic routing efficiently while minimizing cost and complexity.

Seriously, Microsoft, extend that free trial. As much as I've loved every aspect of learning Azure DevOps, given that half of the things didn't work as intended, I would've rather have spent that money on a few pints of Guinness!
Step 1: Setting Up OpenVPN on Ubuntu 🖥️
In my previous article, I deployed a clean Ubuntu VM within my AKS VNet for my DevOps agent. The goal now was to securely access the private resources within the network from my machine. Here's how I got started:
1. Install OpenVPN on the VM

2. Generate the Certificate Authority (CA) and Server Keys
Using Easy-RSA, I created a PKI and generated the necessary keys:

3. Configure OpenVPN Server
I configured the OpenVPN server with the required certificates and keys, then set up the server.conf file:

4. Enable IP Forwarding
I enabled IP forwarding to allow the VM to route traffic:

Step 2: The Load Balancer Setup and Troubleshooting 💡
At this point, the OpenVPN server was set up and running on the VM, but when I tried to connect using Tunnelblick on my machine, the connection attempt would start, but it would get stuck on "waiting for the client".
This happened because the VM did not have a public IP, it was behind the Azure Bastion, which was only accessible internally. Without a public IP or a way to route external traffic to my private VM, I couldn’t establish the VPN connection properly.
Azure Load Balancer Setup:
To resolve this, I added a load balancer to route the traffic externally to my private VM:
Frontend IP Configuration: I created a public IP for the load balancer.
Backend Pool: I added my VM to the backend pool.
Inbound NAT Rule: Configured the NAT rule to route OpenVPN traffic (UDP 1194) from the load balancer to my private VM.
This configuration allowed me to use the public IP of the load balancer to route traffic to my VM. With this change, I was able to successfully establish a connection to the OpenVPN server. 🚀
Configuring Split Tunnelling:
Once I had connected to the VPN, I encountered a routing issue; all traffic was routed through the VPN, causing me to lose access to Azure Bastion and external websites (Reddit, how could I lose you?! 😢). This happened because the VPN was configured to route all traffic via the tunnel (due to the push "redirect-gateway def1" directive).
To fix this:
I removed the push "redirect-gateway def1" directive from the OpenVPN server config.
I added split tunnelling on the client side by adding route-nopull to the client config.
This change allowed my VPN connection to route only internal traffic through the VPN while leaving external traffic unaffected. Now, Reddit & LinkedIn were back online, and I could access Azure Bastion once again. 🎉
Bonus step: Setting Up Azure Storage for File Transfer from VM to my local machine 💾
Since my VM was in a private network without a public IP, I needed a way to transfer files like OpenVPN configuration files from the VM to my machine. Azure Storage made this simple:
Created an Azure Storage Account: I created a storage account in the same resource group as my VM.
Set Up a Blob Container: I created a blob container to securely store the files I needed to transfer.
Upload Files from the VM to Azure Blob Storage: I installed the Azure CLI on the VM with the following command:

Once that was installed, I authenticated using my Azure credentials. Then, I uploaded the required files using the following command:

Download the Files to my machine: Once the files were uploaded to Azure Blob Storage, I connected to Azure via terminal to download the files:

This approach provided a seamless way to move the OpenVPN files between the VM in a private network and my local machine, leveraging Azure’s secure and easy-to-use storage solutions.
Step 3: Testing and Final Configuration ✅
Once I resolved the routing issues and got everything connected, I tested the setup by connecting to the OpenVPN server using Tunnelblick on my machine. Here’s what I confirmed:
I could ping the private IP of the VM.
I could access Azure Bastion using the private IP.
LinkedIn and other external sites were accessible again, thanks to split tunnelling.
Final Config for the OpenVPN Client (client.ovpn):

Lessons Learned and Final Thoughts
This OpenVPN setup wasn’t without its challenges. From routing issues, load balancing, to split tunnelling, there were a few roadblocks along the way. But by using Azure’s Load Balancer and NAT rules, I was able to secure the VM while keeping it accessible through OpenVPN.
Key Takeaways:
Secure the VM by removing the public IP and placing it behind a load balancer or private network.
Configure split tunnelling to access both private and public resources simultaneously.
Test the VPN connection thoroughly to ensure seamless access to both internal services and external websites.
This setup allowed me to create a secure, isolated network for Azure resources while still providing external access to specific services.
If you’re considering setting up OpenVPN on your own Azure VM, I hope this guide helps you. Let me know if you have any questions or need further clarification! 💬
Final Thoughts 🌟
If you made it this far, thanks for reading! This was a journey into the depths of Azure networking, OpenVPN, and the sometimes painful but rewarding experience of trying to make everything work seamlessly. It wasn’t easy, but the feeling of success when it finally came together was worth it.
I’d love to hear your experiences, whether you’ve had similar struggles with Azure networking or OpenVPN, or if you have any tips to share. Let’s chat below! 👇
Next Steps ✅
🔄 Fully test my Azure Pipeline to ensure it now works with all these changes made and update it accordingly
🔄 Automate VPN Config Distribution. Use Terraform/Ansible/Puppet to manage the OpenVPN VM and distribute .ovpn configs securely