Cisco ASA vpn-filter as I see it

I must admit, it took me some time to become familiar with ASAs “vpn-filter” functionality. Sometimes I have a feeling that guys from Cisco make thing weird on purpose. This feature could be implemented in less weird way, if you ask me. Ok, here is the issue: you are in charge on ASA box (once again). You have one tunnel, then comes another one, third, … For each of them you have to have in place some kind of security policy. Some of these tunnels you trust fully, because they are your remote offices, but there are those you don’t trust fully. You want to provide them with just enough right to do their job. No more, no less.

There are two ways of doing this. One is obvious: use outside ACL and filter out what you don’t want into your network. This will work, but have in mind that outside ACL has many more other things to filter out, and if you have lot’s of tunnels it can be tough to cope with it.

Second one is the one I will try to explain. This is my point of view on “vpn-filter“…

We can totally kick the outside ACL out of the equation and construct special ACL that is not bound to outside interface but instead to each VPN tunnel. As far as number of ACEs required in this approach and outside ACL’s, you need roughly the same number. But now you can name ACL by your partner’s name. This way you will manage VPN access more easily than looking through the one large, “partnerly” unnamed ACL. Yes, but… This is where Cisco’s weirdness comes into play, when you want to construct this ACL. Construst? A heavy word? Read on! But before you do, you must be aware of the “sysopt connection permit-vpn” command. It is not listed in the config, is on by default and only with it the traffic coming from the tunnel will be ignored by outside ACL. Have this in mind!

Let’s look at the basic topology:

We are in charge of Company1’s ASA box. We have to set up the VPN tunnel with the guys from the Company2 but we want to apply some restrictions. We want telnet from Company1 to Company2 to go through. Remember, we are only dealing with ASA1. We are not interesting in restrictions on ASA2, if any. Beside the telnet, we want HTTP, but in reverse way: from Company2 to Company1. And we want ICMP both ways.

Here is the catch: you always make the vpn-filter ACL in such a way that remote network is at the source position in the ACL and the local network is at the destination position. You just change TCP/UDP port’s position. Let’s illustrate this using our requirements. In our case the vpn-filter ACL would look like this:

access-list VPNFILTER12 extended permit tcp 10.0.2.0 255.255.255.0 eq telnet 10.0.1.0 255.255.255.0
access-list VPNFILTER12 extended permit tcp 10.0.2.0 255.255.255.0 10.0.1.0 255.255.255.0 eq www
access-list VPNFILTER12 extended permit icmp any any

As you can see, remote network (in this case 10.0.2.0/24) is always at the source position and the local network (10.0.1.0/24) is at the destination position. If we want to allow the access from the remote network the ACE looks like one from second line and this is how we used to deal with ACEs. This line reads: from source network 10.0.2.0/24 to destination network 10.0.1.0/24 allow port TCP/80.

But look at the first line. Isn’t it weird? In traditional ACL we would read this: from source network 10.0.2.0/24 and port TCP/23 allow traffic to destination network 10.0.1.0/24. What a mess!

So forget about traditional reading and remember:

– you always type in ACEs so that at the source position you put remote network and at the destination position you place local network
– if you are permitting something from remote network to local network just type the destination port after destination (local) network
– if you are permitting something from local network to remote network then type the destination port after source (remote) network

Like I said – weird! But if you remember these three rules, you should be fine.

Of course, you need some settings in group-policy section and tunnel-group section like:

!
group-policy 4.4.4.2 internal
group-policy 4.4.4.2 attributes
vpn-filter value VPNFILTER12
!
tunnel-group 4.4.4.2 type ipsec-l2l
tunnel-group 4.4.4.2 general-attributes
default-group-policy 4.4.4.2
tunnel-group 4.4.4.2 ipsec-attributes
pre-shared-key spop123
!

Before i paste the whole ASA’s configs few more thing to have in mind:

- all interesting traffic will trigger the tunnel, whether it is allowed or not by the vpn-filter
- if you DENY something by changing vpn-filter ACL while tunnel is up - it is in effect immediately
- if you PERMIT something by changing vpn-filter ACL while tunnel is up - you MUST rebuild the tunnel

These three things are not from any documentation (at least I did not find them in there), but are from testings I have done in my lab.

So at the end, here are full ASAs configs that illustrates what I just explained. Routers once again act as PCs.

ASA1
!
hostname ASA1
domain-name popravak.com
enable password 8Ry2YjIyt7RRXU24 encrypted
names
!
interface Ethernet0/0
nameif outside
security-level 0
ip address 4.4.4.1 255.255.255.0
no sh
!
interface Ethernet0/1
nameif inside
security-level 100
ip address 10.0.1.254 255.255.255.0
no sh
!
interface Ethernet0/2
shutdown
no nameif
no security-level
no ip address
!
interface Ethernet0/3
shutdown
no nameif
no security-level
no ip address
!
interface Ethernet0/4
shutdown
no nameif
no security-level
no ip address
!
interface Ethernet0/5
shutdown
no nameif
no security-level
no ip address
!
passwd 2KFQnbNIdI.2KYOU encrypted
boot config disk0:/.private/startup-config
ftp mode passive
dns server-group DefaultDNS
domain-name popravak.com
access-list NONAT extended permit ip 10.0.1.0 255.255.255.0 10.0.2.0 255.255.255.0
access-list CRYPTO12 extended permit ip 10.0.1.0 255.255.255.0 10.0.2.0 255.255.255.0
access-list VPNFILTER12 extended permit tcp 10.0.2.0 255.255.255.0 eq telnet 10.0.1.0 255.255.255.0
access-list VPNFILTER12 extended permit tcp 10.0.2.0 255.255.255.0 10.0.1.0 255.255.255.0 eq www
access-list VPNFILTER12 extended permit icmp any any
pager lines 24
no logging message 402128
mtu outside 1500
mtu inside 1500
no failover
icmp unreachable rate-limit 1 burst-size 1
no asdm history enable
arp timeout 14400
nat-control
nat (inside) 0 access-list NONAT
route outside 10.0.2.0 255.255.255.0 4.4.4.2 1
timeout xlate 3:00:00
timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02
timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00
timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00
timeout uauth 0:05:00 absolute
dynamic-access-policy-record DfltAccessPolicy
http server enable
no snmp-server location
no snmp-server contact
snmp-server enable traps snmp authentication linkup linkdown coldstart
crypto ipsec transform-set TS1 esp-aes-256 esp-sha-hmac
crypto map E0-0 100 match address CRYPTO12
crypto map E0-0 100 set peer 4.4.4.2
crypto map E0-0 100 set transform-set TS1
crypto map E0-0 interface outside
crypto isakmp enable outside
crypto isakmp policy 100
authentication pre-share
encryption aes-256
hash sha
group 2
lifetime 86400
no crypto isakmp nat-traversal
telnet timeout 5
ssh timeout 5
console timeout 0
threat-detection basic-threat
threat-detection statistics access-list
!
class-map inspection_default
match default-inspection-traffic
!
!
policy-map type inspect dns preset_dns_map
parameters
message-length maximum 512
policy-map global_policy
class inspection_default
inspect dns preset_dns_map
inspect ftp
inspect h323 h225
inspect h323 ras
inspect netbios
inspect rsh
inspect rtsp
inspect skinny
inspect esmtp
inspect sqlnet
inspect sunrpc
inspect tftp
inspect sip
inspect xdmcp
!
service-policy global_policy global
group-policy 4.4.4.2 internal
group-policy 4.4.4.2 attributes
vpn-filter value VPNFILTER12
tunnel-group 4.4.4.2 type ipsec-l2l
tunnel-group 4.4.4.2 general-attributes
default-group-policy 4.4.4.2
tunnel-group 4.4.4.2 ipsec-attributes
pre-shared-key spop123
prompt hostname context
end

ASA2
!
hostname ASA2
domain-name popravak.com
enable password 8Ry2YjIyt7RRXU24 encrypted
names
!
interface Ethernet0/0
nameif outside
security-level 0
ip address 4.4.4.2 255.255.255.0
no sh
!
interface Ethernet0/1
nameif inside
security-level 100
ip address 10.0.2.254 255.255.255.0
no sh
!
interface Ethernet0/2
shutdown
no nameif
no security-level
no ip address
!
interface Ethernet0/3
shutdown
no nameif
no security-level
no ip address
!
interface Ethernet0/4
shutdown
no nameif
no security-level
no ip address
!
interface Ethernet0/5
shutdown
no nameif
no security-level
no ip address
!
passwd 2KFQnbNIdI.2KYOU encrypted
boot config disk0:/.private/startup-config
ftp mode passive
dns server-group DefaultDNS
domain-name popravak.com
access-list NONAT extended permit ip 10.0.2.0 255.255.255.0 10.0.1.0 255.255.255.0
access-list CRYPTO21 extended permit ip 10.0.2.0 255.255.255.0 10.0.1.0 255.255.255.0
pager lines 24
no logging message 402128
mtu outside 1500
mtu inside 1500
no failover
icmp unreachable rate-limit 1 burst-size 1
no asdm history enable
arp timeout 14400
nat-control
nat (inside) 0 access-list NONAT
route outside 10.0.1.0 255.255.255.0 4.4.4.1 1
timeout xlate 3:00:00
timeout conn 1:00:00 half-closed 0:10:00 udp 0:02:00 icmp 0:00:02
timeout sunrpc 0:10:00 h323 0:05:00 h225 1:00:00 mgcp 0:05:00 mgcp-pat 0:05:00
timeout sip 0:30:00 sip_media 0:02:00 sip-invite 0:03:00 sip-disconnect 0:02:00
timeout uauth 0:05:00 absolute
dynamic-access-policy-record DfltAccessPolicy
http server enable
no snmp-server location
no snmp-server contact
snmp-server enable traps snmp authentication linkup linkdown coldstart
crypto ipsec transform-set TS1 esp-aes-256 esp-sha-hmac
crypto map E0-0 100 match address CRYPTO21
crypto map E0-0 100 set peer 4.4.4.1
crypto map E0-0 100 set transform-set TS1
crypto map E0-0 interface outside
crypto isakmp enable outside
crypto isakmp policy 100
authentication pre-share
encryption aes-256
hash sha
group 2
lifetime 86400
no crypto isakmp nat-traversal
telnet timeout 5
ssh timeout 5
console timeout 0
threat-detection basic-threat
threat-detection statistics access-list
!
class-map inspection_default
match default-inspection-traffic
!
!
policy-map type inspect dns preset_dns_map
parameters
message-length maximum 512
policy-map global_policy
class inspection_default
inspect dns preset_dns_map
inspect ftp
inspect h323 h225
inspect h323 ras
inspect netbios
inspect rsh
inspect rtsp
inspect skinny
inspect esmtp
inspect sqlnet
inspect sunrpc
inspect tftp
inspect sip
inspect xdmcp
!
service-policy global_policy global
tunnel-group 4.4.4.1 type ipsec-l2l
tunnel-group 4.4.4.1 ipsec-attributes
pre-shared-key spop123
prompt hostname context
end

I hope this helped a bit! Until the next time …

This entry was posted in ASA, Cisco, VPN and tagged , , , , . Bookmark the permalink.

15 Responses to Cisco ASA vpn-filter as I see it

  1. Pingback: Cisco IOS vpn-filter | popravak

  2. looka says:

    thank you very much , very helpful

  3. zli says:

    Thanks! This is immpressive explanation…

  4. Marinko says:

    This explanation is better than the one from cisco 🙂
    Clean, easy and straight to the point.
    Excellent job!

  5. Greetings from Châteauroux, France.Does your blog get many spam comments?
    I’m a blogger too and I’m wanting to know how many people have the
    same dilemma. Some of us have started some nice processes and we are looking to swap ideas with others.
    If you’d be intrigued, don’t hesitate to drop
    me a line via email.

  6. Juergen B. says:

    Hi there,
    just tried to implement this vpn-filter stuff on our asa5520 with 8.3(2).
    It works fine for filtering traffic flowing from remote to local networks.
    But as soon I add some permits for traffic flowing from inside to remote, the same ports are immediately open for the other direction.
    So it is not possible to set some kind of rule allowing everything from inside to remote but restrict traffic initiated from the remote side.
    Anyone out there having a solution for this? Or is it only a BUG in my ASA software version?
    Greetings from Germany
    Jürgen

  7. Legendary Explanation. And real world issue. I have 65 VPN’s and some are 3rd even 4th party.

  8. Wilson says:

    Worked great on Cisco ASA 9.1. The backwards part was tough to see, but thanks to this great article it worked great for a site to site that we had to create. THANKS a million!!!!

  9. qruczlevy says:

    Hi,
    Isn’t The NONAT acl incorrect? Shouldnt be?:
    on ASA1:
    access-list NONAT extended permit ip 10.0.1.0 255.255.255.0 10.0.1.0 255.255.255.0
    on ASA2:
    access-list NONAT extended permit ip 10.0.2.0 255.255.255.0 10.0.2.0 255.255.255.0

  10. Ian says:

    The No NAT is correct as per the configuration for 8.2 version or lower.
    Really appreciate the efforts put in.
    Especially the catch in vpn filter value access list wherein we have remote subnet network acting as the source.

  11. shubham kulkarni says:

    Excellent Explanation…………..!

  12. Wow! At last I got a blog from where I know how to actually obtain helpful information concerning my study and knowledge.

  13. Jim B. says:

    Well Cisco can’t explain it like you do, since you’re basically saying their solution is sh*t. So they have to paraphrase it 🙂

Leave a comment