Back to blog

Zone-Based Policy Firewall: Cisco's Modern Approach to Traffic Control

Idrissa Maiga
Idrissa Maiga
Tuesday, June 16, 20268 min read
Network SecurityCiscoZPFFirewallsIOS ConfigurationInfrastructure
Zone-Based Policy Firewall: Cisco's Modern Approach to Traffic Control

Traditional firewall configurations on Cisco routers relied on Access Control Lists and Context-Based Access Control (CBAC) applied directly to interfaces. It worked, but it was messy. ACLs are stateless by nature, CBAC defaulted to allowing everything, and as networks grew more complex, the per-interface model became increasingly difficult to manage and audit.

In 2006, Cisco introduced the Zone-Based Policy Firewall (ZPF) in IOS 12.4(6)T. It replaced the interface-centric model with a zone-centric one, flipped the default policy to deny-all, and gave network engineers a configuration language that actually reads like a security policy.

Why ZPF Replaced CBAC#

The shift was not incremental. ZPF fundamentally changed how Cisco routers handle firewall policy.

FeatureCBACZPF
Default policyAllow allDeny all
Configuration modelACL-based, per-interfaceZone-based with C3PL (Cisco Common Classification Policy Language)
Depends on ACLsYesNo
ReadabilityComplex, hard to auditClean, structured, easy to troubleshoot

The biggest change is the default stance. CBAC allowed all traffic unless you explicitly configured inspection rules. If you forgot to configure something, traffic flowed freely. ZPF takes the opposite approach: everything is blocked unless you create a policy that explicitly permits it. If you forget something, traffic gets dropped. That is a much safer failure mode.

How Zones Work#

A zone is a logical grouping of interfaces that share the same security requirements. Instead of applying policies to individual interfaces, you define zones and then create policies for traffic moving between them.

Zone Membership Rules#

  • Interfaces are assigned to zones. Policy applies to traffic flowing between zones
  • Interfaces in the same zone communicate freely with no filtering
  • Multiple interfaces can belong to one zone, but one interface can only belong to one zone
  • A new interface added to a zone inherits that zone's characteristics
  • If an interface is the only member of a zone and no zone-pair exists, all traffic is dropped

That last point catches people off guard. Assigning an interface to a zone without creating any zone-pairs effectively kills all traffic on that interface. The deny-all default is absolute.

The Self Zone#

Every router has a system-defined zone called the self zone. It represents the router itself, not the traffic passing through it.

By default, traffic to and from the self zone is permitted. This means any zone can reach the router (SSH, SNMP, routing protocols) and the router can reach any zone. This is intentional because breaking management access to your own router would be catastrophic during initial configuration.

To lock down access to the router, you create explicit zone-pairs with the self zone as source or destination:

  • source OUTSIDE destination self controls who can reach the router from outside
  • source self destination OUTSIDE controls what the router itself can send outbound

The Three Actions#

ZPF gives you three actions to apply to traffic that matches a policy:

Inspect#

This is the action you will use most often. It configures Stateful Packet Inspection (SPI) for the matched traffic. When you inspect traffic in one direction, return traffic is automatically allowed without needing a reverse policy. It also handles ICMP error messages and multi-channel protocols like FTP where the data channel is negotiated dynamically.

Pass#

Similar to a permit statement in an ACL. It forwards the packet but does not track connection state. This means you need a separate policy in the reverse direction if you want return traffic to flow. In practice, pass is rarely used because inspect handles most scenarios better.

Drop#

Silently discards the packet. You can add the log keyword to generate syslog messages for dropped traffic, which is useful for troubleshooting and security monitoring.

The critical distinction: inspect is stateful and handles return traffic automatically. pass is stateless and requires explicit reverse policies. For almost every real-world scenario, inspect is the correct choice.

ZPF vs. ACL-Based Filtering#

FeatureACL-BasedZPF
Default behaviorImplicit deny at end of ACLDefault deny all between zones
StatefulnessStateless (unless CBAC added)Stateful with inspect
Return trafficMust explicitly permit with established keywordAutomatic with inspect
Application awarenessLimited to port numbersProtocol-aware via NBAR integration

ZPF does not eliminate ACLs. You can still reference ACLs inside class-maps for granular source/destination matching. But the firewall logic itself is no longer built on ACLs.

Configuration: The Five Steps#

ZPF configuration follows a consistent five-step process. This structure is one of its strengths because every ZPF setup follows the same pattern regardless of complexity.

Step 1: Create the Security Zones#

zone security INSIDE
 description Internal trusted network

zone security OUTSIDE
 description External untrusted network

Zones are just logical containers at this point. They do nothing until interfaces are assigned and zone-pairs are created.

Step 2: Define Traffic Classes (Class-Maps)#

Class-maps identify what traffic the policy will act on. You can match by protocol, ACL, or both.

class-map type inspect match-any INSIDE_PROTOCOLS
 match protocol tcp
 match protocol udp
 match protocol icmp

The match-any keyword means traffic matching any one of the listed protocols will be classified. Use match-all if every condition must be true simultaneously.

You can also reference ACLs for source/destination specificity:

access-list 101 permit ip 10.0.0.0 0.0.0.255 any

class-map type inspect INTERNAL_TRAFFIC
 match access-group 101
 match protocol tcp
 match protocol udp
 match protocol icmp

Step 3: Specify Firewall Policies (Policy-Maps)#

Policy-maps tie class-maps to actions. This is where you decide what happens to the classified traffic.

policy-map type inspect INSIDE_TO_OUTSIDE
 class type inspect INSIDE_PROTOCOLS
  inspect

The policy says: for traffic matching INSIDE_PROTOCOLS, perform stateful inspection. Because we used inspect, return traffic will be automatically permitted.

Step 4: Apply Policies to Zone-Pairs#

Zone-pairs define the direction of traffic flow and attach the policy.

zone-pair security IN_TO_OUT source INSIDE destination OUTSIDE
 service-policy type inspect INSIDE_TO_OUTSIDE

This creates a unidirectional policy: traffic from INSIDE to OUTSIDE gets inspected. Return traffic (OUTSIDE to INSIDE) is handled automatically by the inspect action. No reverse zone-pair is needed.

Step 5: Assign Interfaces to Zones#

interface GigabitEthernet0/0/1
 zone-member security INSIDE

interface GigabitEthernet0/0/0
 zone-member security OUTSIDE

The moment you assign an interface to a zone, the deny-all default kicks in. Only traffic explicitly allowed by zone-pair policies will flow.

Complete Working Configuration#

Here is a full ZPF configuration that allows internal users to reach the internet with stateful inspection:

! Step 1: Create zones
zone security Inside
 description Inside network
zone security Outside
 description Outside network

! Step 2: Define traffic classes
access-list 101 permit ip 10.0.0.0 0.0.0.255 any

class-map type inspect INTERNAL_TRAFFIC
 match access-group 101
 match protocol tcp
 match protocol udp
 match protocol icmp

! Step 3: Define policies
policy-map type inspect InsideToOutside
 class INTERNAL_TRAFFIC
  inspect

! Step 4: Create zone-pairs
zone-pair security InsideToOutside source Inside destination Outside
 service-policy type inspect InsideToOutside

! Step 5: Assign interfaces
interface FastEthernet0/0
 zone-member security Inside

interface Serial0/0/0.100 point-to-point
 zone-member security Outside

Verification#

After configuration, use these commands to verify everything is working:

show zone security
show zone-pair security
show policy-map type inspect zone-pair sessions
show class-map type inspect
show policy-map type inspect

The show zone security command confirms zone membership:

zone self
  Description: System defined zone

zone INSIDE
  Description: Internal trusted network
  Member Interfaces:
    GigabitEthernet0/0/1

zone OUTSIDE
  Description: External untrusted network
  Member Interfaces:
    GigabitEthernet0/0/0

The show policy-map type inspect zone-pair sessions command is the most useful for troubleshooting. It shows active sessions, match counters, and which policies are being hit.

Design Patterns#

Internal + Internet (Basic)#

The most common setup. One zone-pair: INSIDE to OUTSIDE with inspect. Internal users access the internet freely. No inbound connections from outside.

Internal + DMZ + Internet (Three-Zone)#

Three zone-pairs needed:

  • INSIDE to OUTSIDE (inspect): Internal users access internet
  • INSIDE to DMZ (inspect): Internal users access DMZ servers
  • OUTSIDE to DMZ (inspect for HTTP/HTTPS only): External users access public services

No OUTSIDE to INSIDE or DMZ to INSIDE zone-pairs. The DMZ is reachable from both sides but cannot initiate connections to the internal network.

Guest Network#

A conference room or guest Wi-Fi zone:

  • GUEST to OUTSIDE (inspect HTTP/HTTPS only): Guests browse the web
  • No GUEST to INSIDE zone-pair: Guests cannot reach internal resources

Design Rules to Remember#

  1. No filtering for traffic within the same zone
  2. One interface, one zone. No exceptions
  3. Never mix CBAC and ZPF on the same interface
  4. An interface in a zone with no zone-pair drops everything
  5. Only explicitly allowed traffic moves between zones
  6. Traffic to the self zone is permitted by default
  7. Zone-pairs are unidirectional. Use inspect for automatic return traffic

Takeaways#

  • ZPF replaced CBAC by flipping the default from allow-all to deny-all
  • Zones group interfaces by trust level. Policy lives between zones, not on interfaces
  • The self zone represents the router itself and permits traffic by default
  • Inspect is stateful and handles return traffic. Pass is stateless and requires manual reverse policies
  • Configuration follows five consistent steps: zones, class-maps, policy-maps, zone-pairs, interface assignment
  • Always verify with show zone security and show policy-map type inspect zone-pair sessions

Comments (0)

Sign in to join the conversation