Obligatory Warning
Building a server isn’t like getting a prickly pear cactus, bamboo plant, or the Ronco® Showtime® Rotisserie & BBQ. Making a server is like getting a dog: you must give it care and attention, or it will become a menace to society.
If you build this server and neither update nor check up on it, I can practically guarantee it will become part of a botnet. Depending on your host and jurisdictions, you may also be liable for any damage (both tangible and intangible) that this server causes. This liability is why I provide Web Administration services, but I digress.
I warned you, and I’ll sleep soundly arming you with the following knowledge.
Background
I recently ran into a situation where I needed to run a test with a Québec City IP address.
I checked every well-known Virtual Private Network (VPN) provider for their server lists, but none had servers specifically in Québec City. Regardless, I tested with a VPN in Montreal, which is in the Canadian province of Quebec and about 3 hours away (163 mi/263 km) from Québec City, but I couldn’t reproduce the issue.
The software developer requesting help troubleshooting the issue suggested using Microsoft Azure to create a Virtual Machine (VM) in Québec City, also known as Microsoft Azure’s Canada East region, and thus my search began.
It turns out that Microsoft Azure has had cloud infrastructure service in Québec City since May 2016, so it was vexing that there wasn’t a VPN with the same service.
Possibly because of the 12-month free trial that new accounts automatically receive, I couldn’t create a VM in the Canada East region. So, this project will fill that gap.
Abstract
After additional research, I found it’s possible to create a VPN Gateway in Canada East and have the VM use the linked Virtual Network (VNet) as a Network Interface Controller (NIC). We need the VPN Gateway to connect to the VNet securely, but the VM will also use it to connect to the Internet.
We’ll make the VM private by allowing no incoming connections outside the VNet, not even Secure Shell (SSH). Since there are no incoming connections, we won’t assign the VM a public IP address. We’ll access the VM by connecting to the VNet first, then use local IP addresses.
It’s easier to test with a full web browser, so we’ll also need a Desktop Environment (DE), a way to connect to the VM with a Graphical User Interface (GUI), and a web browser with a GUI.
To achieve this, we’ll cover these steps in this guide:
- Configure a point-to-site VPN connection in Canada East with self-signed certificate authentication.
- Connect to the VNet with the Azure VPN Client software.
- Create a Private Linux VM using the VNet as a NIC.
- Use SSH to install the xfce4 DE and xrdp in the Linux VM to access it with the Remote Desktop Protocol (RDP).
- Install Google Chrome for web browsing and use SFTP to download files from the VM.
Materials
The best thing about software is that it doesn’t require much: a Microsoft Azure VM running Ubuntu 20.04 LTS.
Procedure
Setting up this system is involved considering the extra steps for making the VM private. First, get started with a Microsoft Azure free account. Now, the fun begins.
Create a Microsoft Azure VNet and RouteBased VPN Gateway
Since we can’t make a VM in the Canada East region, we’ll first have to make a VNet there instead. The VNet will also need a way to connect to the Internet, so we’ll also make a VPN Gateway in the same region.
The official documentation covers the steps for making the VNet and will be the most up-to-date, but we’ll summarize them in this guide.
First, create a VNet with a private IP address range that you’re not using on the Local Area Network (LAN). For example, most consumer LANs use the 192.168.0.0/16 address range, while most enterprise LANs use the 10.0.0.0/8 address range. This convention is because, typically, consumers don’t need many IP addresses while enterprises do.
To prevent conflicts with either convention, we can use the 172.16.0.0/12 address range, as the documentation does.
Follow the documentation for creating a VNet with these changes:
- For Region, select Canada East.
- For IPv4 address space, enter 172.17.0.0/16.
- For Subnet address range, enter 172.17.0.0/24.
Finally, we’ll need a VPN Gateway (also known as Virtual Network Gateway) to connect into and out of the VNet we created.
Follow the documentation for creating a VPN Gateway with these changes:
- Region should already be Canada East. If not, then change it to match the VNet.
- The documentation should have Basic selected for Public IP Address Type. If not, change it so that it’s not using a static IP address.
- For Gateway subnet address range, enter 172.17.255.0/27.
Well, we have our VNet in Canada East, where we’ll deploy our VM, and we have a VPN Gateway where our VNet can connect to the Internet, but how do we connect to the VNet?
Create Self-signed Certificates with PowerShell and Connect with Azure VPN Client
The previous guide listed the various ways to use certificates and even ways to create self-signed certificates. We’ll use PowerShell to make the root and client certificates in this instance. Next, we’ll use the root certificate to configure the VPN Gateway as a point-to-site VPN. Then, we’ll use the client certificate with the Azure VPN Client to connect to the VNet.
First, we’ll use PowerShell to make the root certificate and save it in the $cert variable by running this:
$cert = New-SelfSignedCertificate -Type Custom -KeySpec Signature `
-Subject "CN=VNet1GWRootCert" -KeyExportPolicy Exportable `
-HashAlgorithm sha256 -KeyLength 2048 `
-CertStoreLocation "Cert:\CurrentUser\My" -KeyUsageProperty Sign -KeyUsage CertSign
In the same PowerShell console, we’ll create the client certificate using the root certificate in the $cert variable by running this:
New-SelfSignedCertificate -Type Custom -DnsName VNet1GWChildCert -KeySpec Signature `
-Subject "CN=VNet1GWChildCert" -KeyExportPolicy Exportable `
-HashAlgorithm sha256 -KeyLength 2048 `
-CertStoreLocation "Cert:\CurrentUser\My" `
-Signer $cert -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2")
Tip
If the PowerShell console is closed for any reason, there are instructions for how to find the root certificate and create the $cert variable for it.
Next, we must export the root certificate as a .cer file so we can use it to configure the VPN Gateway as a point-to-site VPN.
The fastest way to open the Certificate Manager is by pressing Windows Key + R, entering certmgr.msc, then pressing Enter.
Look for the root certificate under Personal then Certificates in the left pane:

To export it, click the Action option in the menu, then go to All Tasks and select Export…:

Follow the default options in the Certificate Export Wizard except under Export File Format, select Base-64 encoded X.509 (.CER):

Under File to Export, enter an easy-to-remember location, like:
%HOMEDRIVE%%HOMEPATH%\Documents\root
The above path creates a root.cer file in the Documents folder so we can open it in Notepad and copy the contents. Now that we have a physical copy of the root certificate, we can go back to the VNet Gateway to upload it as part of the point-to-site configuration.
Follow the documentation for configuring point-to-site with the following changes:
- For Address pool, enter 172.16.201.0/24.
- For Tunnel type, select OpenVPN (SSL). Since we’re using the Azure VPN Client to connect, we don’t need any other type.
- For Name under Root certificates, enter VNet1GWRootCert to match our root certificate’s name.
After the point-to-site settings save, the Download VPN Client option should be available. Select it to download a .zip file with the same name as the now VPN Gateway. In this instance, it’s a file called VNet1GW.zip.
The official documentation for configuring the Azure VPN Client includes links to download it, including the Microsoft Store.
Tip
Press CTL+M then enable Compact View to make the Azure VPN Client less cluttered.
Next, follow the official documentation to configure the Azure VPN Client. To summarize the documentation:
- Extract the azurevpnconfig.xml file in the AzureVPN folder.
- Press CTL+I in the Azure VPN Client and select the azurevpnconfig.xml file.
- Everything should auto-populate except for Certificate Information under Client Authentication. For that dropdown, select the name of the client certificate. In this instance, it’s VNet1GWChildCert.
Now, the Azure VPN Client can connect to our VNet. In this example, it’s VNet1:

Click Connect, and it should indicate we’re connected:

We connected our computer to the VNet in Canada East, but there aren’t any resources in our VNet.
Create a Private Linux VM in our VNet and Connect with SSH and RDP
Now that we finished the networking, we can create the VM in Canada East and connect to it. We’ll make it private by allowing no incoming connections and not provisioning a public IP address.
Follow the official documentation for creating a VM with the following changes:
- For Resource group, select the same resource group used for the VNet and VPN Gateway. In this instance, it’s TestRG1.
- Leave Region blank to make it use the region of the VNet.
- Image should default to Ubuntu Server 20.04 LTS. If not, change it to the latest version of Ubuntu Server.
- For some reason, Size defaulted to Standard_D2s_v3. Change it to B2s under B-Series.
- For Public inbound ports, select None.
- For OS disk type, select Standard HDD. We don’t need any of the speed or benefits of the SSD options.
- Virtual network should automatically populate to our VNet. If not, select it.
- Likewise, Subnet should be the one we configured for our VNet, but select it if it wasn’t.
- For Public IP, select None.
Note
Although B1s is eligible for free services, it only has one vCPU, which doesn’t work well with Google Chrome. Even with a lightweight DE like xfce4.
Tip
Under Auto-shutdown, select Enable auto-shutdown and deselect Notification before shutdown. Auto-shutdown is a great way to save costs on a VM only used for testing. Don’t forget to set it to a time you won’t be working.
Next, connect to the VM with SSH using the IP address under Private IP address to start installing software:

Since the Azure VPN Client connects us to the VNet, we can access the VM “locally.”
Tip
As I mentioned in my CentOS AMI Web and Mail Server with DDNS guide, I prefer PuTTY/KiTTY when connecting from Windows operating systems. However, the documentation includes instructions for PowerShell.
After connecting with SSH, we need a more standard web browsing experience. So follow the official documentation for installing a DE and an RDP server. To summarize the documentation, run the following commands:
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install xfce4
sudo apt-get -y install xrdp
sudo systemctl enable xrdp
sudo adduser xrdp ssl-cert
echo xfce4-session >~/.xsession
sudo service xrdp restart
sudo passwd azureuser
A wall of bash commands is tough to process, but this is what we’re doing:
- Update all software to its latest version. Running an update is a good idea after an initial installation of an operating system.
- Install the xfce4 DE. By specifying DEBIAN_FRONTEND=noninteractive, we’re telling the package manager not to prompt for anything and the -y switch accepts all defaults.
- Install the xrdp RDP software.
- Start the xrdp service.
- Add the xrdp user used by the service to the ssl-cert group. The ssl-cert group is a requirement for Ubuntu 20.04 LTS so the xrdp user can access SSL certificates.
- Tell xrdp to use the xfce4 DE we installed.
- Restart the xrdp service to pick up the changes.
- Set a password for the azureuser account. The xrdp client only uses password authentication, so we need one for authentication.
Next, go to VM in the Azure Portal, and under Settings, select Connect, RDP, then click Download RDP File.
As it says, it downloads an .rdp file with the name of the VM. In this case, it’s called CA-E.rdp.
When we open the file, it opens the Remote Desktop Connection software. After clicking Connect and entering the username and password we previously created, we’ve logged into our Microsoft Azure VM with a DE:

Finally, download and install Google Chrome by entering the following:
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt-get -y install ./google-chrome-stable_current_amd64.deb
With Google Chrome installed, we can check our IP address and confirm we’re in the VNet’s region:

Okay, we can access websites in a browser that supports JavaScript with an IP address in a different country, but how do we get files from the VM to our computer? Well, it turns out there’s an old protocol that lets us do just that.
Transfer Files with SFTP
The SSH File Transfer Protocol (SFTP) has been around since way back in 1997 and distinguishes itself by providing some file manager features. I defer to Wikipedia for the details, but SFTP lets us connect to the VM using SSH with a protocol designed for secure file transfer.
Tip
There are many SFTP Clients out there, but I prefer FileZilla because it’s as stable as an igneous rock and has a portable version.
First, open the Site Manager and fill out the following:

- In the General tab, select SFTP under Protocol.
- Put the same Private IP address used in SSH and RDP under Host and leave Port blank, so it uses the default.
- Under Logon Type, select Key file since we’re using SSH.
- Put the same username used in SSH and RDP under User.
- For Key file, enter the path of the .ppk file created using PuTTY/KiTTY. Alternatively, use the file manager to select it by clicking Browse….
Finally, click Connect and use the SFTP Client to navigate to the desired folders, then right-click the file to select the Download option in the menu to copy over files:

With that, we have a computer (well, it’s technically a VM) in a different country that we can use to access websites and transfer files.
Neat.
Results


The Microsoft Azure B2s instance runs Ubuntu 20.04 LTS with RDP and SFTP access on a VPN located in Québec City.
Conclusion
In this project, I learned the ultimate form of spoofing an IP address by effectively making a VPN with extra steps and features.
I can’t say I recommend creating a VPN with a GUI, but it’s helpful in edge cases where one needs an IP address in a specific region with a JavaScript-enabled browser.
Nevertheless, this project was highly educational. The secure way of accessing a private VM in this project has given me an idea for another project I’ve been researching.
Truthfully, the cloud has limitless possibilities, so stay tuned to explore them all!