There are times your company will partner with another to provide a resource to them. Often, this interaction is secured with a LAN-to-LAN (L2L) VPN tunnel. Most Cisco documentation about L2L VPNs are written for VPNs within the same organization, as opposed to different companies trying to peer with each other. L2L VPN tunnels within the same organization are relatively simple, for the following reasons:
- That company controls their own IP addressing and can avoid overlapping address space.
- Most L2L VPNs are usually wide open, allowing all IP communication through.
With an L2L VPN tunnel between different organizations, these issues become a greater concern because of overlapping IP space and the need for greater network security.
We will demonstrate how both can be dealt with, but first let us setup the IPSec configuration that is common to L2L tunnels. This lab has been built in GNS3 using ASAs with 8.4 code and MicroCore Linux hosts.
Configs
Note: Some of the VPN config is not all in here yet; we will work on it in the next section.
Local ASA config -
! interface GigabitEthernet0 nameif outside security-level 0 ip address 1.1.1.2 255.255.255.0 ! interface GigabitEthernet1 nameif inside security-level 100 ip address 10.0.0.1 255.255.255.0 ! object network inside subnet 10.0.0.0 255.255.255.0 ! !--- PAT for all other inside hosts nat (inside,outside) 10 source dynamic inside interface route outside 0.0.0.0 0.0.0.0 1.1.1.1 1 ! crypto ipsec ikev1 transform-set aesset esp-aes esp-sha-hmac crypto ipsec security-association lifetime seconds 86400 ! crypto map outside-map 1 set pfs group5 crypto map outside-map 1 set peer 2.2.2.2 crypto map outside-map 1 set ikev1 transform-set aesset crypto map outside-map 1 set security-association lifetime seconds 86400 ! crypto map outside-map interface outside ! crypto ikev1 policy 1 authentication pre-share encryption aes hash sha group 5 lifetime 86400 ! group-policy vpn-grp-policy internal group-policy vpn-grp-policy attributes vpn-tunnel-protocol ikev1 ! tunnel-group 2.2.2.2 type ipsec-L2L tunnel-group 2.2.2.2 general-attributes default-group-policy vpn-grp-policy tunnel-group 2.2.2.2 ipsec-attributes ikev1 pre-shared-key cisco123 peer-id-validate nocheck
Remote ASA config-
! interface GigabitEthernet0 nameif outside security-level 0 ip address 2.2.2.2 255.255.255.0 ! interface GigabitEthernet1 nameif inside security-level 100 ip address 192.168.0.1 255.255.255.0 ! route outside 0.0.0.0 0.0.0.0 2.2.2.1 1 ! crypto ipsec ikev1 transform-set aesset esp-aes esp-sha-hmac crypto ipsec security-association lifetime seconds 86400 ! crypto map outside-map 1 set pfs group5 crypto map outside-map 1 set peer 1.1.1.2 crypto map outside-map 1 set ikev1 transform-set aesset crypto map outside-map 1 set security-association lifetime seconds 86400 ! crypto map outside-map interface outside ! crypto ikev1 policy 1 authentication pre-share encryption aes hash sha group 5 lifetime 86400 ! group-policy vpn-grp-policy internal group-policy vpn-grp-policy attributes vpn-tunnel-protocol ikev1 ! tunnel-group 1.1.1.2 type ipsec-L2L tunnel-group 1.1.1.2 general-attributes default-group-policy vpn-grp-policy tunnel-group 1.1.1.2 ipsec-attributes ikev1 pre-shared-key cisco123 peer-id-validate nocheck
Router config -
! interface FastEthernet0/0 ip address 1.1.1.1 255.255.255.0 speed 100 full-duplex ! interface FastEthernet0/1 ip address 2.2.2.1 255.255.255.0 speed 100 full-duplex
Local host config-
hostname local_host ifconfig eth0 10.0.0.10 netmask 255.255.255.0 route add default gw 10.0.0.1
Remote host config-
hostname remote_host ifconfig eth0 192.168.0.10 netmask 255.255.255.0 route add default gw 192.168.0.1
Overlapping IP Space
The easiest way to deal with the possibility of overlapping IP space is to NAT to a public IP (or at least an IP agreed upon by both parties). With Cisco L2L VPNs, the crypto ACL is processed after NAT. This is why you must use a NAT exemption rule for L2L VPN when not NATing on either end. This means that the crypto ACLs must have the NATed IPs, rather than the private IP addresses.
Local ASA config-
! !--- Objects for the resource object network local_host host 10.0.0.10 object network local_host_nat host 1.1.1.10 ! !--- NAT for the resource nat (inside,outside) source static local_host local_host_nat ! !--- ACL with NATed IP access-list crypto-acl extended permit ip host 1.1.1.10 host 2.2.2.10 ! !---- Apply the ACL to the crypto map crypto map outside-map 1 match address crypto-acl ! !--- Turn IPSec on crypto ikev1 enable outside
Remote ASA config-
! !--- Objects for the resource object network remote_host host 192.168.0.10 object network remote_host_nat host 2.2.2.10 ! !--- NAT for the resource nat (inside,outside) source static remote_host remote_host_nat ! !--- ACL with NATed IP access-list crypto-acl extended permit ip host 2.2.2.10 host 1.1.1.10 ! !---- Apply the ACL to the crypto map crypto map outside-map 1 match address crypto-acl ! !--- Turn IPSec on crypto ikev1 enable outside
Now, we will ping and SSH to the local host from remote host –
root@remote_host:~# ping 1.1.1.10 PING 1.1.1.10 (1.1.1.10): 56 data bytes 64 bytes from 1.1.1.10: seq=0 ttl=64 time=185.055 ms 64 bytes from 1.1.1.10: seq=1 ttl=64 time=82.989 ms 64 bytes from 1.1.1.10: seq=2 ttl=64 time=102.215 ms 64 bytes from 1.1.1.10: seq=3 ttl=64 time=70.191 ms 64 bytes from 1.1.1.10: seq=4 ttl=64 time=40.177 ms ^C --- 1.1.1.10 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 40.177/96.125/185.055 ms root@remote_host:~# ssh [email protected] [email protected]'s password:
Netstat on local host –
root@local_host:~# netstat -ant | grep EST
tcp 0 0 10.0.0.10:22 2.2.2.10:33743 ESTABLISHED
You can see that the local host sees the public IP (2.2.2.10) of the remote host. We have solved the overlapping IP address space issue.
Restricting Resource Access
Now we that have the VPN established between the two organizations, we can secure the access by restricting the connection to only the protocols and ports needed. There are a few ways that this can be done, but there is one I believe provides the greatest level of granular control.
Method #1 – outside ACL
By default, traffic flowing through a VPN tunnel bypasses the interface ACLs. You can change this behavior with the no sysopt connection permit-vpn command. Then, any inbound traffic transiting the VPN tunnel must be evaluated by the outside interface ACL.
The downside is that this affects all VPN tunnel traffic, including your remote access VPN and any other VPN tunnels you might have. It also would allow access to the resource without it having to go through the VPN tunnel, because the outside interface would still accept un-tunneled traffic.
Method #2 – Crypto ACL
On the configs listed above, the crypto ACL is set to permit IP. You could narrow that down to the ports needed.
The downside is that every entry in the ACL would establish another security association and therefore another tunnel (i.e.) 10 lines in the crypto ACL would lead to 10 VPN tunnels, even though the source and destination IP are the same. This uses more system resources which limits its scalability and makes it a little harder to troubleshoot all the different SAs for every port. Cisco recommends that this method not be used, but for the life of me I can’t remember where I saw that bit of Cisco documentation.
Method #3 – VPN filter applied to group-policy
One thing you will notice about the above VPN configuration is that in the tunnel group, we did not use the default group policy, but made a different group policy named vpn-grp-policy. With this, we can apply a vpn-filter with an ACL to control the inbound access on a per-tunnel basis. This gives quite a bit of granular control. If you have 20 other organizations with VPNs tunnels, you can have 20 different group-polices and 20 different ACLs.
! access-list vpn-gp-filter extended permit tcp host 2.2.2.10 host 1.1.1.10 eq 100 access-list vpn-gp-filter extended deny ip any any ! group-policy vpn-grp-policy attributes vpn-filter value vpn-gp-filter
Note: You must clear the existing SA for this to take effect.
One item you will notice is that NATed addresses are used in the access list. In ASA code 8.3 and above, the access-list format for interfaces changed to the real IP addresses instead of NATed addresses. However, VPN filter ACLs are like 8.2 and below, and use the NATed IP address.
We will use a netcat server on the local host to test connectivity -
root@local_host:~# nc -l -p 100
On the remote host we send a message to the local host -
root@remote_host:~# nc 1.1.1.10 100 Hello this is a test ! ^C punt!
And this is what we see on the local host -
root@local_host:~# nc -l -p 100 Hello this is a test ! [1]+ Done
Now we test the SSH connectivity that had worked earlier and see it time out -
root@remote_host:~# ssh [email protected] ssh: connect to host 1.1.1.10 port 22: Connection timed out
And the local ASA logs the ACL drop -
%ASA-6-106102: access-list vpn-gp-filter denied tcp for user '' outside/2.2.2.10(58634) -> inside/1.1.1.10(22) hit-cnt 1 first hit [0xdc2d972e, 0x0]
