VyOS Networks Blog

Building an open source network OS for the people, together.

Automation for VyOS in Microsoft Azure Cloud

Taras Pudiak
Posted 15 Aug, 2021

Hello, People!

Microsoft Azure is one of the biggest cloud service providers nowadays. VyOS is featured as Microsoft preferred solution and many Azure users are already leveraging VyOS capabilities for connecting to other clouds, private data centers, and on-premises networks. As you may recall, this year VyOS achieved the co-sell ready status with Microsoft:

  • All VyOS on Azure consumption count toward your commitments
  • Microsoft CSPs receiving additional incentives when selling VyOS 

We also support VyOS on Azure Stack Hub. In other words, the adoption and recognition of VyOS among Azure users are growing and we are happy to see that. Since VPN gateway is one of the most popular use cases, we'll show an example of how to connect your on-prem environment to Azure with VyOS.

There's a growing number of people asking us how to set up an IPSec tunnel between Azure and an on-premises network. In this post, we will see how to automate spawning VyOS instances and setting up IPsec tunnels using PowerShell commands.

Of course, you can also deploy the same configuration by hand if you don't need the automation part.

Typical topology looks like this:

vyos_azure_ipsec_tunnel

 

In our example, we deploy VyOS 1.2 from the Azure Marketplace, but you can use an already existing instance.

Note: Unless indicated otherwise, all commands must be executed in PowerShell.

First what you need to be able to work with Microsoft Azure is the Azure PowerShell module. You can install it using the following command:

Install-Module AzureRM

After this, you will be able to use Azure-specific commands in PowerShell. First, you need to log in to your Azure tenant account. Only then you will get access to resources in the cloud. Run the following command to open a pop-up authentication window, and then use your credentials from your Azure account:

Login-AzureRmAccount

In the Azure cloud, every virtual machine involves multiple different logical objects (like virtual networks, virtual network adapters, IP addresses and so on). To make managing all these things easier, you may aggregate all objects into one logical resource group. To create a new resource group you need to execute this command:

New-AzurermResourceGroup -ResourceGroupName "VyOS-RG" -Location "westeurope"

In this example, we used location “westeurope” and resource group name "VyOS-RG". You may use any other location and name, based on your requirements. You can get a list of all available locations using this command:

Get-AzureRmLocation|select Location,DisplayName

After creating a new resource group we can add all objects related to our new virtual machine to this group to easily manage and handle them.

To deploy a new virtual machine with VyOS we need to set few variables first. Specify the local user for your virtual machine. This user will be used later for access to the VyOS CLI:

$VMLocalAdminUser = "LocalAdmin"

Set a password for that user:

$VMLocalAdminSecurePassword = ConvertTo-SecureString "VerySecretPassword" -AsPlainText -Force 

Set the location of your resource group:

$LocationName = "westeurope"

Specify the name of your resource group, where you want to create resources:

$ResourceGroupName = "VyOS-RG"

Specify a hostname for your virtual machine:

$ComputerName = "vyos-router-azure-01"

Also, set the name for your virtual machine in your Microsoft Azure tenant. It can be the same as the hostname, or different:

$VMName = "VyOS_WestEurope_01"

Set the desired instance type for your virtual machine:

$VMSize ="Standard_A0"

You can get a list of available sizes in your location using the following command:

 Get-AzureRmVMSize -Location "westeurope"

Set names for two networks. One of them will be used for external connectivity (to the Internet and your local site) and the other for internal network access (to your Azure VMs, for example):

$NetworkName = "VyOS-net"
$NetworkName2 = "VyOS-net2"

Specify names for two NICs, which will be connected to our VM, one for each network:

$NICName_pub = "VyOS-pub-NIC"
$NICName_int = "VyOS-int-NIC"

Specify names for two subnet objects. It will be used for your public and internal IP networks:

$SubnetName = "VyOS-PubSubnet"
$SubnetName2 = "VyOS-IntSubnet"

Set your virtual network address space and subnet address space:

$SubnetAddressPrefix = "10.0.2.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$SubnetAddressPrefix2 = "10.0.2.0/24"
$VnetAddressPrefix2 = "10.1.0.0/16"

Now you can create a public IP address for the router, to provide later external access:

$publicIP = New-AzureRmPublicIpAddress -ResourceGroupName $ResourceGroupName -AllocationMethod static -Name "Vyos-PublicIP" -Location $LocationName

Also, you need to create two subnets, using previously defined variables:

$SingleSubnet = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$SingleSubnet2 = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName2 -AddressPrefix $SubnetAddressPrefix2

After this, you can create a virtual network and add two recently created subnet address spaces to it:

$Vnet = New-AzureRmVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet,$SingleSubnet2

Create two NICs. We'll assign a previously created IP address to one of them:

$NIC1 = New-AzureRmNetworkInterface -Name $NICName_pub -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[0].Id -PublicIpAddressId ($publicIP).id
$NIC2 = New-AzureRmNetworkInterface -Name $NICName_int -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[1].Id

You need to create an object for storing credentials for the virtual machine:

$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword)

Create an object that will hold the properties of the virtual machine:

$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize

Set the operating system parameters and authentication credentials:

$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -linux -ComputerName $ComputerName -Credential $Credential

Also, add created NICs to a virtual machine:

$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC1.Id -primary
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC2.Id

Now, when you have prepared the configuration and parameters for a virtual machine, you need to specify which image from the Azure Marketplace will be used in this machine. We choose VyOS 1.2:

$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName "sentriumsl" -Offer "vyos-1-2-lts-on-azure" -Skus "vyos-1-2-crux" -Version "1.0.0"

And, specify virtual machine plan:

Set-AzureRmVMPlan -VM $VirtualMachine -Publisher "sentriumsl" -Product "vyos-1-2-lts-on-azure" -Name "vyos-1-2-crux"

Now, if you check the properties of variable $VirtualMachine, you will see the following profile parameters, which we created using previous commands:

$VirtualMachine |fl *


ResourceGroupName        :
Id                       :
VmId :
Name : VyOS
Type :
Location :
LicenseType :
Tags :
AvailabilitySetReference :
DiagnosticsProfile :
Extensions :
HardwareProfile : Microsoft.Azure.Management.Compute.Models.HardwareProfile
InstanceView :
NetworkProfile : Microsoft.Azure.Management.Compute.Models.NetworkProfile
OSProfile : Microsoft.Azure.Management.Compute.Models.OSProfile
Plan : Microsoft.Azure.Management.Compute.Models.Plan
ProvisioningState :
StorageProfile : Microsoft.Azure.Management.Compute.Models.StorageProfile
DisplayHint : Compact
Identity :
Zones :
FullyQualifiedDomainName :
AdditionalCapabilities :
RequestId :
StatusCode : 0

And, if everything is correct, you can start deployment of the virtual machine with the following command:

New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine -Verbose

After successful deployment, you can connect to the virtual machine from the same PowerShell console. To do this, you need to install the SSH client module first:

Install-Module Posh-SSH

And then connect to the virtual machine's public IP address:

ssh LocalAdmin@<public IP>

You can get the public IP address of the newly deployed VM with this command:

(Get-AzureRmPublicIpAddress -Name "Vyos-PublicIP" -ResourceGroupName “VyOS-RG ").IpAddress

If you can connect to the VM via SSH, then the deployment stage was finished successfully.

In case, if you need a virtual machine with only one network interface, you can simplify the process and use only the next changed commands:

$VirtualMachine =$null
$VMLocalAdminUser = "LocalAdmin"
$VMLocalAdminSecurePassword = ConvertTo-SecureString "SuperPassword!" -AsPlainText -Force
$LocationName = "westeurope"
$ResourceGroupName = "VyOS-RG"
$ComputerName = "VyOS"
$VMName = "VyOS"
$VMSize ="Standard_A0"
$NetworkName = "VyOS-net-pub"
$NICName_pub = "VyOS-pub-NIC"
$SubnetName = "VyOS-PubSub"
$SubnetAddressPrefix = "10.0.2.0/24"
$VnetAddressPrefix = "10.0.0.0/16"
$publicIP=New-AzureRmPublicIpAddress -ResourceGroupName $ResourceGroupName -AllocationMethod static -Name "Vyos-PublicIP" -Location $LocationName
$SingleSubnet = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$Vnet = New-AzureRmVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet
$NIC1 = New-AzureRmNetworkInterface -Name $NICName_pub -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[0].Id -PublicIpAddressId ($publicIP).id
$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);
$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -linux -ComputerName $ComputerName -Credential $Credential
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC1.Id -primary
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName "sentriumsl" -Offer "vyos-1-2-lts-on-azure" -Skus "vyos-1-2-crux" -Version "1.0.0"
Set-AzureRmVMPlan -VM $VirtualMachine -Publisher "sentriumsl" -Product "vyos-1-2-lts-on-azure" -Name "vyos-1-2-crux"
New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine -Verbose

 


 

After deployment, you can continue to the configuration procedure. All configuration commands need to be entered into VyOS CLI after connecting through the SSH.

Here are the commands for VyOS on the Azure side:

conf
set interfaces ethernet %AZURE_ETH_LOCAL% address 'dhcp'
set vpn ipsec esp-group ESP_AZURE_01 compression 'disable'
set vpn ipsec esp-group ESP_AZURE_01 lifetime '3600'
set vpn ipsec esp-group ESP_AZURE_01 mode 'tunnel'
set vpn ipsec esp-group ESP_AZURE_01 pfs 'dh-group19'
set vpn ipsec esp-group ESP_AZURE_01 proposal 10 encryption 'aes256gcm128'
set vpn ipsec esp-group ESP_AZURE_01 proposal 10 hash 'sha512'
set vpn ipsec ike-group IKE_AZURE_01 key-exchange 'ikev2'
set vpn ipsec ike-group IKE_AZURE_01 lifetime '28800'
set vpn ipsec ike-group IKE_AZURE_01 proposal 10 dh-group '19'
set vpn ipsec ike-group IKE_AZURE_01 proposal 10 encryption 'aes256gcm128'
set vpn ipsec ike-group IKE_AZURE_01 proposal 10 hash 'sha512'
set vpn ipsec ipsec-interfaces interface '%AZURE_ETH_EXTERNAL%'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% authentication id '%AZURE_IP_PUBLIC%'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% authentication mode 'pre-shared-secret'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% authentication pre-shared-secret '%SECRET%'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% default-esp-group 'ESP_AZURE_01'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% ike-group 'IKE_AZURE_01'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% local-address '%AZURE_IP_EXTERNAL%'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% tunnel 1 local prefix '%AZURE_NET_INTERNAL%'
set vpn ipsec site-to-site peer %SITE_IP_PUBLIC% tunnel 1 remote prefix '%SITE_NET_INTERNAL%'
commit
save


And here are the commands for the on-premises side:

conf
set vpn ipsec esp-group ESP_AZURE_01 compression 'disable'
set vpn ipsec esp-group ESP_AZURE_01 lifetime '3600'
set vpn ipsec esp-group ESP_AZURE_01 mode 'tunnel'
set vpn ipsec esp-group ESP_AZURE_01 pfs 'dh-group19'
set vpn ipsec esp-group ESP_AZURE_01 proposal 10 encryption 'aes256gcm128'
set vpn ipsec esp-group ESP_AZURE_01 proposal 10 hash 'sha512'
set vpn ipsec ike-group IKE_AZURE_01 key-exchange 'ikev2'
set vpn ipsec ike-group IKE_AZURE_01 lifetime '28800'
set vpn ipsec ike-group IKE_AZURE_01 proposal 10 dh-group '19'
set vpn ipsec ike-group IKE_AZURE_01 proposal 10 encryption 'aes256gcm128'
set vpn ipsec ike-group IKE_AZURE_01 proposal 10 hash 'sha512'
set vpn ipsec ipsec-interfaces interface '%ETH_EXTERNAL%'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% authentication mode 'pre-shared-secret'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% authentication pre-shared-secret '$$$SECRET'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% default-esp-group 'ESP_AZURE_01'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% ike-group 'IKE_AZURE_01'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% local-address '%SITE_IP_PUBLIC%'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% tunnel 1 local prefix '%SITE_NET_INTERNAL%'
set vpn ipsec site-to-site peer %AZURE_IP_PUBLIC% tunnel 1 remote prefix '%AZURE_NET_INTERNAL%'
commit
save


Variables, placed between "%" symbols must be changed, according to your requirements. For example:

%ETH_EXTERNAL% ---> eth1

The meanings of those variables are as follows:

AZURE_ETH_LOCAL - internal interface name which is attached to an internal subnet, where exist all your VMs in Microsoft Azure.

AZURE_ETH_EXTERNAL - external interface name, to which was attached a public IP in Microsoft Azure.

SITE_IP_PUBLIC - public IP address of VyOS router at your local site, from which you establish a connection to Microsoft Azure.

AZURE_IP_PUBLIC - public IP address, attached to your VyOS router in Microsoft Azure.

SECRET - secret pre-shared key, which you need to enter at both sides.

AZURE_IP_EXTERNAL - IP address of an external NIC of VyOS machine in Microsoft Azure.

AZURE_NET_INTERNAL - IP subnet of resources located in Microsoft Azure, to which we want to provide access through IPSec tunnel.

SITE_NET_INTERNAL - IP subnet of resources located in your local site, to which we want to provide access through IPSec tunnel.

After entering this configuration, hosts in AZURE_NET_INTERNAL and SITE_NET_INTERNAL networks will be able to exchange traffic between each other.

 

If you want to automatically deploy VyOS in Azure, you can use the following PowerShell script, based on previous commands:

###############Log in to Microsoft Azure###############
# Enter your account with administrative permissions to tenant or resource group
$Username = "Your tenant account"
# Enter your password to account
$Password = ConvertTo-SecureString ‘Your password’ -AsPlainText -Force
# Create secure store object
$Creds = New-Object System.Management.Automation.PSCredential $Username, $Password
# Log in process
Login-AzureRmAccount -Credential $Creds
###############Log in to Microsoft Azure###############

###############Settings###############
# Enter the name for guest local account
$VMLocalAdminUser = "LocalAdmin"
# Enter the password for guest local account
$VMLocalAdminSecurePassword = ConvertTo-SecureString "Hyusong650rs" -AsPlainText -Force
# Location for deployment of all resources
$LocationName = "westeurope"
# Resource group name
$ResourceGroupName = "VyOS_PowerShell"
# Host name for guest OS
$ComputerName = "VyOS"
# Name of the VM in Microsoft Azure
$VMName = "VyOS"
# Specify size of the VM
$VMSize ="Standard_A0"
# Names for two networks
$NetworkName = "VyOS-net-pub"
$NetworkName2 = "VyOS-net-int"
# Names for NICs
$NICName_pub = "VyOS-pub-NIC"
$NICName_int = "VyOS-int-NIC"
# Name for two subnet
$SubnetName = "VyOS-PubSub"
$SubnetName2 = "VyOS-IntSub"
# Prefix for two subnets
$SubnetAddressPrefix = "10.0.2.0/24"
$SubnetAddressPrefix2 = "10.0.1.0/24"
# Prefix for VNET
$VnetAddressPrefix = "10.0.0.0/16"
###############Settings###############

###############Logic###############
# Create Public IP
$publicIP=New-AzureRmPublicIpAddress -ResourceGroupName $ResourceGroupName -AllocationMethod static -Name "Vyos-PublicIP" -Location $LocationName
# Create two subnets
$SingleSubnet = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix
$SingleSubnet2 = New-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName2 -AddressPrefix $SubnetAddressPrefix2
# Create VNET and map to it two subnets
$Vnet = New-AzureRmVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet,$SingleSubnet2
# Create two NICs objects
$NIC1 = New-AzureRmNetworkInterface -Name $NICName_pub -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[0].Id -PublicIpAddressId ($publicIP).id
$NIC2 = New-AzureRmNetworkInterface -Name $NICName_int -ResourceGroupName $ResourceGroupName -Location $LocationName -SubnetId $Vnet.Subnets[1].Id
# Create secure store
$Credential = New-Object System.Management.Automation.PSCredential ($VMLocalAdminUser, $VMLocalAdminSecurePassword);
# Create config for VM
$VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize
# Create linux config for guest OS
$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -linux -ComputerName $ComputerName -Credential $Credential
# Assign two NICs to VM
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC1.Id -primary
$VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC2.Id
# Chose VyOS image from Azure Market
$VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName "sentriumsl" -Offer "vyos-1-2-lts-on-azure" -Skus "vyos-1-2-crux" -Version "1.0.0"
# Create a plan for VM
Set-AzureRmVMPlan -VM $VirtualMachine -Publisher "sentriumsl" -Product "vyos-1-2-lts-on-azure" -Name "vyos-1-2-crux"
# Start deployment of VM
New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine -Verbose
###############Logic###############

Let us know what you think!

Thanks!

 

The post categories:

Comments