I do a lot with my hybrid lab where some of my infrastructure resides on-premises and some resides in Azure. In today’s post, I’m going to describe how you can setup a site-to-site VPN between Azure and your local site using VyOS.
Azure Configuration
For the sake of demonstration, I’m going to set this all up from scratch using Azure PowerShell. You may need to make some adjustments, but I’ll try to call out any gotchas as we make our way through the configuration.
The first thing we’ll need to do is connect to Azure. When you run the following command, you’ll be asked to authenticate. Use an account that has the appropriate permissions.
Connect-AzAccount
Next, we’ll need a Resource Group. I’m going to call mine ContosoInfrastructure.
New-AzResourceGroup -Name ContosoInfrastructure -Location "South Central US"
Now, we need a Virtual Network and a couple of subnets. For our purposes here today, my on-premises network will live entirely within 172.16.0.0/16 and my Azure virtual network will be 172.17.0.0/16.
I’m going to create two subnets — a gateway subnet for the Virtual Network Gateway, and a corporate subnet for my Virtual Machines. You may need to make some adjustments if some forethought wasn’t put into your network design. Refer to Planning and design for VPN Gateway for more information.
$GatewaySubnet = New-AzVirtualNetworkSubnetConfig -Name GatewaySubnet -AddressPrefix "172.17.254.0/29"
$CorporateSubnet = New-AzVirtualNetworkSubnetConfig -Name CorporateSubnet -AddressPrefix "172.17.0.0/24"
$ContosoNetwork = New-AzVirtualNetwork -Name ContosoNetwork -ResourceGroupName ContosoInfrastructure -Location "South Central US" -AddressPrefix "172.17.0.0/16" -Subnet $GatewaySubnet,$CorporateSubnet
Now that the Virtual Network has been created, we need to grab the subnet details so we’ll have their identifiers.
$GatewaySubnet = Get-AzVirtualNetworkSubnetConfig -Name GatewaySubnet -VirtualNetwork $ContosoNetwork
$CorporateSubnet = Get-AzVirtualNetworkSubnetConfig -Name CorporateSubnet -VirtualNetwork $ContosoNetwork
The next part can take quite some time. It’s possible it could take 30 minutes or more, so be patient. We’re going to setup a public IP address and define the IP configuration for the Virtual Network Gateway. Then, we’re going to create the gateway itself.
Note: We’ll be using the Policy-based Virtual Network Gateway configuration.
$GatewayAddress = New-AzPublicIpAddress -Name GatewayAddress -ResourceGroupName ContosoInfrastructure -Location "South Central US" -AllocationMethod Dynamic
$GatewayIpConfiguration = New-AzVirtualNetworkGatewayIpConfig -Name GatewayIpConfiguration -SubnetId $GatewaySubnet.Id -PublicIpAddressId $GatewayAddress.Id
$VirtualGateway = New-AzVirtualNetworkGateway -Name VirtualGateway -ResourceGroupName ContosoInfrastructure -Location "South Central US" -IpConfiguration $GatewayIpConfiguration -GatewayType Vpn -VpnType PolicyBased -GatewaySku Basic
Next, we’ll setup a Local Network Gateway, which describes the on-premises part of the WAN, and create the gateway Virtual Network Gateway Connection that links the two networks together.
Note: Use your own public IP address and shared key.
$LocalGateway = New-AzLocalNetworkGateway -Name LocalGateway -ResourceGroupName ContosoInfrastructure -Location "South Central US" -GatewayIpAddress 64.xxx.xxx.19 -AddressPrefix "172.16.0.0/16"
$GatewayConnection = New-AzVirtualNetworkGatewayConnection -Name AzureToContoso -ResourceGroupName ContosoInfrastructure -Location "South Central US" -VirtualNetworkGateway1 $VirtualGateway -LocalNetworkGateway2 $LocalGateway -ConnectionType IPsec -SharedKey "acE1Bl7pxSUc6IvQ"
Now, let’s grab the public IP address that we’ll need in the next part.
Get-AzPublicIpAddress -Name GatewayAddress -ResourceGroupName ContosoInfrastructure | Select-Object -Property IpAddress
That should give you something like this:
IpAddress
---------
40.84.136.186
VyOS Configuration
I’m using version 1.1.8 and have gone through a straightforward basic configuration that sets the following:
- Interface addresses
- Default gateway
- Blackhole routes
- Basic source NAT
- Basic firewall
configure
set interfaces ethernet eth0 address 64.xxx.xxx.19/29
set interfaces ethernet eth1 address 172.16.0.1/24
set protocols static route 0.0.0.0/0 next-hop 64.xxx.xxx.17
set protocols static route 10.0.0.0/8 blackhole distance 254
set protocols static route 172.16.0.0/12 blackhole distance 254
set protocols static route 192.168.0.0/16 blackhole distance 254
set nat source rule 100 outbound-interface eth0
set nat source rule 100 source address 172.16.0.0/16
set nat source rule 100 translation address masquerade
set firewall name WAN-to-LAN-v4 default-action drop
set firewall name WAN-to-LAN-v4 rule 10 action accept
set firewall name WAN-to-LAN-v4 rule 10 state established enable
set firewall name WAN-to-LAN-v4 rule 10 state related enable
set firewall name WAN-to-LAN-v4 rule 20 action accept
set firewall name WAN-to-LAN-v4 rule 20 icmp type-name echo-request
set firewall name WAN-to-LAN-v4 rule 20 protocol icmp
set firewall name WAN-to-LAN-v4 rule 20 state new enable
set firewall name WAN-to-LOCAL-v4 default-action drop
set firewall name WAN-to-LOCAL-v4 rule 10 action accept
set firewall name WAN-to-LOCAL-v4 rule 10 state established enable
set firewall name WAN-to-LOCAL-v4 rule 10 state related enable
set firewall name WAN-to-LOCAL-v4 rule 20 action accept
set firewall name WAN-to-LOCAL-v4 rule 20 icmp type-name echo-request
set firewall name WAN-to-LOCAL-v4 rule 20 protocol icmp
set firewall name WAN-to-LOCAL-v4 rule 20 state new enable
set interfaces ethernet eth0 firewall in name WAN-to-LAN-v4
set interfaces ethernet eth0 firewall local name WAN-to-LOCAL-v4
commit
save
Now, let’s setup the IKE and ESP groups.
set vpn ipsec ike-group ike-azure lifetime 28800
set vpn ipsec ike-group ike-azure proposal 1 dh-group 2
set vpn ipsec ike-group ike-azure proposal 1 encryption aes256
set vpn ipsec ike-group ike-azure proposal 1 hash sha1
set vpn ipsec esp-group esp-azure lifetime 3600
set vpn ipsec esp-group esp-azure pfs disable
set vpn ipsec esp-group esp-azure proposal 1 encryption aes256
set vpn ipsec esp-group esp-azure proposal 1 hash sha1
Next, we’ll setup the peer configuration using the pre-shared-secret we used when we setup the Virtual Network Gateway Connection earlier.
Note: Use your own public IP address and the peer address we captured earlier after setting up the Virtual Network Gateway in Azure.
set vpn ipsec ipsec-interfaces interface eth0
set vpn ipsec site-to-site peer 40.84.136.186 authentication mode pre-shared-secret
set vpn ipsec site-to-site peer 40.84.136.186 authentication pre-shared-secret acE1Bl7pxSUc6IvQ
set vpn ipsec site-to-site peer 40.84.136.186 connection-type respond
set vpn ipsec site-to-site peer 40.84.136.186 local-address 64.xxx.xxx.19
set vpn ipsec site-to-site peer 40.84.136.186 ike-group ike-azure
Here’s where we setup the tunnel itself and specify the networks on each side of the connection.
set vpn ipsec site-to-site peer 40.84.136.186 tunnel 0 esp-group esp-azure
set vpn ipsec site-to-site peer 40.84.136.186 tunnel 0 local prefix 172.16.0.0/16
set vpn ipsec site-to-site peer 40.84.136.186 tunnel 0 remote prefix 172.17.0.0/16
Before the tunnel will come up, we need to allow some traffic through the firewall. I’m only configuring UDP port 500; the rest of the traffic should be covered by the existing rules that allow established and related traffic.
You can be more verbose if you’d like. You’ll need UDP port 4500 if you’re doing NAT traversal, which isn’t covered in this post. You’ll also need ESP (Protocol 50).
Note: ESP is Protocol 50, not TCP or UDP port 50.
Lastly, I’m adding a rule to allow traffic from the remote networks.
set firewall name WAN-to-LOCAL-v4 rule 30 action accept
set firewall name WAN-to-LOCAL-v4 rule 30 protocol udp
set firewall name WAN-to-LOCAL-v4 rule 30 destination port 500
set firewall name WAN-to-LOCAL-v4 rule 30 state new enable
set firewall name WAN-to-LOCAL-v4 rule 40 action accept
set firewall name WAN-to-LOCAL-v4 rule 40 source address 172.17.0.0/16
Now, the last thing we need to do is exclude the VPN traffic from NAT.
set nat source rule 10 outbound-interface eth0
set nat source rule 10 source address 172.16.0.0/16
set nat source rule 10 destination address 172.17.0.0/16
set nat source rule 10 exclude
Don’t forget to commit and save!
commit
save
Testing
By now, your tunnel should be up. Let’s check from VyOS.
vyos@vyos:~$ show vpn ike sa
Peer ID / IP Local ID / IP
------------ -------------
40.84.136.186 64.xxx.xxx.19
State Encrypt Hash D-H Grp NAT-T A-Time L-Time
----- ------- ---- ------- ----- ------ ------
up aes256 sha1 2 no 1247 28800
vyos@vyos:~$ show vpn ipsec sa
Peer ID / IP Local ID / IP
------------ -------------
40.84.136.186 64.xxx.xxx.19
Tunnel State Bytes Out/In Encrypt Hash NAT-T A-Time L-Time Proto
------ ----- ------------- ------- ---- ----- ------ ------ -----
0 up 0.0/32.0 aes256 sha1 no 295 3600 all
Looks good! Let’s check Azure now.
PS C:\> Get-AzVirtualNetworkGatewayConnection -Name AzureToContoso -ResourceGroupName ContosoInfrastructure | Select-Object -Property ConnectionStatus
ConnectionStatus
----------------
Connected
Fantastic! Can we ping from on-premises to Azure?
C:\>ping 172.17.0.4
Pinging 172.17.0.4 with 32 bytes of data:
Reply from 172.17.0.4: bytes=32 time=45ms TTL=126
Reply from 172.17.0.4: bytes=32 time=46ms TTL=126
Reply from 172.17.0.4: bytes=32 time=46ms TTL=126
Reply from 172.17.0.4: bytes=32 time=45ms TTL=126
Ping statistics for 172.17.0.4:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 45ms, Maximum = 46ms, Average = 45ms
And from Azure to on-premises?
C:\>ping 172.16.0.4
Pinging 172.16.0.4 with 32 bytes of data:
Reply from 172.16.0.4: bytes=32 time=44ms TTL=126
Reply from 172.16.0.4: bytes=32 time=46ms TTL=126
Reply from 172.16.0.4: bytes=32 time=43ms TTL=126
Reply from 172.16.0.4: bytes=32 time=44ms TTL=126
Ping statistics for 172.16.0.4:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 43ms, Maximum = 46ms, Average = 44ms
Looks like we’re all set!
Conclusion
I hope this was helpful. There are a fair number of parts to consider here and firewall and NAT rules can definitely trip you up. But overall, once you get the hang of it, it’s really straightforward and you can get this up and running in less than an hour. And truth be told, most of that time is waiting for the Virtual Network Gateway to become available!
I love Azure. I love VyOS. And I love networking. If you have a cool idea for a post, let me know. I’m always looking for cool stuff to play with and share!