Recently, I came across something I have never seen before on the Cisco ASA and I decided to write an article on it. In the scenario, a Cisco ASA was configured for remote-access VPN connections. However, a new policy requires that the source IP addresses of hosts that can connect to the remote access VPN be filtered.

I will be using a simple network diagram to simulate this as shown below:

The configuration on the ASA is shown below. Notice that it includes a remote access tunnel-group called ‘VPN’.

interface GigabitEthernet0
 nameif outside
 security-level 0
 ip address
ip local pool MYPOOL mask
crypto ipsec ikev1 transform-set TRANS_SET esp-3des esp-md5-hmac
crypto dynamic-map DYN_MAP 1 set ikev1 transform-set TRANS_SET
crypto map MYMAP 1 ipsec-isakmp dynamic DYN_MAP
crypto map MYMAP interface outside
crypto ikev1 enable outside
crypto ikev1 policy 1
 authentication pre-share
 encryption 3des
 hash sha
 group 2
 lifetime 86400
group-policy GRP_POL internal
group-policy GRP_POL attributes
 address-pools value MYPOOL
username example password 9hx9DtELyXf6OAqH encrypted
tunnel-group VPN type remote-access
tunnel-group VPN general-attributes
 authorization-server-group LOCAL
 default-group-policy GRP_POL
tunnel-group VPN ipsec-attributes
 ikev1 pre-shared-key *****

I have a Cisco VPN client on my laptop which is configured to connect to the remote access VPN as shown below:

Notice that I can successfully connect to the VPN.

Let’s now implement the policy that requires that only certain hosts are allowed to connect to the VPN. Keep in mind that this is not VPN traffic filtering because we want restriction even before connection is made. The default thinking will be to apply an access list on the outside interface of the ASA. For example, let’s assume we want only hosts and to be able to connect to the VPN; we can implement something similar to the configuration below:

object-group network ALLOWED_VPN_HOSTS
 network-object host
 network-object host
access-list OUT_IN extended permit esp object-group ALLOWED_VPN_HOSTS host
access-list OUT_IN extended permit udp object-group ALLOWED_VPN_HOSTS host eq isakmp
access-list OUT_IN extended deny esp any host
access-list OUT_IN extended deny udp any host eq isakmp
access-group OUT_IN in interface outside

As you can see from above, I have created and applied an access list that permits ESP and ISAKMP traffic from and only and denies ESP and ISAKMP from other IP addresses.

Let’s see if this works. My laptop has an IP address of so it should be restricted.

I will disconnect from the previous VPN connection and attempt to reconnect.

The VPN connected successfully. I can check the VPN session on the ASA to see that the IP address is actually

Now that we have seen that our access list doesn’t work, let me explain what is happening. The access list applied on the ASA by default using the access-group command only filters traffic passing THROUGH the ASA; it does not filter traffic TO the ASA. In short, we can say that the default access list applies to the data plane not the control plane. Luckily for us, there is an option that allows us to specify that an applied access list should be used for traffic destined to the ASA itself and that is the “control-plane” keyword in the access-group command.

Now, let’s disconnect and try to connect to the VPN again.

If we were to take a look at the access list counters, we will notice the hit count of the denied packet.

Cool, so we have seen how to filter traffic destined to the ASA itself using the control-plane keyword. However, a question may be looming on your mind: What if we already had an access-list configured on that interface, would we have to change it to a to-the-box access list? That’s another awesome thing about this feature: You can have this to-the-box access list and a normal access list applied and functioning on the same interface at the same time. For example, let’s create another access list to permit SSH traffic from through the ASA.

As you can see, both access lists are applied on the same outside interface. I will add a router connected to the ASA’s Gi1 interface with an IP address of and enable SSH on that router so we can test.

Note: To get this test to work, the new router must know how to reach the host. Also, you need to add a route on your host for

The above proves that both access lists are functioning simultaneously. We can take a look at the counters of the PERMIT_SSH access list to see that the SSH traffic was matched.

To conclude this article, please note that access control rules for management traffic to the ASA (e.g. HTTP, SSH and telnet) are not affected by the to-the-box access list we configured using the control-plane keyword. These other commands have higher preference.

Let me show you what I mean. Suppose I add an entry to the OUT_IN access list that denies SSH traffic to the ASA from At the same time, if I use the ssh command to allow SSH from that host, the host will be allowed to SSH to the ASA because the ssh command has a higher precedence than the control plane access list as shown below:

access-list OUT_IN extended deny tcp host host eq ssh
crypto key generate rsa modulus 1024
ssh outside
aaa authentication ssh console LOCAL

As you can see, the SSH connection was permitted and you will notice that the deny statement in the OUT_IN access list did not have any effect.


It’s always best to test out solutions because you may be surprised when it does not work the way you thought it would. In this article, we have seen how to use access lists to filter traffic that are destined to the ASA itself. We have also seen that those control plane access lists have a lower precedence than access control rules for management traffic such as HTTPS and SSH.

I hope you have found this article helpful. Keep discovering.

Further reading