KB ID 000116
Problem
The one reason I prefer Cisco over Microsoft is they rarely change things, you learn how to do something and it’s learned. This is the second time have had to write this article purely because the Azure UI has changed!
Virtual Network Gateway Options
With VPN’s into Azure you connect to a Virtual Network Gateway, of which there are TWO types Policy Based, and Route Based. This article will deal with Policy Based, for the more modern Route based option, see the following link;
Microsoft Azure ‘Route Based’ VPN to Cisco ASA
Policy Based
These came first, essentially they work like this, “If traffic is destined for remote network (x) then send the traffic ‘encrypted’ to local security gateway (y).” Note: Where Local Security Gateway is a firewall at YOUR site, NOT in Azure! This is the way traditionally VPNs have been done in Cisco ASA, In Cisco Firewall speak it’s the same as “If traffic matches the interesting traffic ACL, then send the traffic ‘encrypted’ to the IP address specified in the crypto map”.
Advantages:
- Can be used on older Cisco Firewalls (ASA 5505, 5510, 5520, 5550, 5585).
- Can be used on newer Cisco Firewalls (ASA 5506-x, 5508-X, 5512-x, 5515-x, 5516-x, 5525-X, 5545-X, 5555-x, 5585-X)
- Can be used with Cisco ASA OS (pre 8.4) IKEv1 only,
Disadvantages
- Can only be used for ONE connection from your Azure Subnet to your local subnet. Note: You could ‘hairpin’ multiple sites over this one tunnel, but that’s not ideal.
Route Based
These were typically used with routers, because routers use Virtual Tunnel Interfaces to terminate VPN tunnels, that way traffic can be routed down various different tunnels based on a destination, (which can be looked up in a routing table). But Cisco ASA now supports Virtual Tunnels Interfaces (After version 9.7(1))
Advantages
- Can be used for VPNs to multiple sites.
Disadvantages
- Requires Cisco ASA OS 9.7(1) So no ASA 5505, 5510, 5520, 5550, 5585 firewalls can use this.
Configure Azure for ‘Policy Based’ IPSec Site to Site VPN
You may already have Resource Groups and Virtual Networks setup, if so you can skip the first few steps.
Sign int0 Azure > All Services > Resource Groups > Create Resource Group > Give your Resource Group a name, and select a location > Create.
OK, if you’re used to networking this can be a little confusing, we are going to create a virtual network, and in it we are going to put a virtual subnet, (yes I know this is odd, bear with me!) It’s the ‘Subnet Name ‘and ‘address range‘ that things will actually connect to, (10.0.0.0/24).
All Services > Virtual Networks > Create Virtual Network > Give the Virtual Network a name, a subnet, select your resource group > Then create a Subnet, give it a name and a subnet > Create.
To further confuse all the network engineers, we now need to add another subnet, this one will be used by the ‘gateway’. If you are a ‘networking type’ it’s part of the virtual network, but is more specific than the subnet you already created.
With your virtual network selected >Subnets > +Gateway Subnet.
You can’t change the name, (you could before, then it wouldn’t work, which was strange, but I suppose it’s fixed now) > put in another network that’s part of the Virtual-Network, but does not overlap with the subnet you created in the previous step > OK.
All Services > Virtual Network Gateways > Create Virtual Network Gateway > Name it > Policy Based (Note: This will change the SKU to Basic) > Create New Public IP > Give it a Name > Create.
Note: This will take a while, go and put the kettle on! Make sure all running tasks and deployments are complete before continuing.
You can do the next two steps together, but I prefer to do then separately, or it will error if the first one does not complete!
Now you need to create a Local Security Gateway. (To represent your Cisco ASA). All Services > Local Security Gateway > Create Local Security Gateway > Name it > Supply the public IP > Supply the Subnet(s) ‘behind’ the ASA > Select your Resource Group > Create.
Finally create the VPN > Select your Virtual Network Gateway > Connections > Add.
Give the tunnel a name > Site-to-Site IPSec > Select your Local Network Gateway (ASA) > Create a pre-shared-key (you will need this for the ASA config!) > Select your Resource Group > OK.
Configure the Cisco ASA for ‘Policy Based’ Azure VPN
I read somewhere that the ASA had to be at 9.1? That’s not true, I’ve done it with a firewall running 8.3, and I’ve read blog posts from people who have done this with a Cisco PIX (running version 6). But the firewall does have to support AES encryption (‘show version’ will tell you). There are some subtle differences in the code which I will point out below, but essentially you should be running an OS newer than 8.4 for this config to work. (As I’ve said I’ll address 8.4, and 8.3 (or earlier) below).
Connect to the ASA and create an object group for your local subnet, and the subnet that you are using in Azure, (Called Azure-SN above).
[box]
Type help or '?' for a list of available commands. Petes-ASA> enable Password: ******** Petes-ASA# configure terminal Petes-ASA(config)# object-group network OBJ-AZURE-SN Petes-ASA(config-network-object-group)# description Azure Subnet Petes-ASA(config-network-object-group)# network-object 10.0.0.0 255.255.255.0 Petes-ASA(config-network-object-group)# exit Petes-ASA(config)# object-group network OBJ-LOCAL-SN Petes-ASA(config-network-object-group)# description Local Subnet Petes-ASA(config-network-object-group)# network-object 192.168.100.0 255.255.255.0 Petes-ASA(config-network-object-group)# exit
[/box]
Then create an access-list, this will alert the firewall that there is some ‘interesting traffic’ that needs to be encrypted (we will call this ACL later on, from the crypto-map). Then create a NAT rule that stops traffic that’s going over the VPN tunnel from being NATTED.
[box]
Petes-ASA(config)# access-list ACL-AZURE-VPN extended permit ip object-group OBJ-LOCAL-SN object-group OBJ-AZURE-SN Petes-ASA(config)# nat (inside,outside) 1 source static OBJ-LOCAL-SN OBJ-LOCAL-SN destination static OBJ-AZURE-SN OBJ-AZURE-SN no-proxy-arp route-lookup
[/box]
Our VPN is going to use a pre-shared-key, (you created in Azure above). It will use AES-256 for encryption, SHA for hashing, and Diffie Hellman version 2 for key exchange. So we need to have a matching ‘phase 1’ (that’s ISAKMP) policy.
[box]
Petes-ASA(config)# crypto ikev1 policy 5 Petes-ASA(config-ikev1-policy)# authentication pre-share Petes-ASA(config-ikev1-policy)# encryption aes-256 Petes-ASA(config-ikev1-policy)# hash sha Petes-ASA(config-ikev1-policy)# group 2 Petes-ASA(config-ikev1-policy)# lifetime 28800 Petes-ASA(config-ikev1-policy)# exit
[/box]
Enable ISAKMP (version 1) on the outside interface, then configure the parameters that will be used in ‘phase 2’ (that’s IPSEC). Note: If your outside interface is called something else like Outside or WAN substitute that!
[box]
Petes-ASA(config)# crypto ikev1 enable outside Petes-ASA(config)# crypto ipsec ikev1 transform-set AZURE-TRANSFORM esp-aes-256 esp-sha-hmac Petes-ASA(config)# crypto ipsec security-association lifetime seconds 3600 Petes-ASA(config)# crypto ipsec security-association lifetime kilobytes 102400000
[/box]
Next, you need a tunnel-group, in this case the only job of the tunnel group has is to keep the pre-shared-key (PSK) to the peer you specify. Which in this case is the Azure Gateway.
[box]
Petes-ASA(config)# tunnel-group 40.113.16.195 type ipsec-l2l Petes-ASA(config)# tunnel-group 40.113.16.195 ipsec-attribute Petes-ASA(config-tunnel-ipsec)# ikev1 pre-shared-key supersecretpassword Petes-ASA(config-tunnel-ipsec)# exit
[/box]
The thing that ties it all together is the crypto map. Here I’ve called it “AZURE-CRYPTO-MAP”, WARNING if you already have a crypto map, use the name of that one, or all your existing VPNS will stop working, (show run crypto will tell you). This is because, you can only have one crypto map applied to an interface, but you can have many crypto map numbers, i.e crypto map {NAME} {NUMBER} {COMMAND}. And each VPN tunnel has its own number.
[box]
Petes-ASA(config)# crypto map AZURE-CRYPTO-MAP 1 match address ACL-AZURE-VPN Petes-ASA(config)# crypto map AZURE-CRYPTO-MAP 1 set peer 40.113.16.195 Petes-ASA(config)# crypto map AZURE-CRYPTO-MAP 1 set ikev1 transform-set AZURE-TRANSFORM Petes-ASA(config)# crypto map AZURE-CRYPTO-MAP interface outside
[/box]
There are a couple of extra commands you will need, these are sysops commands. Their purpose set things globally, and are generally hidden from the config, (i.e ‘show run’ wont show them). These are recommendations from Azure. The first one drops the maximum segment size to 1350.The second command keeps the TCP session information even if the VPN tunnel drops.
[box]
Petes-ASA(config)# sysopt connection tcpmss 1350 Petes-ASA(config)# sysopt connection preserve-vpn-flows Petes-ASA(config)# exit
[/box]
Testing Azure to Cisco ASA VPN
To test we usually use ‘ping’, the problem with that is, if you are using Windows Servers they will have their Windows firewall on by default, which blocks pings, (bear this in mind when testing). Also your ASA needs to be setup to allow pings, (try pinging 8.8.8.8 that usually responds), if yours doesn’t then configure your ASA to allow ping traffic.
As mentioned above, you might want to turn the firewalls off to test.
On the Cisco ASA you can see the tunnel is established at Phase 1 (ISAKMP)
[box]
Petes-ASA# show cry isa IKEv1 SAs: Active SA: 1 Rekey SA: 0 (A tunnel will report 1 Active and 1 Rekey SA during rekey) Total IKE SA: 1 1 IKE Peer: 40.113.16.195 Type : L2L Role : initiator Rekey : no State : MM_ACTIVE
[/box]
If yours says something else, (or nothing at all) then phase 1 has not established. You need to Troubleshoot phase 1 of the VPN tunnel. (Probably: Public IP is wrong, or pre-shared-key (shared secret) has been mistyped, check these first).
Assuming that’s working, your next test is to make sure that Phase 2 has established. You should see packets encrypting and decrypting.
[box]
Petes-ASA(config)# show cry ipsec sa
interface: outside
Crypto map tag: AZURE-CRYPTO-MAP, seq num: 1, local addr: 128.65.98.43
access-list ACL-AZURE-VPN extended permit ip 192.168.100.0 255.255.255.0 10.0.0.0 255.255.255.0
local ident (addr/mask/prot/port): (192.168.100.0/255.255.255.0/0/0)
remote ident (addr/mask/prot/port): (10.0.0.0/255.255.255.0/0/0)
current_peer: 40.113.16.195
#pkts encaps: 2, #pkts encrypt: 2, #pkts digest: 2
#pkts decaps: 3, #pkts decrypt: 3, #pkts verify: 3
#pkts compressed: 0, #pkts decompressed: 0
#pkts not compressed: 2, #pkts comp failed: 0, #pkts decomp failed: 0
#pre-frag successes: 0, #pre-frag failures: 0, #fragments created: 0
#PMTUs sent: 0, #PMTUs rcvd: 0, #decapsulated frgs needing reassembly: 0
#TFC rcvd: 0, #TFC sent: 0
#Valid ICMP Errors rcvd: 0, #Invalid ICMP Errors rcvd: 0
#send errors: 0, #recv errors: 0
local crypto endpt.: 128.65.98.43/0, remote crypto endpt.: 40.113.16.195/0
path mtu 1500, ipsec overhead 74(44), media mtu 1500
PMTU time remaining (sec): 0, DF policy: copy-df
ICMP error validation: disabled, TFC packets: disabled
current outbound spi: 97624DA8
current inbound spi : D7705547
inbound esp sas:
spi: 0xD7705547 (3614463303)
transform: esp-aes-256 esp-sha-hmac no compression
in use settings ={L2L, Tunnel, IKEv1, }
slot: 0, conn_id: 335872, crypto-map: AZURE-CRYPTO-MAP
sa timing: remaining key lifetime (kB/sec): (97199999/3556)
IV size: 16 bytes
replay detection support: Y
Anti replay bitmap:
0x00000000 0x0000000F
outbound esp sas:
spi: 0x97624DA8 (2539802024)
transform: esp-aes-256 esp-sha-hmac no compression
in use settings ={L2L, Tunnel, IKEv1, }
slot: 0, conn_id: 335872, crypto-map: AZURE-CRYPTO-MAP
sa timing: remaining key lifetime (kB/sec): (97199999/3556)
IV size: 16 bytes
replay detection support: Y
Anti replay bitmap:
0x00000000 0x00000001
Petes-ASA(config)#
[/box] If phase 2 did not connect, then you need to troubleshoot phase 2 of the VPN tunnel. (Probably: Transform set is wrong, or routing being the ASA is not working).
Azure to Cisco VPN ‘Policy Based’ IKEv1 Complete Code Snippets to Copy and Paste
(Change the values highlighted in red) WARNING: re-read the warning about crypto map names above! [box]
VERSION 8.4 AND NEWER ! object-group network OBJ-AZURE-SN description Azure Subnet network-object 10.0.0.0 255.255.255.0 exit object-group network OBJ-LOCAL-SN description Local Subnet network-object 192.168.100.0 255.255.255.0 exit ! access-list ACL-AZURE-VPN extended permit ip object-group OBJ-LOCAL-SN object-group OBJ-AZURE-SN ! nat (inside,outside) 1 source static OBJ-LOCAL-SN OBJ-LOCAL-SN destination static OBJ-AZURE-SN OBJ-AZURE-SN ! crypto ikev1 policy 5 authentication pre-share encryption aes-256 hash sha group 2 lifetime 28800 ! crypto ikev1 enable outside ! crypto ipsec ikev1 transform-set AZURE-TRANSFORM esp-aes-256 esp-sha-hmac crypto ipsec security-association lifetime seconds 3600 crypto ipsec security-association lifetime kilobytes 102400000 ! tunnel-group 40.113.16.195 type ipsec-l2l tunnel-group 40.113.16.195 ipsec-attribute ikev1 pre-shared-key 1234567890asdfg ! crypto map AZURE-CRYPTO-MAP 1 match address ACL-AZURE-VPN crypto map AZURE-CRYPTO-MAP 1 set peer 40.113.16.195 crypto map AZURE-CRYPTO-MAP 1 set ikev1 transform-set AZURE-TRANSFORM ! crypto map AZURE-CRYPTO-MAP interface outside ! sysopt connection tcpmss 1350 ! sysopt connection preserve-vpn-flows VERSION 8.4 (BEFORE IKEv2 WAS INTRODUCED) ! object-group network OBJ-AZURE-SN description Azure Subnet network-object 10.0.0.0 255.255.255.0 exit object-group network OBJ-LOCAL-SN description Local Subnet network-object 192.168.100.0 255.255.255.0 exit ! access-list ACL-AZURE-VPN extended permit ip object-group OBJ-LOCAL-SN object-group OBJ-AZURE-SN ! nat (inside,outside) 1 source static OBJ-LOCAL-SN OBJ-LOCAL-SN destination static OBJ-AZURE-SN OBJ-AZURE-SN ! crypto isakmp policy 5 authentication pre-share encryption aes-256 hash sha group 2 lifetime 28800 ! crypto isakmp enable outside ! crypto ipsec transform-set AZURE-TRANSFORM esp-aes-256 esp-sha-hmac crypto ipsec security-association lifetime seconds 3600 crypto ipsec security-association lifetime kilobytes 102400000 ! tunnel-group 40.113.16.195 type ipsec-l2l tunnel-group 40.113.16.195 ipsec-attribute pre-shared-key 1234567890asdfg ! crypto map AZURE-CRYPTO-MAP 1 match address ACL-AZURE-VPN crypto map AZURE-CRYPTO-MAP 1 set peer 40.113.16.195 crypto map AZURE-CRYPTO-MAP 1 set ikev1 transform-set AZURE-TRANSFORM ! crypto map AZURE-CRYPTO-MAP interface outside ! sysopt connection tcpmss 1350 ! sysopt connection preserve-vpn-flows OLDER THAN VERSION 8.3 (BEFORE NAT SYNTAX CHANGED) ! name 10.0.0.0 OBJ-AZURE-SN name 192.168.100.0 OBJ-LOCAL-SN ! access-list ACL-AZURE-VPN extended permit ip OBJ-LOCAL-SN 255.255.255.0 OBJ-AZURE-SN 255.255.0.0 ! access-list NO-NAT-TRAFFIC extended permit ip OBJ-LOCAL-SN 255.255.255.0 OBJ-AZURE-SN 255.255.0.0 nat (inside) 0 access-list NO-NAT-TRAFFIC ! crypto isakmp policy 5 authentication pre-share encryption aes-256 hash sha group 2 lifetime 28800 ! crypto isakmp enable outside ! crypto ipsec transform-set AZURE-TRANSFORM esp-aes-256 esp-sha-hmac crypto ipsec security-association lifetime seconds 3600 crypto ipsec security-association lifetime kilobytes 102400000 ! tunnel-group 40.113.16.195 type ipsec-l2l tunnel-group 40.113.16.195 ipsec-attribute pre-shared-key 1234567890asdfg ! crypto map AZURE-CRYPTO-MAP 1 match address ACL-AZURE-VPN crypto map AZURE-CRYPTO-MAP 1 set peer 40.113.16.195 crypto map AZURE-CRYPTO-MAP 1 set transform-set AZURE-TRANSFORM ! crypto map AZURE-CRYPTO-MAP interface outside ! sysopt connection tcpmss 1350 ! sysopt connection preserve-vpn-flows
[/box]