Rather than reinvent the wheel with basic VPN theory or deep dive the intricacies of VPN; this falls somewhere in the middle. These steps are by no means a complete guide to creating a tunnel. Instead I hope to demonstrate how each configuration piece relates to the next and detail all the steps as succinctly as possible. We’re assuming previous knowledge with Cisco ASA configuration and that all the basic configuration has been completed (interface setup, ip addressing, user accounts). These steps were designed to be used on IOS 8.4. For easy reference, I’ve included the complete configurations for both peers at the bottom of the post.
Here are the building blocks for a basic L2L IPsec VPN and how they stack.
Blocks
Here are the basic configuration blocks we’ll need for a working tunnel:
- crypto policy – The encryption used to connect to a remote firewall
- tunnel-group – Defines the attributes of the tunnel
- crypto ipsec transform-set – Encryption for the tunnel data
- network-object – Devices and networks to go through the tunnel
- object-group – A group of
network-object
s - access-list – Permissions associated with the
object-group
s - nat – Create NAT exemption for local
network-object
s to reach remotenetwork object
s - crypto map – Binds the *access-list* with the peer and the
crypto ipsec transform-set
crypto policy
The first three steps of our configuration maybe confusing to the uninitiated, but it’ll make sense shortly! Firstly, we’ll create a policy that defines characteristics of our tunnel, specifically Phase 1 – Internet Key Exchange (IKE). At the most simplistic this allows our ASA to make a connection with a remote firewall. This policy can be reused later when building additional tunnels.
crypto ikev1 policy 10 authentication pre-share encryption aes-256 hash sha group 2 lifetime 864000
Now that we have a policy, we’ll enable IKE on the outside interface:
crypto ikev1 enable outside
tunnel-group
To complete the connection we’ll need to specify the pre-shared key referenced in the crypto policy above. This is matched to the tunnel via the peer (or remote firewall).
tunnel-group FW2 type ipsec-l2l tunnel-group FW2 ipsec-attributes ikev1 pre-shared-key ********
crypto ipsec transform-set
With the Phase 1 information in place we move onto Phase 2. Rounding out the steps dealing with encryption, let’s set the encryption for data traversing the tunnel. As with the crypto policy, the transform-set is not tied to a specific tunnel and can be reused for additional tunnels.
crypto ipsec ikev1 transform-set DftTransSet esp-aes-256 esp-sha-hmac
network-object
Now we move onto the slightly more tangible part of the configuration. Let’s specify what will be able to communicate across the tunnel. Here we’ll create two network objects that define the subnets on each side of the tunnel. You can use a host instead of a subnet, or lots of hosts, or lots of subnets and lots of host, whatever needs to get across the tunnel.
object network NetObj_Local subnet 172.16.2.0 255.255.254.0 object network NetObj_Remote subnet 172.17.2.0 255.255.254.0
object-group
To allow multiple subnets or devices we can create an object group. Strictly speaking both network objects and object groups are not mandatory, but they allow for easier expansion later as well as making for a cleaner layout. There are many ways to build network objects and group them, so take the time to decide what convention works for you.
object-group network ObjGrp_Local network-object object NetObj_Local object-group network ObjGrp_Remote network-object object NetObj_Remote
access-list
Create the permissions allowing the traffic from our local object group to the remote object group. We’ll keep it easy by permitting all traffic.
access-list RemoteNetACL extended permit ip object-group ObjGrp_Local object-group ObjGrp_Remote access-list RemoteNetACL extended permit ip object-group ObjGrp_Remote object-group ObjGrp_Local
If we were to create more access lists for the same tunnel (if we have many different network objects, or network groups) we’d simply use the same ACL name: access-list RemoteNetACL extended ...
. ACL is one of subjects here that is hard to summarize in a few lines as there’s lots of options.
nat
To prevent our traffic from being NAT’d out the outside interface, we need to NAT our object groups to themselves.
nat (inside,outside) source static Local ObjGrp_Local ObjGrp_Local destination static ObjGrp_Remote ObjGrp_Remote
With the NAT changes in 8.3, this exemption syntax changed in 8.3 from the old nat (inside) 0
format.
crypto map
Lastly we tie it all together by binding the access-list with the peer and select the encryption.
crypto map RemoteNetMap 1 match address RemoteNetACL crypto map RemoteNetMap 1 set peer FW2 crypto map RemoteNetMap 1 set ikev1 transform-set DftTransSet crypto map RemoteNetMap 1 set security-association lifetime seconds 3600
Now we assign the new crypto map to our outside interface.
crypto map RemoteNetMap interface outside
And that’s it! You’re done one side of the tunnel. Luckily the other is mostly a mirror of configuration above. Its worth reiterating that this a basic design of a L2L IPsec VPN and there are many different options available to configure the tunnel to your needs.
Configurations
Below you’ll find the full configuration for both peers in our tunnel.
FW1
! ! FW1 Configuration ! hostname FW1 ! name 10.1.2.10 FW2 ! interface GigabitEthernet0 nameif outside security-level 0 ip address 10.1.1.10 255.255.255.0 no shut ! interface GigabitEthernet1 nameif inside security-level 100 ip address 172.16.2.1 255.255.254.0 no shut ! route outside 0.0.0.0 0.0.0.0 10.1.1.1 1 ! ! L2L IPsec VPN Configuration ! crypto ikev1 policy 10 authentication pre-share encryption aes-256 hash sha group 2 lifetime 864000 ! crypto ikev1 enable outside ! tunnel-group FW2 type ipsec-l2l tunnel-group FW2 ipsec-attributes ikev1 pre-shared-key ciscoasa ! crypto ipsec ikev1 transform-set DftTransSet esp-aes-256 esp-sha-hmac ! object network NetObj_Local subnet 172.16.2.0 255.255.254.0 ! object network NetObj_Remote subnet 172.17.2.0 255.255.254.0 ! object-group network ObjGrp_Local network-object object NetObj_Local ! object-group network ObjGrp_Remote network-object object NetObj_Remote ! access-list RemoteNetACL extended permit ip object-group ObjGrp_Local object-group ObjGrp_Remote access-list RemoteNetACL extended permit ip object-group ObjGrp_Remote object-group ObjGrp_Local ! nat (inside,outside) source static ObjGrp_Local ObjGrp_Local destination static ObjGrp_Remote ObjGrp_Remote ! crypto map RemoteNetMap 1 match address RemoteNetACL crypto map RemoteNetMap 1 set peer FW2 crypto map RemoteNetMap 1 set ikev1 transform-set DftTransSet crypto map RemoteNetMap 1 set security-association lifetime seconds 3600 ! crypto map RemoteNetMap interface outside
FW2
! ! FW2 Configuration ! hostname FW2 ! name 10.1.1.10 FW1 ! interface GigabitEthernet0 nameif outside security-level 0 ip address 10.1.2.10 255.255.255.0 no shut ! interface GigabitEthernet1 nameif inside security-level 100 ip address 172.17.2.1 255.255.254.0 no shut ! route outside 0.0.0.0 0.0.0.0 10.1.2.1 1 ! ! L2L IPsec VPN Configuration ! crypto ikev1 policy 10 authentication pre-share encryption aes-256 hash sha group 2 lifetime 864000 ! crypto ikev1 enable outside ! tunnel-group FW1 type ipsec-l2l tunnel-group FW1 ipsec-attributes ikev1 pre-shared-key ciscoasa ! crypto ipsec ikev1 transform-set DftTransSet esp-aes-256 esp-sha-hmac ! object network NetObj_Local subnet 172.17.2.0 255.255.254.0 ! object network NetObj_Remote subnet 172.16.2.0 255.255.254.0 ! object-group network ObjGrp_Local network-object object NetObj_Local ! object-group network ObjGrp_Remote network-object object NetObj_Remote ! access-list RemoteNetACL extended permit ip object-group ObjGrp_Local object-group ObjGrp_Remote access-list RemoteNetACL extended permit ip object-group ObjGrp_Remote object-group ObjGrp_Local ! nat (inside,outside) source static ObjGrp_Local ObjGrp_Local destination static ObjGrp_Remote ObjGrp_Remote ! crypto map RemoteNetMap 1 match address RemoteNetACL crypto map RemoteNetMap 1 set peer FW1 crypto map RemoteNetMap 1 set ikev1 transform-set DftTransSet crypto map RemoteNetMap 1 set security-association lifetime seconds 3600 ! crypto map RemoteNetMap interface outside