Basic Configuration of Zone Based Firewall

Zone Based FirewallI often think of Zone Based Policy Firewall or ZBF is Cisco’s new firewall engine for IOS routers. However it came as a new feature in IOS 12.4(6)T, which was released in 2006. So new is a bit of a stretch. The new is probably more related to the fact that I haven’t used it much. As I’m planning on taking CCIE Security Zone Based Firewall is something I have to learn more about. Up until now I’ve used the good old trusted CBAC to while using a router as a firewall, and I’ve a feeling a lot of people still use the legacy CBAC out of old habit.

After doing a review of the setup, my impressions are that the configuration of a zone based firewall seems more complex and can be depending on what your access-lists looked like with the CBAC engine. If you have fine grained access-lists it can take some time to convert the rules to ZBF. However it also feels flexible and overall it’s growing on me.

Starting from scratch

I started with a clean config in terms firewall settings. In this post I’m just going to setup a basic config for zone based firewall and I’ll keep more advanced topics for other articles.

This test was done with a Cisco 881 router running 15.1(4)M4 (advipservices).

This setup uses two interfaces, one Internet connection and one inside network. I’m using DHCP to get an address on my outside Interface.

interface FastEthernet4
 description To Internet
 ip address dhcp
 ip nat outside

interface vlan60
 description Inside Network
 ip address 10.20.10.1 255.255.255.0
 ip nat inside

ip nat inside source route-map OUTSIDE-POOL interface FastEthernet4 overload

ip access-list extended NAT-TO-OUTSIDE
 permit ip 10.20.10.0 0.0.0.255 any

route-map OUTSIDE-POOL permit 10
 match ip address NAT-TO-OUTSIDE
 match interface FastEthernet4

Everything coming from the Inside network going to the outside passes the NAT statement and is translated to the ip address of the Internet interface. Nothing is blocked and all traffic is allowed.

Zones

As obvious as it sounds we use zones in Zone Based Firewalls. A zone is a logical grouping of one or more networks. The first step when using zones is to define the zones themselves.

NL-RTR-01(config)# zone security INTERNET
NL-RTR-01(config)# zone security INSIDE

The next step is to go to each interface and assign them to a zone, or make them a member of a zone. Several interfaces can be members of the same zone, this is useful if you want to assign the same policy to different interfaces. For example if you have two Internet connections, one primary and one backup, both of the interfaces can be members of the same zone. This can simplify the policy and save you from creating duplicate rulesets. However in this post each zone will only have one member interface.

interface Fastethernet4
 zone-member security INTERNET
interface vlan60
 zone-member security INSIDE

Once an interface is made a member of a zone, traffic passing that interface will only be allowed to or from other interfaces if the other interface is also a member of a zone, and you have setup a policy which allows the traffic. So at this point nothing is allowed in or out.

Traffic between two interfaces in the same zone used to be allowed be default, however this behaviour changed in 15.0(1)M.

Aside from each zone assigned to an interface there is also a self zone which can be used to control traffic allowed to and from the router.

Zone pairs

A zone pair is a pairing of two zones and a direction. A firewall policy is then applied to a zone pair.

In this example we want to allow traffic from the Inside to the Internet. When configuring the router you will have to create a service policy prior to creating a zone-pair. But I think it might be easier to follow along the configuration if we setup the zone-pairing first. The complete configuration located at the bottom of the article lists the configuration in the correct order.

zone-pair security ZP-INSIDE-TO-OUTSIDE source INSIDE destination INTERNET
 service-policy type inspect INSIDE-TO-OUTSIDE-POLICY

What this will do is to create a zone-pair named ZP-INSIDE-TO-OUTSIDE and look at traffic coming from INSIDE and going to OUTSIDE. For this traffic we will use the INSIDE-TO-OUTSIDE-POLICY.

Since we only setup one zone-pair and policy only traffic originating from Inside going to Outside will be allowed. If we want to allow traffic from Outside to Inside, we need another zone-pair grouping. However since this is a stateful firewall, the return traffic going back to Inside will be allowed even if we don’t have a policy for traffic originating from the Internet.

Creating a policy for a zone pairing

In the most simple way to look at it a policy is a grouping of traffic along with along with a decision for how that traffic is handled.

To start off we want to allow DNS, ICMP and HTTP from the inside network to the Internet. The first part, the grouping of the traffic, is done by creating a class-map.

class-map type inspect match-any ALLOWED-PROTOCOLS
 match protocol icmp
 match protocol dns
 match protocol http

This is the traffic we want to do something with, in this case we want to allow it. So we reference this traffic in a policy map.

policy-map type inspect INSIDE-TO-OUTSIDE-POLICY
 class type inspect ALLOWED-PROTOCOLS
  inspect

What we’ve done is to define a zone-pair and for traffic going from the Inside to the Internet we use the policy INSIDE-TO-OUTSIDE-POLICY. This policy matches the traffic in the ALLOWED-PROTOCOLS class-map, which now matches for icmp, dns and http traffic. The action we take on this traffic is inspect, meaning we allow the traffic and make sure the correct return traffic is allowed. In other posts I will also go into application level inspection, or layer 7 policies.

Aside from inspect we can also choose to drop or pass the traffic. As you might guess the drop action denies the traffic. The pass action allowed the traffic but doesn’t inspect it, so the pass action is stateless meaning the return traffic isn’t allowed back. This can be useful if we have asymmetric routing or if we’re using the self zone.

Matching traffic to inspect

Now we have a working implementation of a zone based firewall. But we don’t have that much control of the traffic we to allow. Any http, dns or icmp traffic is allowed from any host on the inside to any host on the Internet. Say for example we want to avoid that the clients on the inside can use dns tunnelling. So we only want to allow DNS traffic from our DNS servers 10.20.10.16 and 10.20.10.17. Looking back at the traffic we match on this is what we’re currently matching against:

class-map type inspect match-any ALLOWED-PROTOCOLS
 match protocol icmp
 match protocol dns
 match protocol http

The match-any keyword means that any match will do and that only one match is needed. What we need to do is to remove the dns protocol from the ALLOWED-PROTOCOLS class-map and create a new class-map for DNS. Also since we want to restrict the DNS traffic to two hosts we need an access-list to define that traffic.

class-map type inspect match-any ALLOWED-PROTOCOLS
 no match protocol dns
 exit

ip access-list extended TRAFFIC-FROM-DNS-SERVERS
 remark Match traffic from DNS Servers
 permit ip host 10.20.10.16 any
 permit ip host 10.20.10.17 any

class-map type inspect match-all DNS-TRAFFIC
 match protocol dns
 match access-group name TRAFFIC-FROM-DNS-SERVERS

policy-map type inspect INSIDE-TO-OUTSIDE-POLICY
 class type inspect DNS-TRAFFIC
  inspect

In this new class-map we use the match-all statement, this is basically the opposite of match-any. We have to match every line, in this case the traffic has to originate from the DNS servers as defined in the TRAFFIC-FROM-DNS-SERVERS access-list, and it also has to match the protocol dns. If any of these servers would send out any other traffic such as ftp, we would get a match on the access-list since it’s matching any ip protocol. But we wouldn’t get a match on the protocol dns, so the class-map wouldn’t match.

Since we’ve restricted the DNS traffic we might as well restrict the http traffic too. Let’s say we have a web proxy server on 10.20.10.18 and that’s the only server to be allowed to use http to the Internet. First we remove the http protocol from the ALLOWED-PROTOCOLS class-map and then we create a new access-list and class-map to match the http traffic in the same way as we did with DNS.

class-map type inspect match-any ALLOWED-PROTOCOLS
 no match protocol http
 exit

ip access-list extended TRAFFIC-FROM-WEB-PROXY-SERVER
 remark Match traffic from the proxy server
 permit ip host 10.20.10.18 any

class-map type inspect match-all HTTP-TRAFFIC
 match protocol http
 match access-group name TRAFFIC-FROM-WEB-PROXY-SERVER

policy-map type inspect INSIDE-TO-OUTSIDE-POLICY
 class type inspect HTTP-TRAFFIC
  inspect

The end result is that we don’t allow any traffic originating from the Internet to our network. From the internal network we allow icmp from any host to any host. We only allow DNS traffic from our DNS servers and only allow HTTP traffic from our web-proxy.

Complete configuration

The end config looks like this, again in this setup I’m using a Cisco 881 router running 15.1(4)M4.

class-map type inspect match-any ALLOWED-PROTOCOLS
 match protocol icmp
class-map type inspect match-all DNS-TRAFFIC
 match protocol dns
 match access-group name TRAFFIC-FROM-DNS-SERVERS
class-map type inspect match-all HTTP-TRAFFIC
 match protocol http
 match access-group name TRAFFIC-FROM-WEB-PROXY-SERVER
!
!
policy-map type inspect INSIDE-TO-OUTSIDE-POLICY
 class type inspect ALLOWED-PROTOCOLS
   inspect
 class type inspect DNS-TRAFFIC
   inspect
 class type inspect HTTP-TRAFFIC
   inspect
 class class-default
   drop
!
zone security INTERNET
zone security INSIDE
zone-pair security ZP-INSIDE-TO-OUTSIDE source INSIDE destination INTERNET
 service-policy type inspect INSIDE-TO-OUTSIDE-POLICY

interface FastEthernet4
 description To Internet
 ip address dhcp
 ip nat outside
 zone-member security INTERNET

interface Vlan60
 description Inside Network
 ip address 10.20.10.1 255.255.255.0
 ip nat inside
 zone-member security INSIDE

ip nat inside source route-map OUTSIDE-POOL-MAP interface FastEthernet4 overload
!
ip access-list extended NAT-TO-OUTSIDE
 permit ip 10.20.10.0 0.0.0.255 any
ip access-list extended TRAFFIC-FROM-DNS-SERVERS
 remark Match traffic from DNS Servers
 permit ip host 10.20.10.16 any
 permit ip host 10.20.10.17 any
ip access-list extended TRAFFIC-FROM-WEB-PROXY-SERVER
 remark Match traffic from the proxy server
 permit ip host 10.20.10.18 any
!
!
!
!
!
route-map OUTSIDE-POOL-MAP permit 10
 match ip address NAT-TO-OUTSIDE
 match interface FastEthernet4
!