Wednesday, September 14, 2011

Context Based Access Control, feat. TCP Intercept (Filtering with IOS Part 6)



I have R1, R2, and R3, and I want to use CBAC to effectively help create a security policy that I can apply to R2.

I consider R2's fa0/1 the inside network and R2's s0/1/0 the outside network.

I want to use Context Based Access Control when allowing the inside segment access to services on the outside segment, and to inspect TCP, UDP, HTTP, Telnet, ICMP and TFTP traffic. I want to collect audit statistics on TFTP traffic and have a UDP session inactivity timeout of 20 seconds. For the HTTP inspected traffic I do not want to allow Java applets to be downloaded from R3 with the host address of 10.0.3.3. For Telnet traffic, I want to ensure traffic is inspected while using TCP port 33 to connect from R1 to R3 by adding to R2's port-maps. I want to allow the inside segment to receive responses when using traceroute. I will assume a maximum of 2000 sessions open concurrently, and will adjust the CBAC hash table from its default 1024, to 2048. I want to allow the outside segment access to TCP 80 on R1, allow my routing protocol, disallow ping responses, and I want to configure TCP intercept with CBAC.

Before I begin the CBAC configuration steps, I want to visit the TCP Intercept feature and verify its operation; as CBAC incorporates this feature into its operation.

The TCP intercept feature works as it's described; it intercepts TCP connections. In my scenario, R1 is hosting HTTP services, and R2 will be configured to intercept TCP SYN packets when R3 attempts to make a connection to R1. TCP intercept can be configured to be the middle man in the 3 way handshake, or observe the handshake process. In either case, I can configure R2 to drop half open connections by dropping the connection itself, or by sending reset (RST) messages on the protected server's behalf.

I'll configure R2 to protect the web server on R2, operate in intercept mode with a connection-timeout of 5 seconds. Additionally, I will set the router to begin dropping packets, oldest first, when maximum number of half open connections equals 10 and continue to drop until the half open connections reaches 5. Furthermore, I want to protect against SYN flood attacks by dropping SYN packets when the rate of 20 per minute occur, and to resume once that rate has lessened to 10 per minute.

R2(config)#access-list 101 permit ip any host 10.1.12.1
R2(config)#ip tcp intercept list 101
R2(config)#ip tcp intercept mode intercept 
R2(config)#ip tcp intercept connection-timeout 5 
R2(config)#ip tcp intercept max-incomplete low 5 high 10 
R2(config)#ip tcp intercept drop-mode oldest 
R2(config)#ip tcp intercept one-minute low 10 high 20

Note that ah ACL is required to identify traffic when using TCP intercept.

Now I'll debug ip tcp intercept on R2 and attempt to connect to R1 from R3 with telnet on TCP port 80.

R2#deb ip tcp intercept
TCP intercept debugging is on
R2#
*Sep 13 17:20:59.302: INTERCEPT: new connection (10.1.23.3:25978 SYN -> 10.1.12.1:80)
*Sep 13 17:20:59.302: INTERCEPT(*): (10.1.23.3:25978 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:20:59.310: INTERCEPT: 1st half of connection is established (10.1.23.3:25978 ACK -> 10.1.12.1:80)
*Sep 13 17:20:59.310: INTERCEPT(*): (10.1.23.3:25978 SYN -> 10.1.12.1:80)
*Sep 13 17:20:59.314: INTERCEPT: client packet dropped in SYNSENT (10.1.23.3:25978 -> 10.1.12.1:80)
*Sep 13 17:20:59.314: INTERCEPT: 2nd half of connection established  (10.1.23.3:25978 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:20:59.314: INTERCEPT(*): (10.1.23.3:25978 ACK -> 10.1.12.1:80)
*Sep 13 17:20:59.318: INTERCEPT(*): (10.1.23.3:25978 <- WINDOW 10.1.12.1:80)
*Sep 13 17:21:04.313: INTERCEPT: ESTAB timing out (10.1.23.3:25978 <-> 10.1.12.1:80)
*Sep 13 17:21:04.313: INTERCEPT(*): (10.1.23.3:25978 <- RST 10.1.12.1:80)
*Sep 13 17:21:04.313: INTERCEPT(*): (10.1.23.3:25978 RST -> 10.1.12.1:80)

It behaves as expected and resets the session at 5 seconds.

I'll prevent ACKs from returning to R3

R2(config)#access-list 102 deny tcp any any established 
R2(config)#access-list 102 permit ip any any           
R2(config)#int s0/1/0
R2(config-if)#ip access-group 102 in

I'll attept another connect to R1 from R3, and debug ip tcp intercept on R2.

*Sep 13 17:37:20.828: INTERCEPT: new connection (10.1.23.3:37362 SYN -> 10.1.12.1:80)
*Sep 13 17:37:20.832: INTERCEPT(*): (10.1.23.3:37362 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:37:21.828: INTERCEPT(*): SYNRCVD retransmit 1 (10.1.23.3:37362 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:37:23.828: INTERCEPT(*): SYNRCVD retransmit 2 (10.1.23.3:37362 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:37:27.828: INTERCEPT(*): SYNRCVD retransmit 3 (10.1.23.3:37362 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:37:35.827: INTERCEPT(*): SYNRCVD retransmit 4 (10.1.23.3:37362 <- ACK+SYN 10.1.12.1:80)
*Sep 13 17:37:51.826: INTERCEPT: SYNRCVD retransmitting too long (10.1.23.3:37362 <-> 10.1.12.1:80)
*Sep 13 17:37:51.826: INTERCEPT(*): (10.1.23.3:37362 <- RST 10.1.12.1:80)

R2 attepts to retransmit R1's SYN-ACK until the exponential timer expires when the connection is reset.

With that, I'll remove the previous ip tcp intercept commands, and move on to configure R2 as a stateful firewall with CBAC.

CBAC only inspects TCP and UDP traffic. If other services need to be filtered I must use an access-lists instead.

The difference between reflexive ACLs and CBAC is that reflexive ACLs rely on the return traffic being a mirror of the sent traffic, where CBAC will use an application inspection engine per application to inspect traffic, and is aware of the application's conversation.

I'll create an inspection rule called CBAC for TCP, UDP, HTTP, Telnet, and ICMP traffic. As mentioned before, since UDP is connectionless, there will be no FIN packet to finish sessions, so I'll configure a UDP session inactivity timeout of 20 seconds. Also, I will create an ACL to tie the HTTP inspection to allow Java applets from only the host address of 10.0.3.3.

R2(config)#access-list 10 permit host 10.0.3.3 
R2(config)#ip inspect name CBAC tcp
R2(config)#ip inspect name CBAC udp audit-trail on timeout 20
R2(config)#ip inspect name CBAC http java-list 10
R2(config)#ip inspect name CBAC telnet 
R2(config)#ip inspect name CBAC icmp 

As mentioned some telnet traffic could use destination TCP port 33, I will map TCP 33 to telnet so that it is inspected as well.

R2(config)#ip port-map telnet port 33
R2(config)#do show ip port-map | include user       
Default mapping:  telnet           tcp port 33              user defined

According to Cisco recommendations, I should try to maintain a 1:1 ratio between the number of sessions and the size of the hash table. By default there are 1024 buckets. Since I will have a maximum number of concurrent sessions of 2000, I will double the number of the default bucket size.

R2(config)#ip inspect hashtable-size 2048

I will create an ACL allowing TCP 80, UDP 520, time-exceeded, and port-unreachable icmp messages from the outside, apply it to the outside interface, and configure no ip unreachables.

R2(config)#ip inspect hashtable-size 2048 
R2(config)#ip access-list extended OUTSIDE_IN
R2(config-ext-nacl)#permit tcp any host 10.1.12.1 eq 80
R2(config-ext-nacl)#permit udp any host 10.1.23.2 eq 520
R2(config-ext-nacl)#permit icmp any any time-exceeded
R2(config-ext-nacl)#permit icmp any any port-unreachable
R2(config-ext-nacl)#int s0/1/0
R2(config-if)#ip access-group OUTSIDE_IN in
R2(config-if)#no ip unreachables 

CBAC has tcp intercept features. Similar to what I configured initially, I want to configure a connection-timeout of 5 seconds. Additionally, I will configure the router to drop sessions when the maximum number of half open connections equals 10 and continue to drop until the half open connections reaches 5. Furthermore, I want to protect against SYN flood attacks by dropping SYN packets when the rate of 20 per minute occur, and to resume once that rate has lessened to 10 per minute. Previously with tcp inspect, I was given the ability to choose how half open sessions were dropped, either oldest first or random. This is not configurable with CBAC. According to Cisco: "When the router's DoS counters exceed the default or configured values, the router will reset one old half-open connection for every new connection that exceeds the configured max-incomplete or one-minute high values, until the number of half-open sessions drops below the max-incomplete low values."

R2(config)#ip inspect tcp synwait-time 5
R2(config)#ip inspect max-incomplete low 5   
R2(config)#ip inspect max-incomplete high 10
R2(config)#ip inspect one-minute low 10 
R2(config)#ip inspect one-minute high 20

To verify that the inspection rule has been applied to to correct interface and direction, I will use show ip inspect interfaces.

R2#show ip inspect interfaces
Interface Configuration
 Interface Serial0/1/0
  Inbound inspection rule is not set
  Outgoing inspection rule is CBAC
    tcp alert is off audit-trail is off timeout 3600
    udp alert is off audit-trail is on timeout 20
    http java-list 10 alert is off audit-trail is off timeout 3600
    telnet alert is off audit-trail is off timeout 3600
    icmp alert is off audit-trail is off timeout 10
  Inbound access list is OUTSIDE_IN
  Outgoing access list is not set


R2#

I can also verify the configuration with show ip inspect config

R2#show ip inspect config 
Session audit trail is disabled
Session alert is disabled
one-minute (sampling period) thresholds are [10 : 20] connections
max-incomplete sessions thresholds are [5 : 10]
max-incomplete tcp connections per host is unlimited. Block-time 0 minute.
tcp synwait-time is 5 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 CBAC
    tcp alert is off audit-trail is off timeout 3600
    udp alert is off audit-trail is on timeout 20
    http java-list 10 alert is off audit-trail is off timeout 3600
    telnet alert is off audit-trail is off timeout 3600
    icmp alert is off audit-trail is off timeout 10

Note as also shown in the output of show ip inspect interfaces, ICMP has a timeout of 10 seconds.

I'll send a continous ping from R1 to R3.

R1#ping 10.1.23.3 rep 1000000                      


Type escape sequence to abort.
Sending 1000000, 100-byte ICMP Echos to 10.1.23.3, timeout is 2 seconds:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

With the pings sending, I will verify ICMP is being inspected on R2.

R2#show ip inspect sessions
Established Sessions
 Session 663100C8 (10.1.12.1:8)=>(10.1.23.3:0) icmp SIS_OPEN

I'll break the continuous ping, and after 10 seconds, the session is no longer open.

R2#show ip inspect sessions


R2#

Audit trail was configured on for TFTP. When I attempt to tftp a file from R3 to R1, I can see the AUDIT messages on R2.

*Sep 13 18:42:39.239: %FW-6-SESS_AUDIT_TRAIL_START: Start tftp session: initiator (10.1.12.1:56509) -- responder (10.1.23.3:69)
*Sep 13 18:43:09.320: %FW-6-SESS_AUDIT_TRAIL: Stop tftp session: initiator (10.1.12.1:56509) sent 45 bytes -- responder (10.1.23.3:69) sent 0 bytes








Part 1
Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8
Part 9
Part 10








No comments:

Post a Comment