Thursday, September 22, 2011

Zone-Based Firewall Policy (Filtering with IOS Part 8)

I have R1, R2, R3, R4 and R5. I want to use Zone-Based Firewall Policy to create a security policy that I can apply to R2.



I want R2's Fa0/0 and Fa0/1 interfaces to serve as the INSIDE interfaces, Se0/0/0 to serve as the EXTRANET interface, and Se0/1/0 to serve as the OUTSIDE interface. With the Fa0/0 and Fa0/1 interfaces in the same zone, I won't have to configure any rule allowing traffic between them, as interfaces in the same zone will allow traffic to pass by default. I am simulating a web server in the EXTRANET zone on R4. I want to allow HTTP and ICMP access from the INSIDE zone to the EXTRANET zone, as well as from the OUTSIDE zone to the EXTRANET zone. Additionally, I want the INSIDE zone to be able to telnet to R4. I want to allow access for TCP, UDP, TELNET, HTTP, and ICMP from the INSIDE zone to the OUTSIDE zone, but prevent access from downloading .exe files.

Like previous IP Inspect and TCP Intercept configurations, I want to use a parameter-map to control the timeout for TCP connections after a SYN packet and no further data to 5 seconds, the max-incomplete low of 5, and high of 10, with a one minute low of 10 and a high of 20.I want to rate limit traffic from the OUTSIDE to the web server on the EXTRANET zone to 128000 bytes per second.

When using Zone-Based Firewall, traffic directed to the router will be allowed by default, but I can limit this by applying a policy to a zone-pair between a specified source and the self zone. In my case, I want to allow the EIGRP routing protocol traffic along with ICMP to be allowed to any of R2's interfaces, except for the INSIDE interfaces, where I want to additionally allow telnet traffic for management.

All routers are running EIGRP with AS 1.

I'll start by creating the zones on R2.

R2(config)#zone security OUTSIDE
R2(config-sec-zone)#zone security INSIDE
R2(config-sec-zone)#zone security EXTRANET

On R4 I'll enable the HTTP server, set the ip http path, and create a user.

R4(config)#ip http server
R4(config)#ip http path flash:
R4(config)#username jason password cisco

On R2, I'll classify the traffic for the INSIDE and OUTSIDE to the EXTRANET zone

R2(config)#class-map type inspect match-any CMAP_TO_EXTRANET 
R2(config-cmap)#match protocol http
R2(config-cmap)#match protocol icmp

Since I want to also allow telnet to R4 on the EXTRANET from the INSIDE zone, I'll create another class-map to match this traffic.

R2(config-ext-nacl)#class-map type inspect match-any CMAP_INSIDE_TO_EXTRANET_MGMT
R2(config-cmap)#match protocol telnet

On R2, I'll classify the traffic for the INSIDE to OUTSIDE zones.

R2(config-if)#class-map type inspect match-any CMAP_INSIDE_TO_OUTSIDE
R2(config-cmap)#match protocol tcp
R2(config-cmap)#match protocol udp
R2(config-cmap)#match protocol telnet
R2(config-cmap)#match protocol icmp

In order to block .exe files from being downloaded, I will have to create a separate class-map which only specifies the http traffic.

R2(config)#class type inspect CMAP_INSIDE_TO_OUTSIDE_HTTP
R2(config-cmap)#match protocol http

In order to block .exe files from being downloaded, I will create a parameter-map matching the regex pattern for .exe.

R2(config)#parameter-map type regex PARAM_DROP_EXE
R2(config-profile)#pattern .*\.([Ee][Xx][Ee])

I'll create another parameter-map to help protect the web server in the EXTRANET zone from TCP related attacks.

R2(config)#parameter-map type inspect PARAM_PROTECT_TCP
R2(config-profile)#tcp synwait-time 5
R2(config-profile)#max-incomplete low 5 
R2(config-profile)#max-incomplete high 10
R2(config-profile)#one-minute low 10
R2(config-profile)#one-minute high 20 

I'll reference the regex parameter-map in a class.

R2(config)#class-map type inspect http CMAP_BLOCK_EXE
R2(config-cmap)#match request uri regex PARAM_DROP_EXE

From the OUTSIDE and EXTRANET zones I will limit traffic going to the self zone to routing protocol and ICMP traffic . I'll create an ACL to match the EIGRP traffic. Note:Some routing protocols can be matched directly within the class-map, others such as EIGRP require an ACL to be matched reference the EIGRP ACL and match the it in a class-map.

R2(config)#ip access-list extended ACL_EIGRP
R2(config-ext-nacl)#permit eigrp any any
R2(config-ext-nacl)#exit
R2(config)#class-map type inspect match-any CMAP_TO_SELF
R2(config-cmap)#match access-group name ACL_EIGRP 
R2(config-cmap)#match protocol icmp 

I'll also add an additional class-map to self for the INSIDE zone.

R2(config)#class-map type inspect match-any CMAP_INSIDE_TO_SELF
R2(config-cmap)#match access-group name ACL_EIGRP
R2(config-cmap)#match protocol icmp
R2(config-cmap)#match protocol telnet

At this point, all traffic should be classified.

Now, I'll create the policy-maps to define what should happen to the traffic.

Rate limiting can be done with QoS, but I'll apply a police statement to this policy map (type inspect) along with the PARAM_PROTECT_TCP parameter-map. This approach can be useful since once this is applied to a zone-pair, and it would automatically be in use if another interface were added to the OUTSIDE zone.

I'll start with INSIDE and OUTSIDE to EXTRANET.

R2(config)#policy-map type inspect PMAP_OUTSIDE_TO_EXTRANET
R2(config-pmap)#class type inspect CMAP_TO_EXTRANET 
R2(config-pmap-c)#inspect PARAM_PROTECT_TCP 
R2(config-pmap-c)#police rate 128000 burst 16000

I'll create another policy-map for the INSIDE to EXTRANET traffic. I could have assigned the same policy-map in use for the OUTSIDE to EXTRANET zones, but in this case, I want to create another policy-map and also pass telnet and EIGRP traffic from the INSIDE to EXTRANET zone.

R2(config)#policy-map type inspect PMAP_INSIDE_TO_EXTRANET
R2(config-pmap)#class type inspect CMAP_INSIDE_TO_EXTRANET_MGMT
R2(config-pmap-c)#inspect
R2(config-pmap-c)#class type inspect CMAP_TO_EXTRANET            
R2(config-pmap-c)#inspect

I'll create a a policy-map for INSIDE to OUTSIDE traffic, and call the class-maps I created for allowed traffic, and disallowed traffic. I'll start with creating a policy-map (type inspect http), and nest the class-map that was created to block .exe files, and set an action of reset. This will then be nested in the main policy-map for INSIDE to OUTSIDE traffic. It's important to understand the order that the "class type inspect" statements are added are the order that they are ran. Since http is a tcp protocol, if I add the class containing the "match protocol tcp" statement before the class containing the "service-policy http" statement, then it would be allowed instead of reset.

R2(config)#policy-map type inspect http PMAP_BLOCK_EXE
R2(config-pmap)#class type inspect http CMAP_BLOCK_EXE
R2(config-pmap-c)#reset
R2(config-pmap-c)#policy-map type inspect PMAP_INSIDE_TO_OUTSIDE
R2(config-pmap)#class type inspect CMAP_INSIDE_TO_OUTSIDE_HTTP
R2(config-pmap-c)#inspect 
R2(config-pmap-c)#service-policy http PMAP_BLOCK_EXE
R2(config-pmap)#class type inspect CMAP_INSIDE_TO_OUTSIDE
R2(config-pmap-c)#inspect

Now I'll create the policy maps for the self zone traffic.

R2(config)#policy-map type inspect PMAP_TO_SELF
R2(config-pmap)#class CMAP_TO_SELF
R2(config-pmap-c)#pass
R2(config-pmap-c)#policy-map type inspect PMAP_INSIDE_TO_SELF
R2(config-pmap)#class CMAP_INSIDE_TO_SELF

At this point, all traffic is classified, and policy-maps have been configured for all classes.

Now I'll create zone pairs and apply the respective policies. I'll create a zone-pair for INSIDE to EXTRANET, OUTSIDE to EXTRANET, INSIDE to OUTSIDE, INSIDE to self, EXTRANET to self, and OUTSIDE to self.

R2(config)#zone-pair security ZP_INSIDE_TO_EXTRANET source INSIDE destination EXTRANET
R2(config-sec-zone-pair)#service-policy type inspect PMAP_INSIDE_TO_EXTRANET
R2(config-sec-zone-pair)#exit
R2(config)#$zone-pair security ZP_OUTSIDE_TO_EXTRANET source OUTSIDE destination EXTRANET
R2(config-sec-zone-pair)#service-policy type inspect PMAP_OUTSIDE_TO_EXTRANET
R2(config-sec-zone-pair)#exit
R2(config)#zone-pair security ZP_INSIDE_TO_OUTSIDE source INSIDE destination OUTSIDE
R2(config-sec-zone-pair)#service-policy type inspect PMAP_INSIDE_TO_OUTSIDE
R2(config-sec-zone-pair)#exit
R2(config)#zone-pair security ZP_INSIDE_TO_SELF source INSIDE destination self 
R2(config-sec-zone-pair)#service-policy type inspect PMAP_INSIDE_TO_SELF
R2(config-sec-zone-pair)#exit
R2(config)#$zone-pair security ZP_EXTRANET_TO_SELF source EXTRANET destination self     
R2(config-sec-zone-pair)#service-policy type inspect PMAP_TO_SELF         
R2(config-sec-zone-pair)#exit
R2(config)#zone-pair security ZP_OUTSIDE_TO_SELF source OUTSIDE destination self
R2(config-sec-zone-pair)#service-policy type inspect PMAP_TO_SELF
R2(config-sec-zone-pair)#exit

Now that the zone-pairs have been created, I will assign the interfaces to their respective zones.

R2(config)#interface fa0/1
R2(config-if)#zone security INSIDE
R2(config-if)#exit
R2(config)#interface fa0/0
R2(config-if)#zone security INSIDE
R2(config-if)#exit
R2(config)#interface se0/0/0
R2(config-if)#zone security EXTRANET
R2(config-if)#exit
R2(config)#interface se0/1/0
R2(config-if)#zone security OUTSIDE
R2(config-if)#end
R2#

This completes the configuration.

Now I'll verify that the configuration is operational.

First I'll verify that the zones have been applied and the correct interfaces have been assigned

R2#show zone security
zone self
  Description: System defined zone


zone OUTSIDE
  Member Interfaces:
    Serial0/1/0


zone EXTRANET
  Member Interfaces:
    Serial0/0/0


zone INSIDE
  Member Interfaces:
    FastEthernet0/1
    FastEthernet0/0

Next, I'll verify that the zone-pairs exist, that the correct source and destination zones have been referenced, and that the correct service-policy has been applied to each pair.

R2#show zone-pair security 
Zone-pair name ZP_INSIDE_TO_EXTRANET
    Source-Zone INSIDE  Destination-Zone EXTRANET 
    service-policy PMAP_INSIDE_TO_EXTRANET
Zone-pair name ZP_OUTSIDE_TO_EXTRANET
    Source-Zone OUTSIDE  Destination-Zone EXTRANET 
    service-policy PMAP_OUTSIDE_TO_EXTRANET
Zone-pair name ZP_INSIDE_TO_OUTSIDE
    Source-Zone INSIDE  Destination-Zone OUTSIDE 
    service-policy PMAP_INSIDE_TO_OUTSIDE
Zone-pair name ZP_INSIDE_TO_SELF
    Source-Zone INSIDE  Destination-Zone self 
    service-policy PMAP_INSIDE_TO_SELF
Zone-pair name ZP_EXTRANET_TO_SELF
    Source-Zone EXTRANET  Destination-Zone self 
    service-policy PMAP_TO_SELF
Zone-pair name ZP_OUTSIDE_TO_SELF
    Source-Zone OUTSIDE  Destination-Zone self 
    service-policy PMAP_TO_SELF

I'll verify that all EIGRP neighborships still exist.

R2#show ip eigrp neighbors 
IP-EIGRP neighbors for process 1
H   Address                 Interface       Hold Uptime   SRTT   RTO  Q  Seq
                                            (sec)         (ms)       Cnt Num
0   10.1.12.1               Fa0/1             13 1d00h       3   200  0  9
3   10.1.25.5               Se0/1/0           13 1d00h       8   200  0  9
2   10.1.24.4               Se0/0/0          152 1d00h      55   330  0  5
1   10.1.23.3               Fa0/0             12 1d00h       9   200  0  6

Although there were no rules configured for the two inside interfaces to communication with each other, I'll verify that I can ping and telnet between them.

From R1 to R3:

R1#ping 10.1.23.3      


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.23.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
R1#telnet 10.1.23.3
Trying 10.1.23.3 ... Open


User Access Verification


Password: 
R3>exit


[Connection to 10.1.23.3 closed by foreign host]

From R3 to R1:

R3#ping 10.1.12.1  


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.12.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/3/4 ms
R3#telnet 10.1.12.1
Trying 10.1.12.1 ... Open


User Access Verification


Password: 
R1>

This works as expected.

Next I'll verify that the INSIDE to EXTRANET communication is working correctly. I should be able to ping and telnet to R4, and R5 should be able to ping, but NOT telnet. I'll use the loopback address to communicate to the web server on R4.

R1 to R4:

R1#ping 10.1.24.4


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.24.4, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 56/57/61 ms
R1#telnet 10.0.4.4 
Trying 10.0.4.4 ... Open


User Access Verification


Password: 
R4>

R5 to R4:

R5#ping 10.1.24.4  


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.24.4, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 68/71/72 ms
R5#telnet 10.0.4.4
Trying 10.0.4.4 ... 
% Connection timed out; remote host not responding

This works as expected, but I should be able to access the web service on R4 from R5. I'll test copying a .txt file, as well as a .exe file. Note that they will both be allowed as the configuration to block .exe files is not applied to this zone-pair.

R5#copy http://jason:cisco@10.0.4.4/test.txt null:
Loading http://***********@10.0.4.4/test.txt !
1784 bytes copied in 0.604 secs (2954 bytes/sec)
R5#
R5#copy http://jason:cisco@10.0.4.4/test.exe null:
Loading http://***********@10.0.4.4/test.exe !
51 bytes copied in 0.224 secs (228 bytes/sec)
R5#

Now I'll test from the INSIDE to the OUTSIDE. I should be able to gain access to the web server running on R5, but I should not be able to access the .exe file.

R1#ping 10.1.25.5


Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.1.25.5, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/15/16 ms
R1#copy http://jason:cisco@10.1.25.5/test.txt null:                  
Loading http://***********@10.1.25.5/test.txt !
2278 bytes copied in 0.252 secs (9040 bytes/sec)

This works as expected. Transferring a .exe file should result in an I/O error.

R1#copy http://jason:cisco@10.1.25.5/test.exe null:
%Error opening http://jason:cisco@10.1.25.5/test.exe (I/O error)

As mentioned previously in the policy-map for PMAP_INSIDE_TO_OUTSIDE, I could encounter an undesirable result if I ordered the classes differently. If I add the CMAP_INSIDE_TO_OUTSIDE_HTTP class after the CMAP_INSIDE_TO_OUTSIDE class, then the inspect statement under the CMAP_INSIDE_TO_OUTSIDE class would allow http traffic, including .exe files since I have tcp listed within that class. I'll change the order and see if I can copy the test.exe file.

R2(config-pmap)#exit
R2(config)#policy-map type inspect PMAP_INSIDE_TO_OUTSIDE
R2(config-pmap)#no class type inspect CMAP_INSIDE_TO_OUTSIDE_HTTP
R2(config-pmap)#class type inspect CMAP_INSIDE_TO_OUTSIDE_HTTP   
R2(config-pmap-c)#inspect
R2(config-pmap-c)#service-policy http PMAP_BLOCK_EXE
R2(config-pmap-c)#do show run | section policy-map type inspect PMAP_INSIDE_TO_OUTSIDE 
policy-map type inspect PMAP_INSIDE_TO_OUTSIDE
 class type inspect CMAP_INSIDE_TO_OUTSIDE
  inspect 
 class type inspect CMAP_INSIDE_TO_OUTSIDE_HTTP
  inspect 
  service-policy http PMAP_BLOCK_EXE
 class class-default
  drop

Note that the class CMAP_INSIDE_TO_OUTSIDE_HTTP is now ordered after the class CMAP_INSIDE_TO_OUTSIDE. Now I'll attempt to copy a .exe file to R1 from R5.

R1#copy http://jason:cisco@10.1.25.5/test.exe null:
Loading http://***********@10.1.25.5/test.exe !
2278 bytes copied in 0.240 secs (9492 bytes/sec)

It is allowed as expected.

I currently have a telnet session open initiated from R1 to R5. I want to view statistics related to this on the firewall. I'll use show policy-map type inspect zone-pair security PMAP_INSIDE_TO_OUTSIDE sessions:

R2#show policy-map type inspect zone-pair ZP_INSIDE_TO_OUTSIDE sessions


policy exists on zp ZP_INSIDE_TO_OUTSIDE
 Zone-pair: ZP_INSIDE_TO_OUTSIDE


  Service-policy inspect : PMAP_INSIDE_TO_OUTSIDE


    Class-map: CMAP_INSIDE_TO_OUTSIDE_HTTP (match-any)
      Match: protocol http
        1 packets, 24 bytes
        30 second rate 0 bps


   Inspect


    Class-map: CMAP_INSIDE_TO_OUTSIDE (match-any)
      Match: protocol tcp
        1 packets, 24 bytes
        30 second rate 0 bps
      Match: protocol udp
        0 packets, 0 bytes
        30 second rate 0 bps
      Match: protocol telnet
        0 packets, 0 bytes
        30 second rate 0 bps
      Match: protocol icmp
        0 packets, 0 bytes
        30 second rate 0 bps


   Inspect


      Number of Established Sessions = 1
      Established Sessions
        Session 66826980 (10.1.12.1:30755)=>(10.0.5.5:23) tcp SIS_OPEN
          Created 00:05:19, Last heard 00:03:06
          Bytes sent (initiator:responder) [49:1078]




    Class-map: class-default (match-any)
      Match: any 
      Drop
        0 packets, 0 bytes
R2#

I can see the related class-maps, and since there is a session established, I can see the source and destination with the indicator of SIS_OPEN (Stateful Inspection Subroutine or Session Inspection Subroutine.)





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