In a previous installment of this tutorial (Part I), the basic Context-Based Access Control IOS stateful firewall was set up and configured to allow through all return transit traffic going from the outside to the inside router.

In this installment (part II), we will be covering problems like the CBAC router’s own-generated traffic, the traceroute issue and the timers and thresholds for a CBAC IOS firewall. We will also cover how to maintain and monitor the CBAC IOS stateful firewall.

Context-Based Access Control and Self-Generated Traffic

(GNS LAB : CISCO IOS FIREWALL (STATEFUL) – Context-Based Access Control (CBAC) – Own Traffic)

Remember that the CBAC router was configured to inspect traffic generated inside our network and going through the CBAC router. This doesn’t include any traffic that is generated by the router itself. Any traffic generated by the router itself will not be inspected and catered for and will instead have to deal with the current access control list configured on the outside interface (namely deny any any log).

Let’s test telnet (TCP) and ping (ICMP) from the CBAC router itself.

Telnet-ing from the outgoing interface or from the lo1 won’t do it:

And on the same CBAC router’s console, mixed with the telnet output (red), we can see the log messages (blue) indicating denied TCP packets on their way back to our inside network.

The same behavior will be noted with pings from either the outgoing interface or from the lo1.

And the same error log messages appear on the console:

To have this situation solved and have self-generated traffic on CBAC router get inspected and catered for by the same inspect rule like the other transit traffic, we need to add the “router-traffic” option at the inspect rule command in addition to the inspected protocol. For every protocol inspected the additional “router-traffic” option is added to the command:

And the list of configured inspect rules would then look like:

We are allowing only ICMP/TCP/UDP inspection because we expect to be doing some telnet (TCP), pings (ICMP) and maybe some NTP traffic (UDP) from our CBAC router and we want the return traffic to get back in seamlessly.

Once the CBAC router is told to include its own traffic in the inspect rule, we will be able to generate any TCP, UDP or ICMP traffic and get it through the temporary open gates on the router IOS firewall without getting in trouble with the current access control list that just drops everything that was not catered for by the CBAC inspect rule (remember the deny any any log command?).

Now that we have the CBAC configured to inspect its own flows, pings from CBAC router to the loopback interface on the outside router works like a charm.

And the same is valid for pings from the CBAC router loopback interface to the outside router loopback interface.

The telnet test will yield similar results to those seen with the ping test. Telnet to the outside router loopback interface from our own loopback interface will succeed:

And without loopback interface as source to.

If we remove, for example, the tcp protocol on the setup to inspect CBAC router’s own generated traffic:

We will have telnet tests failing:

But ping tests will run seamlessly:

When we test the reverse (TCP inspected and ICMP not inspected):

The failures will be observed on the ping tests as shown by the output below:

But the telnet tests will work just fine.

Self-generated traffic (router-traffic) is an important topic because when not correctly considered, your routing protocols might get broken and OSPF or EIGRP will fail. The same applies to traceroutes and pings executed directly on the CBAC router.


The traceroute question, which is common to both transit and self-generated traffic, has been eluded up to now, I hope you noticed. Up to now, the way the CBAC router is configured, with the deny ip any any log unique directive in the extended access control list, traceroute isn’t working even when started from the inside router to the outside router.

Here it is tried without the lo1 as the source:

And with the lo1 as the source interface:

It keeps dying at the CBAC router and no replies from beyond that router.

Once again, the official reason is given by the logs on the CBAC router console:

Return flows from my traceroute destination, outside router, are being denied by the access control list CBAC_INTENSE_SCHOOL_OUTSIDE_IN configured on the outside interface to “deny ip any any log“. As discussed earlier, this is the manifestation that the inspect engine is not catering for the traceroute flows and the traceroute return flow is left to “deal” with the “obstructive” access control list.

Why is traceroute failing? Traceroute is failing for one simple reason: traceroute requests are in TCP and the replies are in ICMP. So traceroute returns are not mirror images of the outbound flow. You may be tempted to say, “But we thought that CBAC was crafted to inspect even those flows for irregular protocols with return flows not mirroring their outbound counterpart?!” Yeah that’s right but traceroute is not included in these protocols.

The command above shows us that when configuring protocols to inspect, traceroute is not among the protocol available in the “t”-range.

Any protocol that I can configure in the inspect engine won’t need a special gate for its return flow to be configured on the access control list. But in the case of traceroute, with the version shown above, I will need to craft a gate into the access control list CBAC_INTENSE_SCHOOL_OUTSIDE_IN for traceroute return flow to go through.

For the purpose of this traceroute problem, suffice to say that we need to open for ICMP return messages of type and code “port-unreachable” (or type 3 and code 3) that are sent by every host along the way to the traceroute originator. The ICMP message type and class is beyond the scope of this tutorial and may even warrant a dedicated tutorial of its own.

(GNS LAB : CISCO IOS FIREWALL (STATEFUL) – Context-Based Access Control (CBAC) – The Traceroute Solution)

Here is the traceroute results before we punch holes into the access control list wall for traceroute return messages of type 3 and code 3 (these are port-unreachable messages).

If we go on and edit the access control list so as to make a way for return icmp “port-unreachable” flows:

We can see the immediate results where the stalled traceroute finally completes successfully.

We have thus solved the traceroute problem by making a door for specific return ICMP messages (port-unreachable) necessary for the traceroute to work. However, this permanent opening in the access control lists wall is less elegant compared to the dynamic real time openings the CBAC IOS firewall provides with its inspection engine. This constitutes a security risk also as it is a permanent gate open even when no relevant legitimate traffic needs it. Any possible bug in the ICMP protocol that causes vulnerability to port-unreachable packets would leave the device exposed to malevolently crafted port-unreachable packets from outside.

Timers and Thresholds for CBAC IOS Firewalls

One of the CBAC embedded features is TCP Intercept like the one seen in the previous tutorial named “GNS3 – Cisco TCP Intercept Feature Against SYN Flood Attacks“. This means that once the CBAC IOS firewall is enabled and configured, a default TCP Intercept engine kicks in and helps the IOS to protect the network and hosts against SYN-flood attacks that can clog the victim host’s TCP stack with half-open sessions due to intentionally unfinished three-way TCP handshakes.

Default settings will from time to time prove to be wanting and we will sometimes need to fine tune the timers and thresholds. The timers and thresholds topic is beyond the scope of this CBAC tutorial. For further details please refer to the above mentioned article.

However, when needed, timers and thresholds can be fine-tuned for intercept feature in the inspect engine. Notice that the syntax and terminology of the intercept feature within the inspection engine is similar to the one for the standalone intercept feature.

We can see here the one-minute and max-incomplete threshold-ing with their HIGH and LOW marks to configure the right behavior when dealing with excess half-open connections.


The same applies for timers, TCP centric or otherwise (UDP centric). Synwait-time or Finwait-time can be set for TCP sessions:

And idle-time for UDP session timers:

TCP centric timers can even be further configured to have separate timers for separate hosts.

That’s beautiful, huh?!

Another fact to keep in mind is the way Reflexive ACLs use idle timers to know when to shut the gate for the returning flow because of witnessed inactivity. Relying on idle timers to know when to shut the temporary gate opened for a flow constitutes a spoofing attack vulnerability. CBAC and its inspection engine on the other hand rely on the FIN flag (in TCP sessions) to know when the session is terminated and to close the gate as soon as it sees a packet with a FIN flag set.

Let’s for example try to open and close a session with a TCP protocol like telnet and see how the inspect engine manages to close down the session as soon as the host closes the connection.

We first telnet into the outside router from the inside router. We took care to check the clock:

Immediately after, we close the connection with the exit command, causing the inside router to send a FIN flagged packet to the outside router to terminate the connection.

If we check the inspect sessions we can see that this session is closed by the CBAC router in a matter of milliseconds because the Inspect engine is able to see in real time the FIN flag signaling connection shut down. This allows the CBAC router to close gates previously open for return flows and close them in real time thus reducing the exposed surface for spoofing attacks.

Unfortunately connectionless protocols like UDP and ICMP don’t have flags in packets like the one we see in TCP packets and therefore the router/firewall won’t know when exactly the session closed and will have to rely on the idle timeout.

In this installment of the Context-Based Access Control tutorial, we’ve configured the CBAC router’s self-generated traffic inspection to allow any return traffic for flows triggered by the edge (CBAC) router itself. That will prevent us from breaking control planes connectivity between EIGRP and OSPF neighbors.

The tutorial also covered the traceroute issue and the timeout and thresholds settings for the integrated intercept feature. This allowed us to fine tune the timers and thresholds to our liking for a better operation of the Intercept feature.

In the next installment of our tutorial we will cover monitoring the CBAC’s inspect sessions, the Port to Application Mapping, audit trails and alerts, etc.

I hope to see you in the next and final installment of the Context-Based Access Control Cisco IOS stateful firewall series.