Zone Based Firewall Configuration Example

Hello Andrew

Hmm, that’s interesting. I chatted with @ReneMolenaar about this one. He labbed it up with the configs you have in your post and it seems to be working correctly. You can even see the ISAKMP and ESP counters go up on the access list:

R2#show access-lists 
Extended IP access list ISAKMP_IPSEC
    10 permit udp any any eq isakmp (16 matches)
    20 permit ahp any any
    30 permit esp any any (38 matches)
    40 permit udp any any eq non500-isakmp

Do you want to recheck the status of your setup and do a couple of more tests to verify the behaviour of your topology? Let us know how you get along and we’ll be here if you need any additional help…

I hope this has been helpful!

Laz

Hi Laz,

Thanks for the assistance. Now taken this to Cisco Tac, as i am still fighting with this one.

How did you get the matches on the ACL? As this does not happen by default.

Hello Andrew

OK, let us know how you get along with TAC. Now in order to get the matches on the ACLs, simply add the log keyword at the end of each line of the ACL that you want to log matches to. So for your ACLs, you would do this:

ip access-list extended Bespoke_VPN
10 permit udp any any eq isakmp log
20 permit ahp any any log
30 permit esp any any log
40 permit udp any any eq non500-isakmp log

I hope this has been helpful!

Laz

Sorry Laz, something is not right here with the log command

For Normal ACL’s, the ‘log’ keyword will write the match to the syslogs, matches will be shown by default on a normal ACL.

However, If i try and match an ACL from within the Class-Map, i get the following message, if the keywork ‘log’ is attached to the ACL

% access-lists with 'log' keyword are not supported

Matches are not shown on ZBFW, instead i can see matches when issues show commands such as

show policy-map type inspect zone-pair x

Hello Andrew

Yes, you are correct, the log option is not supported for use with class-maps. By default, the ACL should display how many matches it has encountered. It also depends upon the platform and IOS version that you are using. Specifically, in the lab implementation, IOS version 15.9(3)M2 is being used on an IOSv device using CML. According to this Cisco Documentation:

Access control lists (ACLs) in a class map are used only for classification; the firewall does not display the packet count that matches the configured ACLs. Perfilter statistics is available in zone-based firewalls from Cisco IOS XE Release 3.13S and later releases.

So it looks like it ultimately boils down to the IOS version you are using. Depending on the version, it may or may not show matches. For more info on how IOS and IOS XE versions are related, take a look at this lesson:

I hope this has been helpful!

Laz

1 Like

Nice Lesson! Which are the Routers/IOS that support ZBF? I don’t find the zone command in the routers I use in GNS3.
Thx

Hello Giacomo

According to Cisco, the ZBF feature was introduced in IOS version 12.4(6)T. You can find out more info about it at the following two links:

In addition, you can check out Cisco’s feature navigator and search out the zone-based firewall feature to see what particular platforms support it.

I hope this has been helpful!

Laz

I’m looking to implement IPv6 on a C1111-4P acting as CPE/FTTH router. This would require me to implement stateful firewalling as a simple NAT overflow setup like with IPv4 will not suffice.

So far I’ve come up with the following config:

class-map type inspect match-any SP_LAN-TO-WAN
 match protocol tcp
 match protocol udp
 match protocol icmp
!
policy-map type inspect PM_LAN-TO-WAN
 class type inspect SP_LAN-TO-WAN
  inspect
 class class-default
!
zone security LAN
zone security WAN
zone-pair security LAN-TO-WAN source LAN destination WAN
 description LAN-TO-WAN TRAFFIC
 service-policy type inspect PM_LAN-TO-WAN
zone-pair security WAN-TO-LAN source WAN destination LAN
 description WAN-TO-LAN TRAFFIC
! 

interface GigabitEthernet0/0/0
 description outside
 ip nat outside
 zone-member security WAN
!

interface GigabitEthernet0/0/1
 description inside
 ip nat inside
 zone-member security LAN
!

The goal is to simply allow all normal traffic from LAN to WAN. Is this the way to go or is there a batter way to match “all traffic” instead of matching on tcp/udp/icmp ?

It seems enabling ZBFW with the config above reduces the throughput with ~ 20%. And during some iperf tests the following message is logged:

> %IOSXE_QFP-2-LOAD_EXCEED: Slot: 0, QFP:0, Load 100% exceeds the setting threshold 80%.
> 5 secs traffic rate on QFP: Total Input: 64546 pps (64.5 kpps), 730304048 bps (730.3 mbps),  Total Output: 64447 pps (64.4 kpps), 732756136 bps (732.8 mbps).

Hello Fabian

Your configuration seems to be mostly correct for stateful firewalling using ZBF. The class-map you have created is matching TCP, UDP and ICMP protocols, which should cover most of the traffic.

However, if you want to match all traffic, you can modify your class-map to match all IP traffic instead, like this:

class-map type inspect match-any SP_LAN-TO-WAN
 match protocol ip
!

This will match all IP traffic, not just TCP, UDP and ICMP.

Regarding the performance issue, ZBF can indeed introduce some overhead as it requires more processing power to inspect packets. The message you’re seeing indicates that the router’s CPU is reaching its limit, and this is likely the reason for your decrease in throughput. You might want to consider upgrading your hardware if you’re pushing a lot of traffic through the router and need to use ZBF.

Alternatively, you could try to optimize your policy-map to reduce the CPU load. For example, you could try to limit the inspection to only the traffic you’re really interested in, or you could try to use the ‘pass’ action for some traffic instead of ‘inspect’.

Lastly, I would recommend you monitor the CPU usage regularly and during different times of the day to get a better understanding of the load on the router and what kinds of traffic patterns are causing this excess usage. This can help you to better plan for capacity and possible hardware upgrades. Let us know how you get along!

I hope this has been helpful!

Laz

1 Like

I recently passed my CCNA with great help from network lessons thanks, continuing on with my studies and working towards CCNP.

Policy Map type inspect INTERNET-TO-SELF-POLICY
Class GRE-IN-CLASS
Pass
Class INTERNET-TO-SELF-CLASS
Inspect
Class class-default
Drop log

Could someone help me explain why the policy-map above passes GRE and the one below will not, but also does not show dropped packets

the class map for GRE-TO-SELF matches ACL - permit GRE host a.a.a.a host b.b.b.b.b
the classmap for INTERNET-TO-SELF matches ACL - permit ip host a.a.a.a b.b.b.b

is the permit ip a.a.a.a matching part of the GRE in the INTERNET-TO-SELF-CLASS but failing to inspect due to GRE being stateless ? in the example below

  Policy Map type inspect INTERNET-TO-SELF-POLICY
    Class INTERNET-TO-SELF-CLASS
      Inspect
Class GRE-IN-CLASS
      Pass
    Class class-default
      Drop log

Hello Michael

The order of class maps within a policy map can significantly impact the behavior of your Cisco IOS router’s zone-based firewall, especially when dealing with different types of traffic such as GRE and IP. The key here is understanding how the Cisco IOS processes these class maps and the traffic that matches them.

In the first policy map, the GRE traffic is explicitly allowed to pass before any inspection is applied to other traffic. This is because the GRE-IN-CLASS is matched first, and the PASS action associated with it is immediately applied to GRE traffic between hosts a.a.a.a and b.b.b.b. This ensures GRE packets are not subject to deep packet inspection or any other processing that might otherwise be applied to the traffic in INTERNET-TO-SELF-CLASS, which is subjected to inspection.

In the second policy map, the INTERNET-TO-SELF-CLASS is matched and inspected before GRE-IN-CLASS gets a chance to be processed. Because the GRE packets are indeed IP packets, they are matched by the INTERNET-TO-SELF-CLASS and may be inadvertently affected by these inspections. Even though there’s a subsequent class map intended to simply pass GRE traffic, the initial inspection could disrupt GRE communication due to the processing and potential modifications or delays imposed on the inspected traffic. GRE traffic, therefore, might not even reach the point where it matches the GRE-IN-CLASS class map, as it could be dropped or delayed in a way that affects its delivery.

To see what packets are passed, you can try issuing the ip inspect log drop-pkt command to log any packets that are dropped. That way you can see which class map is actually doing the dropping and why. Let us know how you get along!

I hope this has been helpful!

Laz

Thank you for the detailed explanation, I will do some more testing and and come back to you.

Michael

1 Like

Hello! My first post but man alive, you ever google stuff and no one ever gives you answers? This place does. Amazing.
I’m gonna paste my ISRC1111 config but my focal point is either my ACL’s are wrong or it just is not enforcing them. I’ll try to simplify. DMZ is 192.168.10.179 and INSIDE is 192.168.1.181. DMZ should have NO access to this host, and yet it can mount its (192.168.2.181) SMB. Also it can access any port on any host (among 5 other vlans). So really nothing is being implemented. Suggestions?

version 17.13
!
hostname HoM
!
boot-start-marker
boot system bootflash:c1100-universalk9.17.13.01a.SPA.bin
boot-end-marker
!
!
no aaa new-model
!
ip vrf mgmt
!
ip name-server 205.171.3.65 205.171.2.65
no ip domain lookup
!
!
no ip igmp snooping
login on-success log
!
!
subscriber templating
!
!
vtp domain ''
vtp mode transparent
!
!
!
no license feature hseck9
license udi pid C1111-8PLTEEAWB sn FGL223493AJ
license smart url https://smartreceiver.cisco.com/licservice/license
license smart url smart https://smartreceiver.cisco.com/licservice/license
license smart transport smart
license smart usage interval 365
memory free low-watermark processor 71826
!
spanning-tree extend system-id
!
!
redundancy
 mode none
!
!
vlan internal allocation policy ascending
!
vlan 8-9
!
vlan 10
 name DMZ
!
!
class-map type inspect match-all INSIDE-TO-OUTSIDE-CLASS
 match access-group name INSIDE-TO-OUTSIDE
class-map type inspect match-all OUTSIDE-TO-INSIDE-CLASS
 match access-group name OUTSIDE-TO-INSIDE
class-map type inspect match-all INSIDE-TO-DMZ-CLASS
 match access-group name INSIDE-TO-DMZ
class-map type inspect match-all DMZ-TO-INSIDE-CLASS
 match access-group name DMZ-TO-INSIDE
class-map type inspect match-all OUTSIDE-TO-DMZ-CLASS
 match access-group name OUTSIDE-TO-DMZ
class-map type inspect match-all DMZ-TO-OUTSIDE-CLASS
 match access-group name DMZ-TO-OUTSIDE
!
policy-map type inspect INSIDE-TO-DMZ-POLICY
 class type inspect INSIDE-TO-DMZ-CLASS
  pass
 class class-default
  drop log
policy-map type inspect INSIDE-TO-OUTSIDE-POLICY
 class type inspect INSIDE-TO-OUTSIDE-CLASS
  inspect
 class class-default
  drop log
policy-map type inspect DMZ-TO-OUTSIDE-POLICY
 class type inspect DMZ-TO-OUTSIDE-CLASS
  inspect
 class class-default
  drop log
policy-map type inspect OUTSIDE-TO-INSIDE-POLICY
 class type inspect OUTSIDE-TO-INSIDE-CLASS
  pass
 class class-default
  drop log
policy-map type inspect OUTSIDE-TO-DMZ-POLICY
 class type inspect OUTSIDE-TO-DMZ-CLASS
  inspect
 class class-default
  drop log
policy-map type inspect DMZ-TO-INSIDE-POLICY
 class type inspect DMZ-TO-INSIDE-CLASS
  pass
 class class-default
  drop log
!
zone security INSIDE
zone security OUTSIDE
zone security DMZ
zone-pair security DMZ-TO-IN source DMZ destination INSIDE
 service-policy type inspect DMZ-TO-INSIDE-POLICY
zone-pair security DMZ-TO-OUT source DMZ destination OUTSIDE
 service-policy type inspect DMZ-TO-OUTSIDE-POLICY
zone-pair security IN-TO-DMZ source INSIDE destination DMZ
 service-policy type inspect INSIDE-TO-DMZ-POLICY
zone-pair security IN-TO-OUT source INSIDE destination OUTSIDE
 service-policy type inspect INSIDE-TO-OUTSIDE-POLICY
zone-pair security OUT-TO-DMZ source OUTSIDE destination DMZ
 service-policy type inspect OUTSIDE-TO-DMZ-POLICY
zone-pair security OUT-TO-IN source OUTSIDE destination INSIDE
 service-policy type inspect OUTSIDE-TO-INSIDE-POLICY
!
!
interface GigabitEthernet0/0/0
 description WAN
 no ip address
 no ip redirects
 no ip unreachables
 no ip proxy-arp
 ip mtu 1460
 zone-member security OUTSIDE
 ip tcp adjust-mss 1412
 negotiation auto
 no cdp enable
 pppoe enable group global
 pppoe-client dial-pool-number 1
!
interface GigabitEthernet0/0/1
 no ip address
 negotiation auto
!
interface GigabitEthernet0/1/0
 switchport mode access
!
interface GigabitEthernet0/1/1
 shutdown
!
interface GigabitEthernet0/1/2
 shutdown
!
interface GigabitEthernet0/1/3
 shutdown
!
interface GigabitEthernet0/1/4
 description ceyea
 switchport access vlan 10
 switchport mode access
 zone-member security DMZ
 spanning-tree portfast
!
interface GigabitEthernet0/1/5
 description FPR-WAN
 switchport access vlan 8
 switchport mode access
 zone-member security INSIDE
 spanning-tree portfast
!
interface GigabitEthernet0/1/6
 description Management
 switchport
 switchport access vlan 9
 switchport mode access
 spanning-tree portfast
!
interface GigabitEthernet0/1/7
 switchport
 shutdown
!
interface Vlan1
 description ISR default LAN
 ip address 192.168.20.1 255.255.255.0
 ip nat inside
 no ip virtual-reassembly
!
interface Vlan8
 description Link _To_FPR
 ip address 172.16.1.1 255.255.255.0
 ip nat inside
!
interface Vlan9
 description management
 ip vrf forwarding mgmt
 ip address 10.0.0.1 255.255.255.0
!
interface Vlan10
 description DMZ
 ip address 192.168.10.1 255.255.255.0
!
interface Dialer1
 mtu 1492
 ip address negotiated
 no ip redirects
 ip mtu 1460
 ip nat outside
 encapsulation ppp
 ip tcp adjust-mss 1412
 dialer pool 1
 dialer idle-timeout 0
 dialer persistent
 dialer-group 1
 no cdp enable
 ppp authentication chap pap callin
 ppp ipcp dns request
 ppp ipcp route default
!
ip forward-protocol nd
no ip http server
ip http authentication local
ip http secure-server
ip http secure-trustpoint TP-self-signed-4284067838
!
ip nat translation tcp-timeout 600
ip nat translation udp-timeout 300
ip nat translation syn-timeout 5
ip nat translation dns-timeout 10
ip nat translation icmp-timeout 30
ip nat translation max-entries 200000
ip nat pool 177 207.108.121.177 207.108.121.177 prefix-length 30
ip nat pool 178 207.108.121.178 207.108.121.178 prefix-length 30
ip nat pool 179 207.108.121.179 207.108.121.179 prefix-length 30
ip nat pool 182 207.108.121.182 207.108.121.182 prefix-length 30
ip nat pool 181 207.108.121.181 207.108.121.181 prefix-length 30
ip nat pool 180 207.108.121.180 207.108.121.180 prefix-length 30
ip nat inside source static tcp 192.168.10.179 22 207.108.121.179 22 extendable
ip nat inside source static tcp 192.168.1.180 25 207.108.121.180 25 extendable
ip nat inside source static tcp 192.168.1.180 993 207.108.121.180 993 extendable
ip nat inside source static tcp 192.168.1.180 2280 207.108.121.180 2280 extendable
ip nat inside source static tcp 192.168.2.181 80 207.108.121.181 80 extendable
ip nat inside source static tcp 192.168.2.181 443 207.108.121.181 443 extendable
ip nat inside source list 1 interface Dialer1 overload
ip nat inside source list 4 pool 179 overload
ip nat inside source list 5 pool 178 overload
ip nat inside source list 6 pool 182 overload
ip nat inside source list 7 pool 177 overload
ip nat inside source list 8 pool 181 overload
ip nat inside source list 9 pool 180 overload
ip route 0.0.0.0 0.0.0.0 Dialer1
ip route 192.168.1.0 255.255.255.0 172.16.1.2
ip route 192.168.2.0 255.255.255.0 172.16.1.2
ip route 192.168.3.0 255.255.255.0 172.16.1.2
ip route 192.168.4.0 255.255.255.0 172.16.1.2
ip route 192.168.5.0 255.255.255.0 172.16.1.2
ip route 192.168.6.0 255.255.255.0 172.16.1.2
ip route vrf mgmt 192.168.5.0 255.255.255.0 10.0.0.3
ip ssh bulk-mode 131072
!
ip access-list extended DMZ-TO-INSIDE
 10 permit tcp 192.168.10.0 0.0.0.255 host 192.168.2.181 eq 22
ip access-list extended DMZ-TO-OUTSIDE
 10 permit ip 192.168.0.0 0.0.255.255 any
ip access-list extended INSIDE-TO-DMZ
 10 permit tcp 192.168.5.0 0.0.0.255 host 192.168.10.179 eq smtp
 20 permit tcp 192.168.5.0 0.0.0.255 host 192.168.10.179 eq 22
ip access-list extended INSIDE-TO-OUTSIDE
 10 permit ip 192.168.1.0 0.0.0.255 any
 20 permit ip 192.168.2.0 0.0.0.255 any
 30 permit ip 192.168.3.0 0.0.0.255 any
 40 permit ip 192.168.4.0 0.0.0.255 any
 50 permit ip 192.168.5.0 0.0.0.255 any
 60 permit ip 192.168.6.0 0.0.0.255 any
ip access-list extended OUTSIDE-TO-DMZ
 10 permit tcp host 192.168.10.179 any eq smtp
 20 permit tcp host 192.168.10.179 any eq 22
ip access-list extended OUTSIDE-TO-INSIDE
 10 permit icmp any 192.168.0.0 0.0.255.255
 20 permit tcp host 192.168.1.180 any eq smtp
 30 permit tcp host 192.168.1.180 any eq 2280
 40 permit tcp host 192.168.2.181 any eq 443
 50 permit tcp host 192.168.2.181 any eq www
!
ip access-list standard 1
 10 deny 192.168.8.0 0.0.0.255
 20 permit 172.16.1.0 0.0.0.255
ip access-list standard 4
 10 permit 192.168.3.0 0.0.0.255
ip access-list standard 5
 10 permit 192.168.4.0 0.0.0.255
ip access-list standard 6
 10 permit 192.168.5.0 0.0.0.255
ip access-list standard 7
 10 permit 192.168.6.0 0.0.0.255
ip access-list standard 8
 10 permit 192.168.2.0 0.0.0.255
ip access-list standard 9
 10 permit 192.168.1.0 0.0.0.255
dialer-list 1 protocol ip permit
!

Hello Matthew

Let’s isolate the configurations that directly affect the specific transaction that you described in your post, that is the communication between the 192.168.10.179 device in the DMZ, and the 192.168.1.181 host on the INSIDE network:

Here’s your access list that matches the traffic from the DMZ network to the specific host on the INSIDE network:

ip access-list extended DMZ-TO-INSIDE
 10 permit tcp 192.168.10.0 0.0.0.255 host 192.168.2.181 eq 22

Here’s the class map that references that ACL to match traffic:

class-map type inspect match-all DMZ-TO-INSIDE-CLASS
 match access-group name DMZ-TO-INSIDE

Here’s the policy map that references the class map:

policy-map type inspect DMZ-TO-INSIDE-POLICY
 class type inspect DMZ-TO-INSIDE-CLASS
  pass
 class class-default
  drop log

Finally, here’s the zone pair that references that policy map:

zone-pair security DMZ-TO-IN source DMZ destination INSIDE
 service-policy type inspect DMZ-TO-INSIDE-POLICY

Based on the policy map, anything that matches the ACL will be passed, but everything else should indeed be dropped. Only an SSH session (TCP port 22) should be allowed. You have the drop keyword in the class-default of the policy map, so you should be OK.

So at first glance, I don’t see the reason for the behavior. I suggest you take a look at this lesson first:

Then you can use some of the verification and debugging parameters to examine your traffic to see where it is going. The show policy-map type inspect zone-pair command is useful. Also, you can use some of the following debugs:

  • debug policy-firewall events
  • debug ip packet detail access-list <acl number>
  • debug ip inspect detail

I hope this will help you to get a start on things. Let us know how you get along and how we can be of further help.

I hope this has been helpful!

Laz