Securing Cisco Devices: Part III – CBAC
Cisco developped Context-based Access Control to intelligently filtering TCP and UDP packets based on application-layer protocols. You can inspect traffic for sessions that originate from any side of the firewall (can be an internal or external interface).
Without CBAC your filtering abilities is limited to pure access-lists which are examining the packets at network or transport layer. However CBAC gives you the ability to analyze also the application-layer protocol information. By example CBAC can detect the FTP connection informations and open also the correct ports for active FTP.
CBAC creates temporary openings in access lists at firewall interfaces. These openings are created when specified traffic exits your internal network through the firewall. The openings allow returning traffic (that would normally be blocked) and additional data channels to enter your internal network back through the firewall. The traffic is allowed back through the firewall only if it is part of the same session as the original traffic that triggered CBAC when exiting through the firewall.
You can inspect the traffic at any point of the router:
- Inbound or outbound traffic on the internal interface
- Inbound or outbound traffic on the external interface
It is important to note that CBAC operates at interface level.
Here’s how CBAC will help you: stateful
In following example we want to allow all traffic from inside to outside, but deny traffic initiated from external to the internal side. To solve this we could use the reflexive access-list feature but this is not the point now.
Lets assume we will place this inACL:
Router(config)#ip access-list extended inACL Router(config-ext-nacl)#deny ip any any Router(config-ext-nacl)#interface GigabitEthernet2/0 Router(config-if)#ip access-group inACL in
The result of this configuration is that all traffic from inside to outside is permitted, but the return traffic will be denied (deny ip any any).
To resolve this issue: Use reflexive access-lists or again: activate CBAC…
How CBAC needs to be configured
The important thing about CBAC is that you need to define inspection rules on all protocols you want to monitor. The rule is always: ip inspect name somename procotol:Router(config)#ip inspect name MyFirewall http Router(config)#ip inspect name MyFirewall ftp Router(config)#ip inspect name MyFirewall smtp
And apply it on the Router as outbound policy:
Router(config)#interface GigabitEthernet2/0 Router(config-if)#ip inspect MyFirewall out
Verification of CBAC
After all you can verify the configuration by typing show ip inspect all:
Router#show ip inspect all Session audit trail is disabled Session alert is enabled one-minute (sampling period) thresholds are [unlimited : unlimited] connections max-incomplete sessions thresholds are [unlimited : unlimited] max-incomplete tcp connections per host is unlimited. Block-time 0 minute. tcp synwait-time is 30 sec -- tcp finwait-time is 5 sec tcp idle-time is 3600 sec -- udp idle-time is 30 sec tcp reassembly queue length 16; timeout 5 sec; memory-limit 1024 kilo bytes dns-timeout is 5 sec Inspection Rule Configuration Inspection name MyFirewall http alert is on audit-trail is off timeout 3600 ftp alert is on audit-trail is off timeout 3600 smtp max-data 20000000 alert is on audit-trail is off timeout 3600 Interface Configuration Interface GigabitEthernet2/0 Inbound inspection rule is not set Outgoing inspection rule is MyFirewall http alert is on audit-trail is off timeout 3600 ftp alert is on audit-trail is off timeout 3600 smtp max-data 20000000 alert is on audit-trail is off timeout 3600 Inbound access list is inACL Outgoing access list is not set
So, lets generate on the client a http session and check the session database:
Router#show ip inspect sessions Established Sessions Session 672E0CE4 (192.168.1.100:46153)=>(193.239.22.2:80) http SIS_OPEN
This means nothing that just adding temporary entries in front of the access-list of the interface. inACL could now be dynamically extended like:
ip access-list extended inACL permit tcp host 193.239.22.2 eq 80 host 192.168.1.100 eq 46153 deny ip any any
Again: Inspection Rules
If you dont specify a procotol to be inspected you will NOT get it passed. In my example I did not included ICMP so pinging a host in the internet will not bring us much:
CLIENT#ping 193.239.22.2 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 193.239.22.2, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
In short: ip inspect does only inspection on protocols you tell him to inspect. If you miss out something this will fall into the regular access-lists / filtering.
In my ICMP example you can either add ICMP to the protocol:
Router#conf term Enter configuration commands, one per line. End with CNTL/Z. Router(config)#ip inspect name MyFirewall icmp Router(config)#end
CLIENT#ping 193.239.22.2 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 193.239.22.2, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 24/59/160 ms
or extend/edit the access-list:
Router#sh access-lists inACL Extended IP access list inACL 10 deny ip any any (28 matches) Router#conf term Enter configuration commands, one per line. End with CNTL/Z. Router(config)#ip access-list extended inACL Router(config-ext-nacl)#5 permit icmp any any Router(config-ext-nacl)#end
CLIENT#ping 193.239.22.2 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 193.239.22.2, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 16/82/252 ms
Last words
Normally, if you just want to have a standard firewall / stateful configuration you add something like:
Router(config)#ip inspect name MyFirewall udp Router(config)#ip inspect name MyFirewall tcp Router(config)#ip inspect name MyFirewall icmp Router(config)#ip inspect name MyFirewall ftp Router(config)#ip inspect name MyFirewall <anyotherspecialprotocolyouneed>
One really last word: DoS Attacks
Cisco recommends that you first make changes to the global timeout and threshold values before configuring your inspection rules:
Router(config)# ip inspect tcp synwait-time seconds Router(config)# ip inspect tcp finwait-time seconds Router(config)# ip inspect tcp idle-time seconds Router(config)# ip inspect udp idle-time seconds Router(config)# ip inspect dns-timeout seconds
Then you set up connection thresholds which is quite similar to setting thresholds for TCP Intercept:
Router(config)# ip inspect max-incomplete high number Router(config)# ip inspect max-incomplete low number Router(config)# ip inspect one-minute high number Router(config)# ip inspect one-minute low number Router(config)# ip inspect tcp max-incomplete host number block-time minutes
A good example could be:
Router(config)# ip inspect tcp synwait-time 20 Router(config)# ip inspect tcp idle-time 60 Router(config)# ip inspect udp idle-time 20 Router(config)# ip inspect max-incomplete high 400 Router(config)# ip inspect max-incomplete low 300 Router(config)# ip inspect one-minute high 600 Router(config)# ip inspect one-minute low 500 Router(config)# ip inspect tcp max-incomplete host 300 block-time 0
Just make sure if you are modifiying the timeout and threshold values that you carefully monitor CBAC. Ensure that you’re not making the problem worse instead of fixing something. This is a real issue and risk.