Reflexive access lists

By stretch | Tuesday, November 25, 2008 at 7:02 a.m. UTC

A typical approach to network perimeter security is to allow outbound traffic not explicitly denied, and to deny inbound traffic unless it is explicitly allowed. Although simple in concept, this approach requires significant considerations regarding the return path of internally initiated sessions. Consider the following scenario:

topology.png

Clients resides on the secure 192.168.0.0/24 subnet, which is connected to the Internet by R1. We can place both inbound and outbound access lists on R1's F0/1 interface to restrict communication between our internal network and the Internet.

For the sake of an example, let's assume we want to allow web traffic from the client to web servers on the Internet. We can leave outbound traffic (from client to server) unrestricted by simply not including an ACL, but how would we restrict return traffic from the Internet? Obviously we can't simply deny all traffic, or nothing would work. Nor can we allow all traffic, as it would leave the secure subnet exposed.

We also can't simply allow all TCP traffic with a source port of 80, as an attacker could easily send malicious traffic using 80 as his source port. And we can't restrict inbound traffic to certain source IP addresses, as we'd have to create a new entry for every server we want to access on the Internet. We could allow inbound traffic to the client's source port, but this is typically a randomly-chosen high port number which can't be practically matched with static configuration. But what if we could record and match each source address/port pair automatically?

Enter reflexive access lists. To employ reflexive ACLs, three access lists are actually needed: one for inbound traffic, one for outbound traffic, and one (the reflexive ACL) to keep track of dynamic entries. Outbound traffic matched in the outbound ACL is reflected to the reflexive ACL; that is, the source and destination addresses and ports are swapped and the entry is recorded in the reflexive ACL with an expiration timer. Traffic in the other direction is matched against the inbound ACL, which in turn evaluates the entries in the reflexive ACL.

First let's create an outbound ACL named Egress to reflect entries for outgoing packets:

Router(config)# ip access-list extended Egress
Router(config-ext-nacl)# permit ip any any reflect Mirror
Router(config-ext-nacl)# interface f0/1
Router(config-if)# ip access-group out Egress

Any packet matched by Egress will be reflected into our reflexive ACL, named Mirror. Since Egress matches all IP traffic, we reflect entries for TCP, UDP, and ICMP. If we wanted, we could have specified only TCP, for example, to only match TCP traffic. While TCP sessions are relatively simple to track, IOS can also roughly track UDP and ICMP "sessions," even though these aren't true session-oriented protocols.

egress_acl.png

Now when a client in 192.168.0.0/24 initiates a TCP session to a server on the Internet we can see a reflected entry is created in Mirror:

Router# show ip access-lists Mirror
Reflexive IP access list Mirror
  permit tcp host 209.20.64.81 eq www host 192.168.0.123 eq 62839 (7 matches) (time left 294)

Now, to put our reflexive ACL into action! We'll create an inbound ACL named Ingress to evaluate Mirror, and apply it inbound to FastEthernet0/1:

Router(config)# ip access-list extended Ingress
Router(config-ext-nacl)# evaluate Mirror
Router(config-ext-nacl)# interface f0/1
Router(config-if)# ip access-group in Ingress

ingress_acl.png

Now packets inbound on FastEthernet0/1 are only allowed in if they are permitted by Ingress, which is essentially just a reference to Mirror. Note, however, that we are free to add normal entries to Ingress both before and after the evaluate statement if we want. With all three components in place, we can see the static outbound entries (Egress), the static inbound entries (Ingress), and the dynamic inbound entries (Mirror):

Router# show ip access-lists 
Extended IP access list Egress
  10 permit ip any any reflect Mirror (76 matches)
Extended IP access list Ingress
  10 evaluate Mirror
Reflexive IP access list Mirror
  permit tcp host 209.20.64.81 eq www host 192.168.0.123 eq 62839 (7 matches) (time left 248)

One last item to note is the expiration timer on the Mirror entry. This timer is reset to 300 seconds with each new packet that would cause the reflection. If no new traffic has been seen before the timer expires, the entry is erased. Additionally, when the router detects a session has been closed (for example, using the FIN flag in TCP), the timer is immediately reduced and the entry is removed shortly thereafter.

About the Author

Jeremy Stretch is a network engineer living in the Raleigh-Durham, North Carolina area. He is known for his blog and cheat sheets here at Packet Life. You can reach him by email or follow him on Twitter.

Posted in Security

Comments


rantanplan (guest)
November 25, 2008 at 9:13 a.m. UTC

Great post!

But consider that router generated traffic is not reflected and therefore return traffic will be blocked by the ingress ACL. Important when using routing protocols on the same link!


Praetor (guest)
November 25, 2008 at 1:36 p.m. UTC

Superb explanation!

Please tell me, is CBAC (for simple L4 and L3 protocols, ie. TCP, UDP, ICMP...) using the same mechanism as reflexive access-lists. Works pretty much the same, doesn't it?


Michael (guest)
November 25, 2008 at 2:21 p.m. UTC

Very informative stretch, thanks.

Two questions though: one is the same as Praetor's, the other is related to NAT. In your example you are NAT overloading from 192.168.0.0/24 to your WAN IP, so wouldn't this ACL for this particular scenario be overkill? Doesn't NAT overload do this same process by default? Are there any benefits to applying this to a NATed interface? Thanks.


Vybhav (guest)
November 25, 2008 at 4:58 p.m. UTC

Awesome explanation..Yeah i agree with Praetor...does CBAC work the same way... if yes where can one find the logs or the "reflexive access-list" created by CBAC?


Kam (guest)
November 26, 2008 at 9:13 a.m. UTC

Nice, can see some use for it rather than using CBAC, CBAC limited, you could have a requirement to open a particular protocol not covered by CBAC, ALSO CBAC inspection chew up the processor by adding in alot of inspections


Ron (guest)
November 26, 2008 at 11:04 a.m. UTC

CBAC is more robust, as it can monitor applications that utilize multiple ports when establishing a session, like FTP.

http://tcpmag.com/qanda/article.asp?EditorialsID=379


Paul Stewart (guest)
December 14, 2008 at 4:27 p.m. UTC

I prefer CBAC when possible, but not all ios images have the CBAC features. CBAC looks as the communication in much more detail. However, I have seen a couple of occasions that inspecting TCP absolutely killed performance for an application.


Robert (guest)
March 11, 2009 at 9:35 a.m. UTC

hm, can somebody explain me why this feature is only usable with named ACLs ?

seems so with IOS: C2600-ADVSECURITYK9-M Version 12.4(21)


Addy
April 23, 2010 at 3:57 a.m. UTC

Just Amazing, everyday there is something new on your blog to learn. Thanks a lot


emilio1973
May 28, 2011 at 8:09 a.m. UTC

Nice post!!

Thanks


sunny (guest)
June 6, 2012 at 10:33 a.m. UTC

great post. understood in a single reading. thanks.


Mohideen Pitchai (guest)
December 21, 2012 at 12:54 p.m. UTC

Amazing explanation. its much easier to understand than cisco website.


mohamed (guest)
July 27, 2013 at 11:42 p.m. UTC

thank you very much


Custu (guest)
August 16, 2013 at 9:20 p.m. UTC

Great post. Thank you.


isocaine (guest)
January 17, 2014 at 2:08 p.m. UTC

Dude, how can I send you a coin ?, of course you deserve more than that. You always save me time when I look for explanations.

Question: Reflexive access list, Is there any other way to explain it more easily than this article do ?.

Answer: NO WAY.

A million thanks.


Big Mook (guest)
November 19, 2014 at 9:38 p.m. UTC

Great post, and especially good where CBAC won't work due to IOS constraints, e.g. 2651XM with 12.3T IOS that only has 32MB flash. Can't upgrade to 12.4T or later due to flash size. 12.3T version has a bug that causes most inspected traffic to get dropped.

Reflexive ACL works the same way as CBAC for the most part, and doesn't suffer from the inspection bug.


Vishal (guest)
April 4, 2016 at 7:24 a.m. UTC

Great post. Amazing explanation..

Thanks you very much !!!!


Daniel B. (guest)
April 24, 2016 at 9:17 a.m. UTC

Thumb up for the post (the technical details), but the challenge required in order to post comments was the funniest and inspired surprise of this page. Very nice.


Nishidh (guest)
May 22, 2016 at 10:29 p.m. UTC

Really Good Explanation of How Reflexive ACL works.

Comments have closed for this article due to its age.