Saturday 7 May 2011

IOS Firewall (CBAC)

I think of CBAC as "ip inspect" because the majority of commands related to this technology piece start with this string.  To me it seems to be a more intelligent form of reflexive access lists as it can look in applications rather than only tracking port numbers of a conversation. 

You can get alarming and audit messages so its helpful in tracking issues and checking policy conformance and troubleshooting.

Note that fragmentation can be an issue for the IOS Firewall, so "ip virtual-reassembly" on the interface is a good idea, unlike NAT it is not enabled by default.

To configure CBAC - an extended ACL on the inbound interface that pretty much blocks everything is required, CBAC traffic that is allowed outbound will have the return path open via an invisible entry in the inbound ACL (sh ip inspect session).  An Audit trail can show when a conversation starts, stops and how much data was transferred.

Below are some basic configurations, with the topology as:

R4 is acting as a host inside the LAN
R5 is acting as my border router with a BGP peering with R6
R6 is acting as the service provider/internet


Below are our starting configurations with CBAC

R4
hostname R4
no ip routing
interface FastEthernet0/0
 ip address 192.168.101.4 255.255.255.0
!
ip default-gateway 192.168.101.5

R5
hostname R5
interface Loopback0
 ip address 5.5.5.5 255.255.255.255
!
interface FastEthernet0/0
 description R6 Fa0/1
 ip address 192.168.56.5 255.255.255.0
!
interface FastEthernet0/1
 description R4 Fa0/0
 ip address 192.168.101.5 255.255.255.0
!
router bgp 64512
 bgp router-id 5.5.5.5
 no bgp default ipv4-unicast
 bgp log-neighbor-changes
 neighbor 192.168.56.6 remote-as 65535
 !
 address-family ipv4
  redistribute connected metric 20 route-map Local
  neighbor 192.168.56.6 activate
  no auto-summary
  no synchronization
 exit-address-family
!
route-map Local permit 10
 match interface Loopback0 FastEthernet0/1

R6
hostname R6
aaa new-model
aaa authentication login default none
aaa authentication enable default none
ip http server
interface Loopback0
 ip address 6.6.6.6 255.255.255.255
!
interface FastEthernet0/1
 ip address 192.168.56.6 255.255.255.0
!
router bgp 65535
 no bgp default ipv4-unicast
 bgp log-neighbor-changes
 neighbor 192.168.56.5 remote-as 64512
 !
 address-family ipv4
  neighbor 192.168.56.5 activate
  neighbor 192.168.56.5 default-originate
  no auto-summary
  no synchronization
 exit-address-family
!

So in this example we are going to be using the IOS firewall on R5's interface facing R6

First we're going to set up the applications we're going to inspect and allow through the network

R5(config)#ip inspect name StuffAllowed telnet alert on audit-trail on
R5(config)#ip inspect name StuffAllowed icmp router-traffic
R5(config)#ip inspect name StuffAllowed http alert on
R5(config)#ip inspect name StuffAllowed dns

the "router-traffic" keyword means that router originated or terminated traffic is included in inspection, normally only traffic flowing through the router is considered.

Now we'll set up some access-lists, this is somewhat similar to reflexive access-lists where the inbound entry will have pinholes matching the outbound sessions going through.  In this case, we're going to allow the internet to ping our WAN interface, allow our BGP peering with R6 and block anything else.

R5(config)#ip access-list extended FW-IN
R5(config-ext-nacl)#permit icmp any host 192.168.56.5
R5(config-ext-nacl)#permit tcp host 192.168.56.6 host 192.168.56.5 eq bgp
R5(config-ext-nacl)#deny ip any any log

Now we apply the access-list for inbound traffic, inspect outbound traffic to enable pinholes on return and we need to make sure we have virtual-reassembly turned on so the firewall can deal with ip fragments:

R5(config-ext-nacl)#interface FastEthernet0/0
R5(config-if)#ip access-group FW-IN in
R5(config-if)#ip inspect StuffAllowed out
R5(config-if)#ip virtual-reassembly

Let's give it a test R4 telnetting to R6 Lo0

R4#telnet 6.6.6.6
Trying 6.6.6.6 ... Open

R6>sh users
    Line       User       Host(s)              Idle       Location
* 98 vty 0                idle                 00:00:00 192.168.101.4

  Interface    User               Mode         Idle     Peer Address

R6>exit

[Connection to 6.6.6.6 closed by foreign host]

Good, since we had auditing turned on for telnet, we should have a record of the session on R5

R5#
*Mar  1 00:29:49.655: %FW-6-SESS_AUDIT_TRAIL_START: Start telnet session: initiator (192.168.101.4:22391) -- responder (6.6.6.6:23)
*Mar  1 00:30:00.611: %FW-6-SESS_AUDIT_TRAIL: Stop telnet session: initiator (192.168.101.4:22391) sent 40 bytes -- responder (6.6.6.6:23) sent 267 bytes

Lets try a basic http session (we can do this by telnetting to port 80 of R6 and typing "GET / HTTP/1.0" to simulate a web browser trying to get the front page)

R4>do telnet 6.6.6.6 80
Trying 6.6.6.6, 80 ... Open
GET / HTTP/1.0

HTTP/1.1 401 Unauthorized
Date: Fri, 01 Mar 2002 02:03:20 GMT
Server: cisco-IOS
Accept-Ranges: none
WWW-Authenticate: Basic realm="level_15_access"

[Connection to 6.6.6.6 closed by foreign host]

Okay - that works, the response is saying that we're not allowed in because we have authenticated into the web interface but that's ok for this test, now time to play with the application firewall functionality. This is where the real difference between reflexive acls and CBAC come together.  The application firewall allows us to check whether the conversation using the ports associated with the protocol are actually the protocol itself and can do things like check that protocol level messages are valid or even filter on certain objects (such as filtering file types)

For the example here we're just going to ensure that we're following strict HTTP messages and will drop the session and generate a log message

R5(config)#appfw policy-name HTTPcontrol
R5(cfg-appfw-policy)#application http
R5(cfg-appfw-policy-http)#strict-http action alarm reset
R5(cfg-appfw-policy-http)#port-misuse default action reset

Then we just add it to our ip inspect definition

R5(cfg-appfw-policy-http)#ip inspect name StuffAllowed appfw HTTPcontrol

And check the overall configuration

R5(config)#do sh 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 StuffAllowed
    icmp alert is on audit-trail is off timeout 10
 inspection of router local traffic is enabled
    dns alert is on audit-trail is off timeout 30
    telnet alert is on audit-trail is on timeout 3600
    Application Policy name HTTPcontrol
      Application http
        strict-http action reset alarm
        port-misuse default action reset

Interface Configuration
 Interface FastEthernet0/0
  Inbound inspection rule is not set
  Outgoing inspection rule is StuffAllowed
    icmp alert is on audit-trail is off timeout 10
 inspection of router local traffic is enabled
    dns alert is on audit-trail is off timeout 30
    telnet alert is on audit-trail is on timeout 3600
    Application Policy name HTTPcontrol
      Application http
        strict-http action reset alarm
        port-misuse default action reset
  Inbound access list is FW-IN
  Outgoing access list is not set


So Let's try with an improper http message type by typing "123 PROTOCOL VIOLATION TEST"

R4(config)#do telnet 6.6.6.6 80
Trying 6.6.6.6, 80 ... Open
123 PROTOCOL VIOLATION TEST
[Connection to 6.6.6.6 closed by foreign host]

Well we can see that the session was closed without a response - what did R5 say?

R5#
*Mar  1 02:12:20.071: %APPFW-4-HTTP_STRICT_PROTOCOL: Sig:15 HTTP protocol violation detected - Reset -  HTTP Protocol not detected from 192.168.101.4:51629 to 6.6.6.6:80

So it appears to be blocking improper HTTP syntax.  Let's confirm it works ok with proper protocol usage

R4(config)#do telnet 6.6.6.6 80
Trying 6.6.6.6, 80 ... Open
GET / HTTP/1.0

HTTP/1.1 401 Unauthorized
Date: Fri, 01 Mar 2002 02:14:12 GMT
Server: cisco-IOS
Accept-Ranges: none
WWW-Authenticate: Basic realm="level_15_access"

401 Unauthorized

[Connection to 6.6.6.6 closed by foreign host]

Yep, no problem here.

Next we can play around with URL Filtering, for this example we're going to allow access to 6.6.6.6 (R6 Lo) but not to 192.168.56.6 (R6 Fa0/1)

R5(config)#ip urlfilter exclusive-domain permit 6.6.6.6
R5(config)#ip urlfilter exclusive-domain deny 192.168.56.6
R5(config)#ip urlfilter audit-trail

Let's try 192.168.56.6 since that should be blocked

R4#telnet 192.168.56.6 80
Trying 192.168.56.6, 80 ... Open
GET / HTTP/1.0
HTTP/1.1 403 Forbidden
Server: IOS Firewall HTTP/1.1
Content-type: text/html
Connection: close

<html>
      <head>
            <title>Forbidden</title></head>
                                           <body bgcolor="#ffffff">
                                                                   <center><h1><font color="#ff0000">HTTP Error 403 - Forbidden</font></h1>
                                                                                                                                           <b>You do not have permission to access the document or program you requested.
                 </b></center>
                              </body></html>


[Connection to 192.168.56.6 closed by foreign host]

We can see that we recieved a message back not allowing us to R6 Fa0/1 and we can see the log entry on R5 confirming this occurred as well.

R5#
*Mar  1 02:21:01.967: %URLF-4-SITE_BLOCKED: Access denied for the site '192.168.56.6', client 192.168.101.4:59608 server 192.168.56.6:80


Lets verify that going to R6 Lo0 is ok:

R4#telnet 6.6.6.6 80
Trying 6.6.6.6, 80 ... Open
GET / HTTP/1.0

HTTP/1.1 401 Unauthorized
Date: Fri, 01 Mar 2002 02:23:05 GMT
Server: cisco-IOS
Accept-Ranges: none
WWW-Authenticate: Basic realm="level_15_access"

401 Unauthorized

[Connection to 6.6.6.6 closed by foreign host]

R5#
*Mar  1 02:23:09.271: %URLF-6-SITE_ALLOWED: Client 192.168.101.4:23109 accessed server 6.6.6.6:80


This blog entry has really only scratched the surface as to what the IOS firewall can do but it shows some of the extra functionality within IOS

1 comment: