As I mentioned in the previous post, the Client VPN software that is generated for you to be able to connect your client to the P2S (Point-to-Site) Azure VPN solution, has a few shortcomings, at least for my situation.
The information and methods provided in this post are the results of an evening of tinkering and brainstorming with colleague Michael Verbeek (congrats on your official Azure certification!).
To summarize the shortcomings we found in the VPN Client package provided by Azure:
- We need my on-premises subnet to be routed through the VPN adapter
- We want the Root Certificate to be deployed when the VPN client software is installed
- Nice to have: We want to custom brand the startup screen and icons for the VPN Client software
Let’s see how many, if any, of these goals can be accomplished.
Almost forgot the disclaimer again. The steps shown here are the steps I took to reach certain goals. I’m in no way an Azure expert, so don’t just take my word for everything you read here. There might be better or more effective ways to reach the same goals. These steps achieve what I needed to achieve. Your situation might be different from mine.
First of all, log on to the management portal and download the 32bit and 64bit VPN Client packages.
They can be found on the Networks menu, drilling down into you Virtual Network, on the Dashboard tab:
Oh, and since the new portal is now Generally Available, here’s where to find the packages in the new portal (https://portal.azure.com):
If you look at the bread crumbs on top of the page, I clicked Browse in the menu, then Virtual Networks (Classic), then my Virtual Network (ITWORXX.azure) and then I clicked the VPN connections widget. On the right side I’ve marked the download links for the VPN Client software.
So, whichever portal you prefer, download both VPN Client packages.
This should net you 2 relatively small executable files, which are in fact self-extracting executables, meaning you can extract them with your favorite extractor tool. I use WinRar, but 7-zip works just as well.
If you prefer the command line options from the .exe files themselves:
Specify a /T:<full path to extract to> /C command.
Whichever method you choose, result should be two folders to which the .exe files are extracted:
I renamed the .exe files prior to extraction.
Let’s examine the contents of the x64 folder:
How very interesting. The two .ico files and the .bmp file are everything we need to reach our “nice to have” goal: branding the VPN adapter.
We can simply replace the icon files with our own (16×16 pixels and 32×32 pixels respectively) and replace the bitmap file with an image we prefer.
The cmroute.dll is a dll that is used by the client software to add the routes to the route table that are defined in the routes.txt file. This file is the only thing responsible for having two packages. The dll comes in a 32bit and 64bit version.
The .pbk file is a “phonebook” file, basically this holds the VPN profile entry settings.
Combine this with the .cmp and .cms files and the VPN profile is complete. If you have ever created a Connection Profile using the CMAK (Connection Manager Administration Kit), these files should look familiar.
This whole package looks like it was built using RAS CMAK, which you can install by adding it using the Add Windows Features option on your Windows desktop.
We tried using that but weren’t able to do anything useful with the files we have extracted. Instead we chose to manually do all the modifications we need.
The .cer file is the certificate for the Azure VPN Gateway communications.
The .inf file is the installation file that tells Windows where to put what and what to do with it.
So now that we have had a look at all the files in the package, let’s start modifying some of them.
We’ll be modifying the x64 package.
We replaced both .ico files with new icon files for IT-WorXX and we replaced the .bmp file with an IT-WorXX branded image.
Yeah, we started with the easiest bit. Quick win ftw.
Now open the routes.txt file using your favorite text editor:
Well look at that. That’s the entire address range of my ITWORXX.azure Virtual Network. That route tells us that any packets destined for 172.16.0.0/16 are routed to the Azure VPN Connection when it is connected. No need to know the IP it’s going to get when we connect, since “default” will be replaced when connected. Using this very same technique it’s a piece of cake to add a route to my on-premises subnet here.
There. Easy as pie. See the empty line after the last route entry? Don’t forget to leave that there. The file needs to end with a CRLF or it won’t work.
Ofcourse at this stage this was all just theory, but we’ll show the results later on. Relatively easy modification as well. Another quick win this one.
Now for the hardest part. We want our users to have the smoothest experience possible when installing the VPN Client software on a non-domain-joined device.
Since these devices do not have the CA IT-WorXX root certificate, we have two options for that user.
The first one is to add the root certificate to the .pfx file that we hand over to the user, which that user uses to authenticate. However, this generates a security popup when installing the .pfx telling the user that his or her device will now always trust that CA’s certificates. No big deal because that’s what happens when we use our own CA, but if we can avoid the popup, we avoid tickets or questions.
The second option is to try and install it with the VPN Client software. After all, it already installs a certificate for the Azure VPN Gateway as a trusted root as well.
We’re going for the second option.
First we exported the root certificated and copied it to the source folder:
Remember the .inf? That is the file that tells the installer what to do with all the files and where to put them. Open the .inf in a text editor and specifically have a look at lines 108-112:
No magical stuff happening here, just a simple cmd.exe to certutil to import the .cer file that is part of the package already. The comment even tells us this command is executed at the end of the install.
We’ll use that to add our own certificate. I copied line 111 to line 112 and modified it to my own root certificate.
I kept the source folder the same as the other certificate because I’m assuming that’s where the files are put during installation.
I also added a line to the uninstall information, starting at line 114:
Notice that you need the thumbprint for your root certificate in the uninstall section, instead of the filename which we added in the install section.
There are a few more sections where you need to add the filename for your root certificate:
Please note that all the line numbers I show in the .inf screenshots above reflect the numbers as they are after the changes, so if you’re using this as a guide to make your own modifications, work top to bottom or your numbers won’t match mine.
We have all modifications done. Couple of things left to do. Ofcourse we need to package the whole thing again. And if we re-package it, which method or tool do we use? But more importantly, which command do we issue to install the connection onto a target device? And most important probably, does it even work with all the modifications we just did?
To test it we need the command we need to issue. There’s a little trick to retrieve that. Open the original .exe file in a text editor. A whole lot of unreadable stuff, but search for your .inf filename:
And there it is. The command that is executed when you install the .exe file. Take note of this command, you’ll need it later.
To test the modifications I made, I open up a command prompt in the folder where my modified files are and issue that command there:
Not a lot seems to happen when issuing that command.
Let’s see if installing the .inf worked.
We have the VPN connection:
We have the required certificates in the root store:
Starting the VPN connection shows the modified .bmp:
We can successfully connect:
The routing table shows the route to the Azure Virtual Network, and the routing table shows the route to the IT-WorXX on-premises subnet:
We can reach a VM in the Azure Virtual Network, and we can reach a server on-premises:
Success! All modifications seem to work as intended.
All that is left to do is repackage everything. I don’t have access to fancy software to create an .msi file or any packaging software for that matter.
Luckily Michael Verbeek found a nice little tool inside Windows that can repackage everything into a .exe file, just like the files you can download from Azure itself. It’s been in Windows for forever and you probably didn’t even know it exists. It’s called IExpress 2.0.
The tool is in %windir%\system32\iexpress.exe and you need to run it as an administrator. I’ll show the steps for the x64 package, just for fun.
The goal here is to mimic the Azure VPN Client installation, which only shows a popup for confirmation during install, nothing else:
We’re creating a new package so I leave the defaults selected. Select the other option if you need to make modifications. Click the Next button:
Again, the default is what we want. Click the Next button:
This is actually the title of the popup window during installation, so I put “ITWORXX.azure” here. The Azure installation package using the Virtual Network name. Click the Next button:
This will be the text in the popup window during installation. To mimic the original installer I entered the text “Do you wish to install a Vpn Client for ITWORXX.azure?”. Click the Next button:
Neither does the original installation, so no. Click the Next button:
Click the Add button, browse to the folder containing all the files for the package, and add all the files. Click the Next button:
Enter the following command:
cmstp.exe /s /su /ns 5e397cd5-xxxx-xxxx-xxxx-465ca2d0641a.inf (of course replace the .inf name with the correct one)
Enter the correct command and click the Next button:
Select “Hidden” and click the Next button:
The original package doesn’t do this, so neither will we. Click the Next button:
Browse to a location where you want to store your installation package and give it a name. I choose “Custom ITWORXX.azure VPN x64.exe”. Check both boxes. We don’t want to see progress, and we want the original filenames in our package and they exceed the 8.3 standard. Click the Next button:
This pops up if you set the second check by the way. I told you it was in Windows like forever already:
Leave the defaults and click the Next button:
I left defaults here. This will be default save the .sed file (package definition file) next to the .exe you’re creating. Click the Next button:
After that click Next and Finish until the wizard is done and closes.
That finishes creating the x64 installer. Repeat as needed if you want to do the same for the x86 installer.
By the way, the custom installer needs to be run as an administrator, or the certificates can’t be installed into the stores and your VPN connection will not work. The original Azure .exe files enforce this, our custom package does not:
This is shown by the little shield on the icon.
Again, two solutions. Instruct your users to right click the executable and choose the Run as Administrator option, or, the better solution, add that shield to the executable.
If you want to have a shield like this, and thus enforcing the exe to be run with administrative priveliges, follow the following steps.
Download and install the Windows Software Development Kit (SDK) for the operating system of your choice. It really doesn’t matter which one you choose, I like to choose the one fitting my current operating system.
For Windows 8.1 you can download it here: https://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx
For Windows 10 you can download it here:
Both links will just download the install wrapper. When presented with the choice of what to install, choose the Windows SDK only. All other options are not needed.
Next you will need a manifest file. This file tells the operating system what to expect from your executable.
We’ll extract the manifest file from our custom .exe file using mt.exe from the Windows SDK issuing the following command:
mt.exe -inputresource:”yourexecutable.exe”;#1 -out:”yourexecutable.exe.manifest”
Open the manifest file that is now extracted in a text editor and modify line 17 as shown here:
Replace “asInvoker” with “requireAdministrator”.
Next we’ll replace the manifest in the custom .exe using mt.exe:
mt.exe -manifest “yourexecutable.exe.manifest” -outputresource:”yourexecutable.exe”
And there you have it:
A custom VPN Connection installer, which requires administrative rights to run, which acts and looks exactly the same as the original installer from the Azure Portal.
And with that all goals for this (optional) (side) step in the Azure Labs saga are achieved:
– Company branded VPN Connection
– Complete route table instead of just the Azure Virtual Network
– My company’s Root CA certificate included and installed