2015年10月7日

[Azure]在Azure上設定OpenVPN作為VPN Gateway

Azure提供Site-to-Site或是Point-to-Site VPN兩種方式讓我們可以透過Secure VPN Tunnel將本地端與雲端連接起來;在較新的ARM (Azure Resource Manager)版本中,暫時只支援Site-to-Site VPN,如果需要使用Point-to-Site VPN時,一個解決方式是透過自行架設OpenVPN Server來達成。
為了順利建構OpenVPN Server,我們需要完成以下幾件事:
<![if !supportLists]>1.      <![endif]>建立VNet
<![if !supportLists]>2.      <![endif]>VNet中建立一台OpenVPN Gateway,並設定OpenVPN
<![if !supportLists]>3.      <![endif]>設定User Define route讓雲端與本地端可以雙向溝通
接下來的範例,我們會建置以下的架構

Create OpenVPN VM

<![if !supportLists]>1.       <![endif]>Create a "Resource Manager " VNet



<![if !supportLists]>2.       <![endif]>Create GW-Subnet for Gateway uses



<![if !supportLists]>3.       <![endif]>Create VM-Subnet for Appliance VM uses
<![if !supportLists]>·         <![endif]>Open Newly created VNet to Add a new Subnet (VM-Subnet)
<![if !supportLists]>·         <![endif]>Add a new Subnet



<![if !supportLists]>·         <![endif]>Your VNet should contains these two Subnets
<![if !supportLists]>4.       <![endif]>Provision OpenVPN Gateway VM in GW-Subnet, here we use Ubuntu 14.0.4 as our OpenVPN gateway



<![if !supportLists]>5.       <![endif]>Add the VM to newly created Resource Group



<![if !supportLists]>6.       <![endif]>Add OpenVPN gateway to newly created VNet, resides in GW-Subnet



<![if !supportLists]>7.       <![endif]>Add a new Network Security Group



<![if !supportLists]>8.       <![endif]>Give it a new, allow all UDP traffic



<![if !supportLists]>9.       <![endif]>Allow traffic going to UDP 1194



<![if !supportLists]>10.   <![endif]>Your Network Security Group should look like this



<![if !supportLists]>11.   <![endif]>Once completed, press OK to create OpenVPN gateway VM



<![if !supportLists]>12.   <![endif]>Once provisioned, open Essentials, click on the public Ip address to bring up IP Address blade



<![if !supportLists]>13.   <![endif]>Click "Configuration" to bring up "Configuration" blade



<![if !supportLists]>14.   <![endif]>Give it a unique DNS name and press Save
<![if !supportLists]>15.   <![endif]>Now you can ssh to the gateway VM



Configure OpenVPN Server

<![if !supportLists]>16.   <![endif]>SSH into OpenVPN server
<![if !supportLists]>17.   <![endif]>Execute the following command to update all packages and install OpenVPN server and Easy-RSA package
sudo apt-get update



sudo apt-get install openvpn easy-rsa
                Not to press "Y" for any questions



<![if !supportLists]>18.   <![endif]>Now execute the following commands to initialize my_ca directory for certificates
cd /etc/openvpn
sudo mkdir easy-rsa
cd easy-rsa
sudo make-cadir my_ca
sudo bash
cd my_ca
<![if !supportLists]>19.   <![endif]>Now we need to edit vars file to configure default values for certificates. You can skip this step if you want to keep everything by default.
sudo vi /etc/openvpn/easy-rsa/my_ca/vars
<![if !supportLists]>20.   <![endif]>Once opened, find the following settings and change to desired values
export KEY_COUNTRY="TW"
export KEY_PROVINCE="TW"
export KEY_CITY="Taipei"
export KEY_ORG="YourCompanyName"
export KEY_EMAIL="yourmail@yourcompany.com"
export KEY_OU="R&D"



<![if !supportLists]>21.   <![endif]>Now we need to build keys for server and client certificates
cd /etc/openvpn/easy-rsa/my_ca
. ./vars
. ./clean-all
. ./build-ca



<![if !supportLists]>22.   <![endif]>When promoted to input certain values, accept defaults or input desired values.



<![if !supportLists]>23.   <![endif]>Execute the following command, accept all defaults and press "y" when promoted the following questions:
<![if !supportLists]>·         <![endif]>Sign the certificate? [y/n]:y
<![if !supportLists]>·         <![endif]>1 out of 1 certificate requests certified, commit? [y/n]y
./build-key-server server



<![if !supportLists]>24.   <![endif]>Now to create client certificates, OpenVPN grants two free clients, each identified by certificate Common Name. Accept all defaults and input desired client name for this certificate
./build-key client1
               



When promoted the following questions, press "y"
<![if !supportLists]>·         <![endif]>Sign the certificate? [y/n]:
<![if !supportLists]>·         <![endif]>1 out of 1 certificate requests certified, commit? [y/n]y



<![if !supportLists]>25.   <![endif]>Repeat step 24 to create second client certificate
./build-key client2
<![if !supportLists]>26.   <![endif]>Now execute the following command, this can take some times.
./build-dh
<![if !supportLists]>27.   <![endif]>Now copy dh2048.pem, ca.cert, server.crt and server.key to /etc/openvpn
cd /etc/openvpn/easy-rsa/my_ca/keys
cp dh2048.pem ca.crt server.crt server.key /etc/openvpn

<![if !supportLists]>28.   <![endif]>Now we are going to configure OpenVPN server, to do this we will uses OpenVPN's smaple server.conf as a base.
cd /usr/share/doc/openvpn/examples/sample-config-files
cp server.conf.gz /etc/openvpn
cd /etc/openvpn
gunzip server.conf.gz
<![if !supportLists]>29.  <![endif]> Edit server.conf file
sudo vi server.conf
<![if !supportLists]>·         <![endif]>Find the following configuration
server 10.8.0.0 255.255.255.0
and replace them to your VPN pool base IP
server {{VPNPOOL BASEIP} {MASK} #such as server 10.1.2.0 255.255.255.255




<![if !supportLists]>·         <![endif]>Uncomment the following lines
user nobody
group nogroup

<![if !supportLists]>·         <![endif]>Confirm the following *.cer and *.key file names are exactly the same as you specified earlier
ca ca.crt
cert server.crt
key server.key  # This file should be kept secret
                       

dh dh2048.pem
           
<![if !supportLists]>·         <![endif]>Push routes to client, the IP address (10.1.100.4) here is the Azure Private IP address of the OpenVPN gateway
push "route 10.1.100.4 255.255.255.255"
<![if !supportLists]>·         <![endif]>Uncomment the following line
push "redirect-gateway def1 bypass-dhcp" 
<![if !supportLists]>·         <![endif]>Configure static client folder
client-config-dir ccd
<![if !supportLists]>30.   <![endif]>Once completed, save and exit.



Configure Firewall using ufw

<![if !supportLists]>31.   <![endif]>Execute the following command
sudo bash
echo 1 > /proc/sys/net/ipv4/ip_forward
exit
<![if !supportLists]>32.   <![endif]>Edit /etc/sysctl.conf
sudo vi /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

<![if !supportLists]>33.   <![endif]>Now allow ssh and UDP/1193 traffic
sudo ufw allow ssh
sudo ufw allow 1194/udp
<![if !supportLists]>34.  <![endif]>Now to modify ufw configuration file
sudo vi /etc/default/ufw
<![if !supportLists]>·         <![endif]>Change the following configuration form "DROP" to "ACCEPT"
DEFAULT_FORWARD_POLICY="ACCEPT"

<![if !supportLists]>35.  <![endif]>Now to modify ufw rules file
sudo vi /etc/ufw/before.rules
<![if !supportLists]>·         <![endif]>Add the following lines above *filter; change 10.1.2.0/24 to VPN IP pools IP address.
# START OPENVPN RULES
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
# Allow traffic from OpenVPN client to eth0
-A POSTROUTING -s 10.1.2.0/24 -o eth0 -j MASQUERADE
COMMIT
# END OPENVPN RULES
<![if !supportLists]>36.  <![endif]>Now enable ufw service
<![if !supportLists]>37.  <![endif]>Now to modify ufw rules file





Configure Static Client IP

<![if !supportLists]>38.   <![endif]>Create ccd directory
sudo mkdir /etc/openvpn/ccd
<![if !supportLists]>39.   <![endif]>Create configuration file for each client, file name must be the Common Name of your client certificate. In this example, client1 and client2.
sudo vi /etc/openvpn/ccd/client1
<![if !supportLists]>·         <![endif]>Add the following line to the file, change {CLIENT-STATIC-IP} to desired client ip address, in this example, 10.1.2.6 and 10.1.2.7
ifconfig-push {CLIENT-STATIC-IP} 255.255.255.255
push "route {CLIENT IP POOL CIDR} {MASK} {GATEWAY}"
<![if !supportLists]>40.   <![endif]>Once configured, start OpenVPN service
<![if !supportLists]>41.   <![endif]>

Copy certificate files to client

<![if !supportLists]>42.   <![endif]>Execute the following commands to copy required client files to Downloads directory
mkdir -m 0700 ~/Downloads
cd ~/Downloads
sudo cp /etc/openvpn/easy-rsa/my_ca/keys/ca.crt .
sudo cp /etc/openvpn/easy-rsa/my_ca/keys/client1.crt .
sudo cp /etc/openvpn/easy-rsa/my_ca/keys/client1.key .
sudo cp /etc/openvpn/easy-rsa/my_ca/keys/client2.key .
sudo cp /etc/openvpn/easy-rsa/my_ca/keys/client2.crt .

sudo sed 's/$/\r/' /usr/share/doc/openvpn/examples/sample-config-files/client.conf > ~/Downloads/OpenVPNGW.ovpn

sudo chown $USER *
<![if !supportLists]>43.   <![endif]>In windows, open cmd prompt, download pscp from system internals. And execute the following commands to copy files to client machine.
pscp azureuser@23.99.113.89:Downloads/"*" .\cer



Install and configure OpenVPN client

<![if !supportLists]>44.   <![endif]>Download and install OpenVPN client in your client machine here: https://openvpn.net/index.php/open-source/downloads.html
<![if !supportLists]>45.   <![endif]>Copy client certificate files to OpenVPN install folder\config
<![if !supportLists]>46.   <![endif]>Rename OpenVPNGW.ovpn to client1.ovpn or client2.ovpn depends on which your client is
<![if !supportLists]>47.   <![endif]>Modify the following line to fit your OpenVPN gateway address
remote xxxxxx.eastasia.cloudapp.azure.com 1194
<![if !supportLists]>48.   <![endif]>Specify correct .crt and .key file name for your client here



Configure Azure VNet User defined routes


Add-AzureAccount

$vpnIpPool = "10.1.2.0/24"
$openVpnGwIP = @"10.1.100.4"
$vnetResourceGroup = "OpenVPN-DEMO-RG"
$location = "East Asia"
$vnetName = "openVPNGwVM"
$vmSubnet = "VM-Subnet"
$gwnicName = "openvpngw835"
$gwVmName = "openVPNGW"

Switch-AzureMode AzureResourceManager

$route = New-AzureRouteConfig -Name OpenVPNCloudToOnPrem -AddressPrefix $vpnIpPool -NextHopType VirtualAppliance -NextHopIpAddress $openVpnGwIP
$rt = New-AzureRouteTable -ResourceGroupName $vnetResourceGroup  -Name OpenVPNtoOnPrem -Location $location  -Route $route


$vnet = Get-AzureVirtualNetwork -ResourceGroupName $vnetResourceGroup  -Name $vnetName

$subnet = Get-AzureVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $vmSubnet


$gw = get-azurevm -Name $gwVmName -ResourceGroupName $vnetResourceGroup
$if =  Get-AzureNetworkInterface -ResourceGroupName $vnetResourceGroup -Name $gwnicName
$if.EnableIPForwarding = $true

Set-AzureNetworkInterface -NetworkInterface $if

$subnet.RouteTable = $rt

$vnet | Set-AzureVirtualNetwork



About Me