The Cisco ASA firewall uses access-lists that are similar to the ones on IOS routers and switches. If you have no idea how access-lists work then it’s best to read my introduction to access-lists first.
Without any access-lists, the ASA will allow traffic from a higher security level to a lower security level. All other traffic is dropped. If you have no idea what security levels on the ASA are about then read this post first.
Access-lists are created globally and then applied with the access-group command. They can be applied in- or outbound.
There are a couple of things you should know about access-lists on the ASA:
- When you create an ACL statement for outbound traffic (higher to lower security level) then the source IP address is the real address of the host or network (not the NAT translated one).
- When you create an ACL statement for inbound traffic (lower to higher security level) then the destination IP address has to be:
- The translated address for any ASA version before 8.3.
- The real address for ASA 8.3 and newer.
- The access-list is always checked before NAT translation.
Let’s take a look at some examples how we can use access-lists. I’ll be using this topology:
We have three devices, R1 on the inside, R2 on the outside and R3 in the DMZ. This means that by default the following traffic is allowed:
- R1 can reach R2 or R3 (from security level 100 to 0 or 50)
- R2 can’t reach any devices (from security level 0 to 50 or 100)
- R3 can reach R2 but not R1 (from security level 50 to 0 or 100)
Let’s look at an example first where we restrict traffic from the inside as by default, all traffic is allowed.
Deny Traffic from Inside
To test this I will enable HTTP server on R2 so that we have something to connect to from R1:
R2(config)#ip http server
Now we’ll telnet from R1 to R2 using TCP port 80:
R1#telnet 192.168.2.2 80 Trying 192.168.2.2, 80 ... Open
This traffic is allowed by default, let’s create an access-list that restricts HTTP traffic. We’ll create something so that users on the inside are not allowed to connect to the HTTP server on R2. All other traffic will be permitted:
ASA1(config)# access-list INSIDE_INBOUND deny tcp any host 192.168.2.2 eq 80 ASA1(config)# access-list INSIDE_INBOUND permit ip any any
The access-list above will do the job.
Let’s enable the access-list:
ASA1(config)# access-group INSIDE_INBOUND in interface INSIDE
The access-group command enables the access-list called “INSIDE_INBOUND” inbound on the “INSIDE” interface. Let’s see if we can still reach the HTTP server on R2:
R1#telnet 192.168.2.2 80 Trying 192.168.2.2, 80 ... % Connection refused by remote host
This is no longer working, take a look on the ASA to see why:
ASA1# show access-list INSIDE_INBOUND access-list INSIDE_INBOUND; 2 elements; name hash: 0x1cb98eea access-list INSIDE_INBOUND line 1 extended deny tcp any host 192.168.2.2 eq www (hitcnt=1) 0xe9af7602 access-list INSIDE_INBOUND line 2 extended permit ip any any (hitcnt=0) 0x38288040
As expected the ASA is dropping this packet because of our deny statement. Using an access-list like this is useful to deny some traffic from hosts that is headed towards the Internet or DMZ. Let’s continue with another example…
Permit Traffic to DMZ
When you have a DMZ you probably want to access some of the servers in it from the Internet. To allow this, we need to create an access-list that permits our traffic. For example let’s say that we have a telnet server in the DMZ that should be reachable from the Internet. We can create an access-list like this:
ASA1(config)# access-list OUTSIDE_INBOUND permit tcp any host 192.168.3.3 eq 23
This access-list will permit traffic from any device that wants to connect with IP address 192.168.3.3 on TCP port 23. Let’s activate it:
ASA1(config)# access-group OUTSIDE_INBOUND in interface OUTSIDE
This access-list is now activate on the OUTSIDE traffic and applied to inbound traffic. Let’s test it by telnetting from R2 to R3:
R2#telnet 192.168.3.3 Trying 192.168.3.3 ... Open
Great we are able to connect from R2 to R3. Let’s verify this on the ASA:
ASA1# show access-list OUTSIDE_INBOUND access-list OUTSIDE_INBOUND; 1 elements; name hash: 0x82be59f0 access-list OUTSIDE_INBOUND line 1 extended permit tcp any host 192.168.3.3 eq telnet (hitcnt=1) 0x19e795c8
You can see that we have a hit on our permit statement. Last but not least, let’s take a look at an example where we use an access-list for outbound traffic…
Restrict Outbound Traffic
In the previous examples I showed you how to use inbound access-lists. This time we’ll use an outbound access-list. For example, let’s say that we want to ensure that all our hosts and servers that are located in the inside or DMZ can only use one particular DNS server on the outside. We can create an access-list like this: