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

Hello, everyone.

What exactly is the difference between normal/class policy maps and those that use type inspect?

I understand that the second option is used with the ZBFW configuration on cisco IOS routers. What exactly does the type inspect indicate, though?

Also, I have the same topology as Rene:

R2(config)#zone security LAN
R2(config)#zone security WAN

R2(config-if)#int G0/0
R2(config-if)#zone-member security LAN
R2(config-if)#int G0/1
R2(config-if)#zone-member security WAN

R2(config)#ip access-list extended ANY
R2(config-ext-nacl)#permit ip any any

R2(config)#class-map type inspect ANY
R2(config-cmap)#match access-group name ANY

R2(config)#policy-map type inspect ANY
R2(config-pmap)#class ANY
R2(config-pmap-c)#inspect

R2(config)#zone-pair security LAN-TO-WAN source LAN destination WAN
R2(config-sec-zone-pair)#service-policy type inspect ANY

I can ping from R1 to R3

R1(config-if)#do ping 192.168.23.3 repeat 1000
Type escape sequence to abort.
Sending 1000, 100-byte ICMP Echos to 192.168.23.3, timeout is 2 seconds:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

And while that ping is active, I can ping from R3 to R1

R3#ping 192.168.12.1 repeat 10
Type escape sequence to abort.
Sending 10, 100-byte ICMP Echos to 192.168.12.1, timeout is 2 seconds:
...!!!!!!!

Any idea why? I understand that the router will inspect the ICMP request, allow it to pass, and create some rules for the replies, however, this allows R3 to also initiate ICMP requests to R1 until some timeout for that flow expires I suppose.

If I try it a minute later, it doesn’t work of course, it only works when R1 is pinging R3 or a few seconds after the ping ends.

R3#ping 192.168.12.1 repeat 10
Type escape sequence to abort.
Sending 10, 100-byte ICMP Echos to 192.168.12.1, timeout is 2 seconds:
....

It doesn’t of course work with protocols like Telnet

R1#telnet 192.168.23.3
Trying 192.168.23.3 ... Open

**************************************************************************
* IOSv is strictly limited to use for evaluation, demonstration and IOS  *
* education. IOSv is provided as-is and is not supported by Cisco's      *
* Technical Advisory Center. Any use or disclosure, in whole or in part, *
* of the IOSv Software or Documentation to any third party for any       *
* purposes is expressly prohibited except as otherwise authorized by     *
* Cisco in writing.                                                      *
**************************************************************************

User Access Verification

Password:
R3#telnet 192.168.12.1
Trying 192.168.12.1 ...

What could be causing this for ICMP? Does the reply rule only work on an IP-address basis? Does R1 not know that R3 is actually initiating the ping and not responding to the ping initiated by R1? :smiley:

Next, what exactly does this value indicate? (The 2:0). When a packet is inspected via a firewall (or a cisco router :smiley:), the control plane is also involved, or not? So this basically says that 2 packets were process-switched.

policy exists on zp LAN-TO-WAN
  Zone-pair: LAN-TO-WAN 

  Service-policy inspect : ONE

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

   Inspect
        Packet inspection statistics [process switch:fast switch]
        tcp packets: [2:0]

And one more thing. Say that I configured my zones in a way where LAN can initiate connections to the WAN but WAN cannot initiate connections to the LAN. If LAN is configured under the inspect option, this means that WAN will be able to talk to the LAN as long as WAN is responding to LAN and not trying to initiate any connections to it, correct?

Then, if we configure a zone such as LAN and assign it to an interface via the zone-member command, will this interface be part of the LAN zone or the self zone?

And one last thing. Say that the LAN zone has 20 hosts, each of them should only be able to use ICMP to reach the WAN however, one host can use any protocol to reach the WAN. How would we configure this?

Thank you.
David

Hello David

The type inspect keywords can be used at the class-map level, the policy map level, or within the class under the policy map. These must be used together. As stated in this Cisco command line reference for the policy-map type inspect command:

Use the policy-map type inspect command to create a Layer 3 and Layer 4 inspect-type policy map or a Layer 7 application-specific inspect-type policy map. After you create a policy map, you should enter the class type inspect command (as appropriate for your configuration) to specify the traffic (class) on which an action is to be performed. The class was previously defined in a class map. Thereafter, you should enter the inspect command to enable Cisco IOS stateful packet inspection and to specify inspect-specific parameters in a parameter map.

So the type inspect keywords enable stateful packet inspection specifically used for ZBFW functionality, based on the specific parameters included (i.e. protocol etc). now what is the difference between the type inspect and other policy maps? Non-inspect policy maps are used primarily for QoS to enforce traffic shaping, policing, prioritization, etc. They classify traffic with class maps and apply QoS actions like bandwidth, priority, or shape.

Yes, this is expected behavior, and the reason why has to do with the nature of ICMP traffic and Telnet traffic, and how the ZBFW handles session tracking.

Your firewall policy is set to inspect for ICMP. So when R1 initiates an ICMP echo request (ping) R2 inspects the packet and allows the ICMP reploy from R3 to pass. This is because R2 creates a temporary session in the firewall state table, allowing return ICMP traffic from R3 to R1. Now ICMP is stateless. This means there is no explicit session initiation and termination, nor is there any tracking of specific flows. Any ICMP packets that go from R3 to R1 are allowed for a period of time, including echo replies from the original request, as well as new echo requests from R3 to R1. This doesn’t work a minute later because the temporary session in the firewall state table in R2 has since been removed. The key here is that ICMP is stateless, and flows are not tracked. So all ICMP traffic is allowed temporarily on R2, and that’s why you see the ping from R3 to R1 being allowed temporarily. Now Telnet on the other hand uses TCP, which is stateful, with specific session initiation and termination activities, and with specific port numbers that keep track of the session. For this reason, you can’t initiate a new session from R3 to R1 at the same time simply because the ZBFW can identify the new session and distinguish it from the original. Make sense?

Yes, your understanding is correct. The only exception is the behavior of ICMP that you noticed since there is no session tracking available for stateless traffic.

Actually, if you configure a zone such as LAN and assign it to an interface, that interface will not be part of the self zone. Remember, an interface assigned to a custom zone (e.g., LAN, WAN) is not part of the self zone anymore.

In the scenario you describe, the goal is to allow 19 hosts in the LAN to use only ICMP to reach the WAN, while granting one specific host full access to use any protocol. To achieve this:

  1. We start by defining ACLs to specify which traffic is permitted for each group of hosts.
  2. Next, we create class maps that match these ACLs, ensuring that traffic from the special host and the other LAN hosts is categorized correctly.
  3. Once the class maps are in place, we define policy maps that apply the appropriate inspection rules—permitting all traffic for the special host while restricting the rest to ICMP-only access.
  4. Finally, we apply this policy map to the security zone pair between the LAN and WAN, enforcing the desired access control while maintaining security.

The process is similar to what has been described in the lesson, but with some additional parameters.

I hope this has been helpful!

Laz

Hello everyone,
After playing around for quite some time now with the ZBF, I noticed that there seems to be strange behavior regarding routing protocols tunneled through a GRE. In my current setup, I have two sites connected via a GRE and route the internal networks via RIP. Now, I assumed that RIP traffic would originate from the self zone and have the GRE zone as a destination.

When creating the appropriate ACLs/class-maps/policy-maps/zone-pairs, I noticed that the ACL for RIP did not show any matches. So, I tried a “deny ip any any” on the ACL that’s assigned to the zone with the source as self and the destination as GRE, and while it blocked ICMPs for example I sent from the tunnel interface, RIP traffic just continued to flow.

I currently believe that “self” may not be the appropriate zone for the source of this zone-pair. This is also the case for RIP traffic from the remote site coming to the router. Has anyone got any ideas on how to “fix” this issue?
Leon

	zone security LAN
	zone security VPN
	zone security WAN
	
	interface gig0/1
	zone-member security LAN
	
	interface gig0/0
	zone-member security WAN
	
	interface tunnel 1
	zone-member security VPN
	exit
	
	ip access-list extended lan_wan
	permit icmp any any
	deny ip any any
	exit
	
	ip access-list extended lan_vpn
	permit icmp any any
	deny ip any any
	exit
	
	ip access-list extended vpn_lan
	permit icmp 10.0.20.0 0.0.0.25 10.0.10.0 0.0.0.255
	deny ip any any
	exit
	
	ip access-list extended wan_self
	permit gre host 2.2.2.1 host 1.1.1.1
	deny ip any any
	
	ip access-list extended self_wan
	permit gre host 1.1.1.1 host 2.2.2.1
	deny ip any any
	exit
	
	no ip access-list extended self_vpn
	ip access-list extended self_vpn
	permit icmp any any 
	permit udp host 192.168.1.1 eq 520 host 224.0.0.9 eq 520
	deny ip any any
	exit
	
	no ip access-list extended vpn_self
	ip access-list extended vpn_self
	permit icmp any any
	permit udp host 192.168.1.2 eq 520 host 224.0.0.9 eq 520
	deny ip any any
	exit
	
	no class-map type inspect match-any lan_wan
	class-map type inspect match-any lan_wan
	match access-group name lan_wan
	exit
	
	no class-map type inspect match-any lan_vpn
	class-map type inspect match-any lan_vpn
	match access-group name lan_vpn
	exit
	
	no class-map type inspect match-any vpn_lan
	class-map type inspect match-any vpn_lan
	match access-group name vpn_lan
	exit
	
	no class-map type inspect match-any wan_self
	class-map type inspect match-any wan_self
	match access-group name wan_self
	exit
	
	no class-map type inspect match-any self_wan
	class-map type inspect match-any self_wan
	match access-group name self_wan
	exit
	
	no class-map type inspect match-any self_vpn
	class-map type inspect match-any self_vpn
	match access-group name self_vpn
	exit
	
	no class-map type inspect match-any vpn_self
	class-map type inspect match-any vpn_self
	match access-group name vpn_self
	exit
	
	no policy-map type inspect lan_wan
	policy-map type inspect lan_wan
	class type inspect lan_wan
	inspect 
	class class-default
	drop
	exit
	
	no policy-map type inspect lan_vpn
	policy-map type inspect lan_vpn
	class type inspect lan_vpn
	inspect 
	class class-default
	drop
	exit
	
	no policy-map type inspect vpn_lan
	policy-map type inspect vpn_lan
	class type inspect vpn_lan
	inspect 
	class class-default
	drop
	exit
	
	no policy-map type inspect wan_self
	policy-map type inspect wan_self
	class type inspect wan_self
	pass 
	class class-default
	drop
	exit
	
	no policy-map type inspect self_wan
	policy-map type inspect self_wan
	class type inspect self_wan
	pass 
	class class-default
	drop
	exit
	
	no policy-map type inspect self_vpn
	policy-map type inspect self_vpn
	class type inspect self_vpn
	inspect 
	class class-default
	drop
	exit
	
	no policy-map type inspect vpn_self
	policy-map type inspect vpn_self
	class type inspect vpn_self
	inspect 
	class class-default
	drop
	exit
	
	no zone-pair security lan_wan source LAN destination WAN
	zone-pair security lan_wan source LAN destination WAN
	service-policy type inspect lan_wan
	exit
	
	no zone-pair security lan_vpn source LAN destination VPN
	zone-pair security lan_vpn source LAN destination VPN
	service-policy type inspect lan_vpn
	exit
	
	no zone-pair security vpn_lan source VPN destination LAN
	zone-pair security vpn_lan source VPN destination LAN
	service-policy type inspect vpn_lan
	exit
	
	no zone-pair security wan_self source WAN destination self
	zone-pair security wan_self source WAN destination self
	service-policy type inspect wan_self
	exit
	
	no zone-pair security self_wan source self destination WAN
	zone-pair security self_wan source self destination WAN
	service-policy type inspect self_wan
	exit
	
	no zone-pair security self_vpn source self destination VPN
	zone-pair security self_vpn source self destination VPN
	service-policy type inspect self_vpn
	exit
	
	no zone-pair security vpn_self source VPN destination self
	zone-pair security vpn_self source VPN destination self
	service-policy type inspect vpn_self
	exit

Hello Leon

I believe that the issue you are facing has to do with the way that ZBFs function with GRE tunnels. Of course I can’t be 100% sure unless it is actually tested in the lab, but hopefully what I will share with you will lead you in the right direction to perform the appropriate troubleshooting…

When configuring a ZBF on routers that use GRE tunnels for routing protocols like RIP, it can be confusing to figure out which zone‐pair actually governs that traffic. The key point is that traffic “to or from” the router itself is normally associated with the “self” zone, but GRE‐encapsulated routing updates can behave differently. Below are some guidelines and tips to help you fix the issue:

Understand “self” zone vs. interface‐based zones. The “self” zone is meant for traffic that actually terminates on or originates from the router’s control plane. However, a GRE interface is treated like any other routed interface. Traffic received on or sent out of the tunnel interface may not always use “self” as the zone in ZBF policy. Even if your router is “sending” the RIP updates, the interface membership in a zone (e.g. VPN, WAN, LAN) can change how the firewall engine sees that traffic.

Why your ACL is not matching RIP: Because GRE-encapsulated traffic might appear as transit traffic rather than “self” traffic, ZBF may see it coming from/to the VPN zone (or wherever you placed the tunnel interface). The ACL for RIP inside the “self” zone‐pair might never match because the router internally classifies these updates under the tunnel’s zone membership, rather than “self.”

Create proper zone‐pairs for routing protocols: Ensure you have “vpn_self” and “self_vpn” zone‐pairs if the tunnel is in the “VPN” zone. In those zone‐pairs, craft policy to either pass or inspect UDP/520 (RIP) and any other protocol (GRE, ESP, OSPF, etc.) that needs to terminate on the router. Typically, for routing traffic, “pass” is sufficient rather than “inspect,” because routing protocols don’t create typical client‐server flows. “inspect” won’t hurt but is often overkill.

Verify correct source/destination addresses: RIP to 224.0.0.9 uses UDP/520 (multicast). Verify you have the correct statements in your ACL. Also, confirm that the IP addresses in your ACL (192.168.1.1 / 192.168.1.2) align with the actual loopback or tunnel interface addresses used for RIP. If the router is sourcing RIP from a different interface (or a different IP), you may need to adjust the ACL.

In short, the fix is to be sure that the zone-pair definitions line up with the actual interface zone memberships. If your Tunnel interface is assigned to “VPN,” then RIP traffic inside that GRE tunnel is treated as “VPN → self” or “self → VPN,” not “self → WAN” or “self → LAN.” Modify or create ACLs and policy‐maps in the correct zone‐pairs, and you’ll see your RIP traffic being matched properly. I hope that helps your troubleshooting, let us know how you get along!!

I hope this has been helpful!

Laz

1 Like

Hi Laz,

Thank you very much for your explanation—I really appreciate the help. I also did some further research in the meantime, and I believe I found a possible cause for the behavior I encountered. I found this documentation from Cisco that states multicast inspection is generally not supported.

Based on this information, I labbed up various scenarios and came to the conclusion that the multicast traffic was surprisingly entirely unaffected by any ACL used in the class maps. For example, I changed my scenario slightly from RIP to OSPF (multicast traffic didn’t match again) and then configured OSPF to a Non-Broadcast network type. After that, I used the same zone pairs and policy maps, etc., and as expected, now the (unicast) traffic matched the new ACL (just changed the destination from 224.0.0.5 to 192.168.1.2).

In conclusion, I believe that while my zone pairs/policy maps/class maps were correct, the underlying problem is simply the missing support for multicast traffic. (Maybe it could also be worth mentioning this in the lesson, as this behavior is quite interesting/weird.)

Thanks again for your help,
Leon

Hello Leon

Wow, that’s interesting! Thanks for sharing your findings with us! I will let @ReneMolenaar know to take a look and consider adding this information to the lesson. Can you share with us what platform you tested this out on? Was it an emulator or on real hardware? Can you tell us the platform and IOS versions? Thanks!!

Thanks again, this was helpful!

Laz

1 Like