Reflexive access control lists are a security feature like the dynamic access control lists we discussed in a previous tutorial. They can be seen as a defense method against unwanted and dangerous incoming traffic from intruders outside our network. They make it easy to control what traffic enters our network, much easier than with the usual standard and extended access control lists.

Reflexive access control lists operate in the following way:

  • Outbound traffic from inside our network goes through an outbound access control list. That traffic is permitted through and every session information is reflected into a state table to keep a temporary record of all active sessions.
  • The state table is the base all incoming flows will be checked against to determine if the incoming flow is a response to an existing outgoing flow. When found to be a part of a conversation initiated by an inside host, the traffic flow is allowed in; otherwise, it will be denied entry in our network.

Reflexive access control lists perform better because instead of checking the usual RST and ACK flags in a packet (referring to the TCP three-way-handshake), they also check source and destination IP addresses and PORTS. Additionally, they work well with standard TCP and UDP applications as opposed to the earlier method of checking the EST flags which is specific to TCP only.

They have some limitations however:

  • They provide a lesser application level inspection than Control Based Access Control and Zone Based Policy Firewall.
  • Nonstandard applications like SIP for VoIP and TRACEROUTE have outbound traffic flows different from inbound traffic flows. The same is true for Active FTP where once the client initiates the connection, the server disconnects the clients and initiates on its own a different unsolicited session back to the client. Those kinds of traffic will be denied by reflexive access control lists and the administrator will need to perform special manual configurations to allow them in.

There is one more caveat:

  • Locally generated traffic is not classified by the outbound access control list. Our reflexive access control list can/may/will break some of our IGP and EGP protocol exchanges like the OSPF/EIGRP and BGP sessions between IOS routers. This will be fixed by editing our access control lists to permit specific protocols we know are active on our network.

Once reflexive access control lists are configured properly, any node inside our network (e.g. inside) will be able to ping or telnet outside but no node from outside our network (e.g. outside3) will be able to do so unless other access control lists are specially configured to let them.

Reflexive Access Control Lists Configuration

Reflexive access control lists will be configured by:

  • An outbound extended access list that permits outgoing traffic and records the session information in a state table (REFLEXIVE_STATE_TABLE)
  • An inbound access list that evaluates the flow against the REFLEXIVE_STATE_TABLE and allows in the right flow
  • Deny is implicit and should be replaced by an explicit deny log for our debugging needs but it should always be removed when all the settings are in place to work as planned.

Let’s start now.

For the outbound traffic we create an outbound access control list that will be applied to the outside interface:

And we record (reflect) the flow state into a state table to check incoming flow against:

The same “reflect” operation is done for UDP and ICMP traffic for good measure:

For inbound traffic, we create an inbound access control list that will be applied on the outside interface:

And evaluate that inbound traffic flow against the previously “reflected” outbound traffic flow as stored in the configured state table:

Don’t forget to allow your inbound IGP traffic since it was not reflected into the state table by your reflexive access control list and therefore might be denied and rejected simply because it is not in the configured state table. For more information, our lab is now running static routing so there will be no such statement like permit eigrp any any.

The friendly explicit “deny and log” statement allows us to see on the console all rejected traffic for information. Otherwise, there is the usual implicit deny statement at the end of every access control list.

We go into the outside interface:

Here the two configured access control lists are applied, one inbound and the other outbound. Make sure they are each applied in the right direction or else you won’t get the desired effect.

If we go to the inside router and do a ping to the lo1 of the outside3 router:

On the outside3 router the show access-list output is displayed below:

We can see the content of the state table. This is an ICMP entry generated by a host outside our network replying to pings from a host inside our network. And the state table entry is saying reverse traffic flow (in the inbound direction) to the inside router from the outside3 router was permitted through the outside interface.

Note also the timer saying 294 seconds are left before this flow is removed from the state table if no more traffic matching it is seen on the router’s outside interface.

If we do a telnet into the outside3 router from the inside router:

Another telnet traffic flow entry is now showing up on our access control list state table.

A telnet session initiated from the outside3 router will fail:

And a log showing us the denied traffic appears on the border router:

This shows clearly that the reflexive access control lists are working, allowing any traffic from inside to outside and its related incoming traffic but denying any incoming traffic generated outside our network.

How to Manually Configure Access Control Lists for Needed Traffic

How to Fix Traceroute

In real life situations, the nonstandard protocols will also need a fix to allow their incoming traffic through the border router because, for now, active FTP traffic, VoIP traffic, etc., won’t go through the border router whatever the direction. Even traceroute initiated from the inside router won’t work because of the difference between the outgoing and incoming flows of the same session.

In the following example, a traceroute generated inside our network dies at the border router due to a reflexive access control list and can’t go beyond.

We can witness from the log messages the incoming ICMP traffic being denied on the outside interface of the border router:

We can even see the ICMP code and the type of packets that are being denied. In our exact case, the three packets are “icmp type11–code0”, “icmp type11–code0” and “icmp type 3-code3” respectively.

The exact meanings of these ICMP types and codes are beyond the scope of this tutorial but can easily be found and consulted in various IETF documents related to traceroute. One needs to understand how traceroute works in order to interpret the ICMP packet type and code that every intermediate host sends back to the ICMP originator. Suffice to say that in the framework of this tutorial and reflexive access control lists in general, the logs above show us two ICMP (11/0) and one ICMP (3/3) being denied.

This gets even easier to understand when we realize, from the show access-list output, that when it is about traceroute, the outbound flow and the inbound flow are not the exact mirror of each other as far as the protocols are concerned. The requests are sent as UDP while the replies are sent back as ICMP.

The logs above show us ICMP replies while the logs below show us the requests sent as UDP packets. This alone is enough for the border router with reflexive access control lists to not take these two flows as parts of one session.

One document you can find at states that icmp type-3 means Destination Unreachable and icmp type-11 means Time Exceeded as per RFC792.

Many of the ICMP types have a code number, something like a subtype. Code-3 in icmp type-3 means port unreachable as per RFC792.

How do we fix such issues when traceroute is one of the first-aid tools that network administrators run to when troubleshooting network faults?

We have already been told in the console log messages that the ICMP packets are being denied by the inbound access control list on the outside interface of the border router. Another fact told by the state table, as shown by the command show access-list, is that icmp type11 code0 and icmp type3 code3 are the ones being denied. We are going to edit our access control lists to open a door for these ICMP messages since, otherwise, as per the reflexive access control lists, these packets will never get admitted past the border router.

Let’s now go and fix the traceroute issue according to what we have diagnosed so far.

We go in the inbound access control list:

And permit icmp type 11/0 (time-exceeded):

And also icmp type 3/3 (port unreachable):

These two permit statements will be inserted at the top of the list of statements.

If we do a traceroute now from inside our network to a router outside our network, we see that the traceroute successfully completes (whatever the source interface used).

And that is no wonder because we can now see that the inbound access control list has been set to allow ICMP messages in.

How to Fix Locally Generated Traffic like Ping and Telnet

At this point in our lab configuration, we still can’t ping and telnet from our border router where the reflexive access control lists are configured to any router in the outside network. This is due to the reflexive access control lists not catering for these flows considered locally generated traffic as opposed to transit traffic. Also, nothing has been done to manually allow these locally generated traffic inbound flows past the outside interface of the border router.

We can see the telnet and ping failing below:

On the same console we can see how the replies are being denied.

This problem can be solved in two ways:

1. We can add this traffic to the permitted traffic through our inbound access control list.

2. We can also fix this issue with some local policy based routing so as to have our border router treat its own locally generated traffic as a transit traffic and let the reflexive access control lists deal with opening for the incoming traffic flow based on the outgoing traffic flow.

The latter is a little bit beyond the scope of this tutorial while the former can be quickly done since we are already dealing with access control lists.\

Let’s go and fix this with our extended access control lists.

Permit any TCP traffic from port 23 to our lo1 on the border router:

Also allow the same incoming traffic to our outside interface on the border router:

This allows us to telnet from the border router’s lo1 or the outside interface:

For the ping problem, we will be brief and point out that this is an ICMP problem as the console log message shows:

One hint is to proceed the same way as with the traceroute, and edit our access lists to allow the specific ICMP messages of type 0 code 0.

We have reached the end of our tutorial and thank you for reading. More tutorials to come soon.