Photo by @archduk3 / Unsplash.com

Building a Point-to-Site VPN setup to Azure using Azure AD authentication

It’s early October, and we’re starting to experience the colder evenings and cold nights here where I live. Thus it’s the perfect time to tinker with another project – this time a VPN solution to Azure!

But aren’t VPN solutions so last season? Well, yes. And also, no – I’m now seeing several interesting use cases for this, so let me briefly explain these before diving into the solution.

Employees are not in the office any more

I think we’ve all witnessed in the past 550 days or so that employees are gone from the office. I visited a co-working space in August. Once, during this time. Many companies I interact with are still operating with the same model. The office, which I might also call the on-premises in this context, is empty – or at least very spacious for the few people who might work from there.

Most services might be migrated to the cloud – websites, intranets, extranets, custom services – all gone to the cloud. The physical things are still left behind: Wi-Fi access points, DHCP infrastructure to support those, printers, file shares, and Active Directory domain controllers. Printers are usually the reason people commute to the office. Personally, I utilize Universal Printing at home to print remotely without the need to VPN in.

Now that most operational services are in Azure enabling VPN access from the home office to these services might make sense. Obviously, the perhaps more modern approach of simply leveraging a regular HTTPS connection is also often enough. Yet, a VPN connection is often warranted for some services – such as Azure-based file shares, virtual machines, and such.

The Big Picture

The premise is that employees are working from home – or at least not from the office. The office might have a Site-to-Site VPN connection to Azure. This makes sense, yet it makes zero sense for most employees – they don’t want to operate any hardware at home, such as a VPN gateway.

The solution is to use a Point-to-Site VPN – which in traditional terms means a VPN dial-in from a user’s laptop to an Azure Virtual Network (VNet). This also isn’t new – it’s been around for years but relied on either RADIUS-based authentication or certificate-based authentication. Both are slightly cumbersome, as managing and distributing the certificates is what I’d consider equivalent to a root canal operation at the dentist, and RADIUS is often deployed these days.

Since 2020, the Point-to-Site VPN capability has included authenticating with a regular Azure AD account. Perfect! I never got around to deploying this then, so it was about to test that this works.

It’s often too easy to think that once something is documented on Microsoft Docs, that it “works” – and I’ve found that trialing these deployments with a fresh set of eyes tends to reveal the little cracks and issues you might encounter with customer deployments.

The solution

I set out to configure the Point-to-Site VPN infrastructure in Azure. And hoped to configure my current Windows 11 workstation (running 22000.194 build, the latest Beta Insider build before the October 5th release). This way, I could open a VPN connection to Azure, authenticate with my Azure AD account and forget the boring IT Pro stuff – certificates and RADIUS.

Getting to work: Provisioning the components in Azure

I need two components for this to work – a Virtual Network and a Virtual Network Gateway. The Virtual Network will be my TCP/IP network the user connects to through the VPN. And the Virtual Network Gateway is the virtualized VPN endpoint where the VPN clients connect to initially. It’s technically a highly available virtual machine, similar to a regular Windows Server with RRAS enabled.

I provisioned a new Virtual Network with the following settings:

  • Address space: 10.1.0.0/16
  • Subnet: default (10.1.0.0/24)

Everything else I left to defaults, which in essence disables all the fancy things I don’t need.

Once this is done, I added a new Virtual Network Gateway. As this is the more critical component, I opted to go with the defaults mostly:

  • Gateway type: VPN
  • VPN type: Route-based
  • SKU: Basic
  • Generation: Generation1
  • Virtual Network: <the VNet I just created>

SKU here defines the cost for your VPN deployment. Basic is the cheapest, and since it’s a previous generation, it lacks some of the greater things you might need in life. For my tests, this is usually enough. Microsoft considers the Basic SKU legacy at this time, so it might be sunset at some point in the future. The difference in price between Basic and the next option is considerable: Basic is $26/month, and VpnGw1 is $139/month. You can review the numerous options here.

Note: It’s perhaps best to opt for VpnGw1 if you can afford that, due to Basic already being marked as legacy and classic at this time.

Since the gateway requires the provisioning of a VM behind the scenes, it usually takes up to 50 minutes to provision this configuration. It’s frustrating, especially if you rapidly need to configure something – and then you end up waiting for the better part of an hour for ‘something’ to happen.

Configuring for Point-to-Site

Once the provisioning is done, all that is left is a configuration for Point-to-Site. Open your Virtual Network Gateway and Configuration first. You can verify your exact SKU here – and you should now verify you have the Standard SKU selected:

Hold on! We initially opted for the Basic SKU, didn’t we? Yes, but since we aim to use Azure AD authentication, that in turn requires the use of the Standard SKU (or any of the more expensive VpnGw SKUs). And this will cost more – although Azure Calculator doesn’t reflect this too clearly.

If you need to change the SKU from Basic to Standard at this point, it will easily take another 30 minutes to re-provision. If I revisited my initial setup, I would have selected the VpnGw1 instead of the Basic SKU – and mentally prepared in quadrupling my monthly cost with the VPN endpoint. You can convert to the newer one by re-deploying the gateway.

Next, click Point-to-site configuration on the left navigation. Before we fill out the configuration, we need to prepare our environment. You can find the exact instructions here. In essence, we’ll need to provide Admin Consent for our solution against Azure AD by calling this URL: https://login.microsoftonline.com/common/oauth2/authorize?client_id=41b23e61-6c1e-4545-b367-cd054e0ed4b4&response_type=code&redirect_uri=https://portal.azure.com&nonce=1234&prompt=admin_consent

This will provision an Enterprise App that looks like this in Azure AD:

Pick up the Application ID, as that’s needed next.

Back in Point-to-site configuration, fill out the form:

  • Address pool: 10.2.0.0/24 (something that fits within the VNet address range you provisioned previously)
  • Tunnel type: OpenVPN (SSL)
  • Authentication type: Azure Active Directory
  • Tenant: <your Azure AD tenant ID>
  • Audience: <Azure VPN application ID>
  • Issuer: https://sts.windows.net/ + Azure AD Tenant ID + trailing ‘/’

And that’s it! Click save, and prepare for a long wait. This usually takes me about 10 minutes to complete.

Once done, this is how it looks:

You can now download the VPN settings by clicking Download VPN client. Sadly, this doesn’t actually download the client any longer – just the necessary configuration data.

Configuring Azure VPN client

The peculiar thing here is that you have a choice between three different VPN clients:

  • The built-in Windows 10/11 VPN capability
  • The Azure VPN client
  • The OpenVPN client

Obviously, you’d be drawn to the first option as it’s built-in. Sadly, that doesn’t support Azure AD authentication, so you’re out of luck there.

Therefore, download the Azure VPN client from the Microsoft Store. Direct link to the app: https://www.microsoft.com/store/productId/9NP355QT2SQB

Once installed, open the app. You can now import the .XML file from the downloaded Azure VPN Client .ZIP-package (it’s under the \azurevpn\ folder). It looks like this:

But why is the Server Validation Certificate looking a bit off? This seems to be a bug in Windows 11 that something might break when you update from Windows 10 to Windows 11. For me, the certificate subsystem is somehow slightly broken, and the Azure VPN client is unable to recognize the correct certificate that is being offered from the .XML file:

I fought with this for the good part of an hour with the traditional tricks: the Certificates snap-in, importing and exporting, re-generating certs, and verifying they are correct. Yet, the Azure VPN client refused even to allow me to select anything else – it’s actually flickering and losing the selection if I click the dropdown menu now.

I suspected something was off, so I spun up a new Windows 11 in a VM. And it “just works”:

I guess my main Windows 11 (upgraded from Windows 10) will get a fresh install next week, when Windows 11 is officially available on October 5th.

And that’s it. Curiously, the Azure VPN actually configures the built-in VPN subsystem with these settings:

I can even connect now via the built-in Windows VPN capability! But nowhere will it prompt for a username or a password unless I’ve first connected via the Azure VPN app (which prompts for them properly). The Windows Credential Manager doesn’t store them, so I’m slightly intrigued by how they are passed. Perhaps time to dig into this in a future post.

Connecting via the Azure VPN is easy:

On the Azure side, I can verify that an IP has been allocated for the connection:

Perfect!

Additional configuration

I also needed to add custom routes for the connection. This way, the user can access resources that might not be found through the internal DNS. To add a custom route, open the original AzureVPN .XML-file, add this block:

<clientconfig>
<includeroutes>
<route>
<destination>20.50.2.65</destination>
<mask>32</mask>
</route>
</includeroutes>
</clientconfig>

You’ll then need to re-import the configuration to make these routes visible and accessible through the connection.

Additional thoughts

This was an interesting and educating project. Getting Azure AD-based authentication is great, but it isn’t without some downsides. Mostly, the use of the Azure VPN app is a bit problematic. It’s yet another app that needs managing, and even if distributing it via Intune or a similar venue is certainly possible, it lacks some capabilities we might need to rely on – namely, a Device Tunnel. We cannot open the VPN tunnel before the user has logged in, thus making it impossible to perform domain authentication on a workstation.

To achieve this, we’d need to revert to a certificate-based authentication (forgoing Azure AD altogether) and rely on the built-in VPN capability in Windows 10/11. Still good, but not as good as using Azure AD and relying on its superior security capabilities.