Securing any infrastructure means, amongst other things, protecting machines from unnecessary exposure, and restricting remote administration access. While having an SSH port open to the world is sometimes a necessary evil, a preferable approach is to restrict access, via a firewall or security group, to a smaller, more controlled network.
If you always administer your systems from a single location - home, office, etc - it is practical to simply whitelist those IP addresses. However, if you are ever working remotely it’ll become necessary to either manually add your current IP address, or use a VPN.
The VPN solution on Azure is the topic of this post. But more specifically, how to make it accessible from a Linux system. There are plenty of how-tos around about how to setup a VPN on Azure, so this post will focus on the specifics of making it compatible with Linux.
VPN Selection
The first thing to understand is the different SKU for the VPN product, and what they mean:
SKU | S2S/VNet-to-VNet Tunnels | P2S SSTP Connections | P2S IKEv2/OpenVPN Connections | Aggregate Throughput Benchmark | BGP | Zone-redundant |
---|---|---|---|---|---|---|
Basic | Max. 10 | Max. 128 | Not Supported | 100 Mbps | Not Supported | No |
VpnGw1 | Max. 30* | Max. 128 | Max. 250 | 650 Mbps | Supported | No |
VpnGw2 | Max. 30* | Max. 128 | Max. 500 | 1 Gbps | Supported | No |
VpnGw3 | Max. 30* | Max. 128 | Max. 1000 | 1.25 Gbps | Supported | No |
VpnGw1AZ | Max. 30* | Max. 128 | Max. 250 | 650 Mbps | Supported | Yes |
VpnGw2AZ | Max. 30* | Max. 128 | Max. 500 | 1 Gbps | Supported | Yes |
VpnGw3AZ | Max. 30* | Max. 128 | Max. 1000 | 1.25 Gbps | Supported | Yes |
Table 1: https://docs.microsoft.com/en-us/azure/vpn-gateway/vpn-gateway-about-vpngateways
There are to Point-to-site (P2S) options:
- SSTP - Secure Socket Tunnelling Protocol
- IKEv2/OpenVPN
OpenVPN is more widely supported, and is easier to configure, but SSTP is the only option available on the Basic Azure VPN SKU.
Key Pairs
(Updated 2020-10-03)
You will need a user key pair to use to authenticate. This need to end up as a key and certificate PEM file, and can either be converted to these using OpenSSL
, or you can generate these yourself if you are setting up the the VPN yourself.
Converting a Provided P12
# Extract the certificate
openssl pkcs12 -in nigel.p12 -out nigelCert.pem -clcerts -nokeys
# Extract the private key
openssl pkcs12 -in nigel.p12 -nocerts -nodes | openssl rsa -aes256 > nigelKey.pem
Generating Your Own
This is super brief, and I recommend finding a better tool or tutorial if you get stuck.
First you need a CA key pair
openssl rsa -in caKey.pem -outform PEM -pubout -out caCert.pem
The contents of public.pem
, minus the BEGIN CERTIFICATE barriers, can be copied into the Azure Portal VPN Setup.
Now you need to generate a signed user key pair. The following script creates an encrypted user key pair. It will prompt for 2 passwords, first the user password, then the CA password.
#!/bin/bash
read -p 'Please provide a user key password' PASSWORD
export USERNAME=$1
ipsec pki --gen --outform pem > "${USERNAME}Key.pem"
ipsec pki --pub --in "${USERNAME}Key.pem" | ipsec pki --issue --cacert caCert.pem --cakey caKey.pem --dn "CN=${USERNAME}" --san "${USERNAME}" --flag clientAuth --outform pem > "${USERNAME}Cert.pem"
openssl pkcs12 -in "${USERNAME}Cert.pem" -inkey "${USERNAME}Key.pem" -certfile caCert.pem -export -out "${USERNAME}.p12" -password "pass:${PASSWORD}"
SSTP
(Updated 2020-01-11)
SSTP is a PPP over HTTPS protocol that is used primarily by Azure. It has official clients for Windows and OSX. There is a project to provide a Linux client, which which with a little bit of work, can be used on Ubuntu. Currently you’ll need to set this up using a PPA and a pppd
config, although there is a Network Manager UI coming.
Debian Packages
From https://github.com/enaess/network-manager-sstp
You can import the gpg key using the following command:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 61FF9694161CE595
Put the following two lines into the following file: /etc/apt/sources.list.d/sstp-client.list
deb http://ppa.launchpad.net/eivnaes/network-manager-sstp/ubuntu eoan main
deb-src http://ppa.launchpad.net/eivnaes/network-manager-sstp/ubuntu eoan main
Setting Up Connection
The first step is to get the client download from the Azure VPN portal. This contains the connection settings, and the VPN certificate.
The certificate will be in DER format, and this needs to be in PEM format. To convert, use openssl
openssl x509 -inform DER -in VpnServerRoot.cer -out VpnServerRoot.pem
Now, install the SSTP which can be done on Ubuntu/Debian by using the PPA provided by the author (see the site).
Finally, setup a provider in /etc/ppp/peers
. I’ve named mine /etc/ppp/peers/azure-vpn
.
remotename REMOTE_NAME
linkname azure-vpn
ipparam azure-vpn
pty "sstpc --ipparam azure-vpn --nolaunchpppd --ca-cert /etc/ppp/VpnServerRoot.pem VPN_IP"
name CERT_CN
plugin sstp-pppd-plugin.so
sstp-sock /var/run/sstpc/sstpc-azure-vpn
require-mppe
require-eap
refuse-mschap-v2
refuse-pap
refuse-chap
refuse-mschap
nobsdcomp
nodeflate
noauth
password KEY_PASSWORD
ca CA_FILE
cert CERT_FILE
key CERT_KEY
You’ll need to substitute in some values as follows.
Substitute | From |
---|---|
REMOTE_NAME | VpnServer value in VpnSettings.XML . Remove the azuregateway- prefix. If this is wrong then the server certificate will not validate |
VPN_IP | The IP of the VPN server from the Azure console |
KEY_PASSWORD | This is the password to the user key |
CERT_CN | The CN from your client certificate. Get it using openssl x509 -subject -nocert < CERT_FILE (see below) |
azure-vpn | You can leave this, or change it, just make sure it is consistent as it is used to correlate all the parts of the PPP operation |
CA_FILE | Points to the server certificate we converted earlier. I put mine /etc/ppp/VpnServerRoot.pem |
CERT_FILE | Points to the user’s certificate |
CERT_KEY | Points to the user’s encrypted key |
At this point you should be able to run pon azure-vpn
and connect. However, out of the box nothing will route beyond the initial VPN subnet. The VpnServer.xml
file also contains a Routes
element that contains the list of router that should be exposed. To use these create a file in /etc/ppp/ip-up.d/9999azure-vpn
:
#!/bin/sh
if [ "$PPP_IPPARAM" = "azure-vpn" ] ; then
ip route add 10.4.0.0/16 via $PPP_LOCAL dev $PPP_IFACE
fi
Replace the 10.4.0.0/16
address with your own routes. Also, make sure you chmod +x /etc/ppp/ip-up.d/9999azure-vpn
.
Now, disconnect (poff
) and reconnect (pon azure-vpn
) and you should have a working connection.
OpenVPN
OpenVPN however, is a more widely available VPN solution, with out-of-the-box support in Linux.
As you can see in Table 1 OpenVPN is not supported using the Basic SKU. Therefore, if you want the easy ride, use one of the others.
Setup
Microsoft have their own howto, but this was my approach. Start by installing the Network Manager extensions for OpenVPN
apt install network-manager-openvpn-gnome network-manager-openvpn
Next, download the VPN Client Config from the Azure VPN Portal.
Now, extract the config zip file, and [import the config] (https://www.cyberciti.biz/faq/linux-import-openvpn-ovpn-file-with-networkmanager-commandline/)
sudo nmcli connection import type openvpn file OpenVPN/vpnconfig.ovpn
This will create the VPN configuration called vpnconfig in your Network Manager VPN screen.
Edit the connection, fixing up the name, and supplying your user certificates.
Conclusion
If SSTP becomes available in the main Debian/Ubuntu repos then it would also be a good option, but in terms of return on time investment, OpenVPN is the best current option for Linux admins using Azure.