I am seeing many people migrating from Cisco CBAC to Zone Based Firewall (ZBF) on 800 - 3900 series ISR devices being used as Internet edge firewalls due to the greater flexibility, and better interoperability with policy routing.
The most common question I receive is from a tech that sets up Zone Based Firewall according to Cisco's guide and many examples on the Internet, then finds out clients on the inside are unable to use their PPTP Windows VPN to connect to a server outside the firewall.
I encourage anyone interested in a deep understanding of PPTP to read through RFC 2637, but I will give a quick summary of the pertinent aspects of PPTP here. It is important to understand that PPTP utilizes TCP port 1723 for connection establishment, authentication, and maintenance, it then uses GRE, IP protocol 47, to pass data. By default, ZBF's keyword "match protocol pptp" does not handle the GRE traffic, only the TCP 1723 traffic.
First, let's see how to migrate from CBAC to the most basic ZBF configuration
Exhibit 1: Most Basic ZBF Config
Everything except PPTP will work outbound with this config
Step 1: Define and populate our zones:
!Define two zones
zone security ZONE_INSIDE
zone security ZONE_OUTSIDE
interface fa0/1
!Assume FastEthernet0/1 is our inside interface
zone-member security ZONE_INSIDE
interface fa0/0
!Assume FastEthernet0/1 is our outside interface
zone-member security ZONE_OUTSIDE
!Remove any CBAC commands you had here
no ip inspect CBAC in
no ip inspect CBAC out
!Remove the inbound access-list from the outside interface. Unlike CBAC, we do not control inbound access via an access-list.
no ip access-group ACLin in
Step 2: Define the class maps that identify traffic that is permitted between zones:
class-map type inspect match-any CM_INTERNET_TRAFFIC
match protocol h323
match protocol pptp
match protocol ftp
match protocol tcp
match protocol udp
match protocol icmp
!Note - we add h323 and ftp here specifically to account for upper-layer inspection required for those protocols
Step 3: Configure a policy map which specifies the action for the class map:
policy-map type inspect PM_INSIDE_TO_OUTSIDE
class type inspect CM_INTERNET_TRAFFIC
inspect
Step 4: Configure the zone pair and apply your policy:
zone-pair security ZONEP_INSIDE_OUTSIDE source ZONE_INSIDE destination ZONE_OUTSIDE
service-policy type inspect PM_INSIDE_TO_OUTSIDE
Exhibit 2: I like PPTP, would like!
This config adds outbound PPTP. Note – GRE is not automatically opened by the “match protocol pptp” in the CM_INTERNET_TRAFFIC, so we need to make GRE passed both inside to outside and reverse without inspecting it.
Step 1, Define new class-map that matches all GRE, note that you need to use an ACL for this that is referenced in the class-map:
ip access-list extended GRE
remark Access List to allow PPTP GRE outbound
permit gre any any
class-map type inspect match-any CM_GRE_PROTOCOLS
match access-group name GRE
Step 2: Configure a policy map which specifies the action for the class map:
policy-map type inspect PM_INSIDE_TO_OUTSIDE
class type inspect CM_GRE_PROTOCOLS
pass
class type inspect CM_INTERNET_TRAFFIC
inspect
class class-default
drop
policy-map type inspect PM_OUTSIDE_TO_INSIDE
class type inspect CM_GRE_PROTOCOLS
pass
class class-default
drop
Step 3: Configure the zone pair and apply your policy:
zone-pair security ZONEP_INSIDE_OUTSIDE source ZONE_INSIDE destination ZONE_OUTSIDE
service-policy type inspect PM_INSIDE_TO_OUTSIDE
zone-pair security ZONEP_OUTSIDE_INSIDE source ZONE_OUTSIDE destination ZONE_INSIDE
service-policy type inspect PM_OUTSIDE_TO_INSIDE
Note: The above config is perfect for a SOHO user who is not hosting any internal servers. However, most sites will be hosting servers internally, so below is an example with the naming scheme of how I like to form my class maps, access-lists, and policy-maps. Note that I like to keep all "variable" names in upper case so they pop out to me in my config. (Credit to Internetwork Experts for that tip)
Exhibit 3: I host servers, so I need an inbound firewall
Step 1, Define an access-list with the internal IP of the server:
ip access-list extended HELPDESK
permit ip any host 10.5.0.3
Step 2, Define a "match-any" class-map with the protocols to be allowed:
class-map type inspect match-any CM_HELPDESK_PROTOCOLS
match protocol http
match protocol https
match protocol ssh
Step 3, Define a "match-all" class map to combine the two:
class-map type inspect match-all CM_HELPDESK
match access-group name HELPDESK
match class-map CM_HELPDESK_PROTOCOLS
Step 4, Add the class-map to the OUTSIDE_TO_INSIDE policy-map:
policy-map type inspect PM_OUTSIDE_TO_INSIDE
description Internet to LAN Servers
class type inspect CM_GRE_PROTOCOLS
pass
class type inspect CM_ICMP
inspect
class type inspect CM_HELPDESK
inspect
class class-default
drop
Step 5, Don't forget your nat statement:
ip nat inside source static 10.5.0.3 1.1.1.1
Notes:
- I like to add an ICMP inspect class map so you can ping all servers without needing to explicitly adding ICMP to every server's class-map. You would not want this if permitting pinging is not preferred, or if you are worried about ICMP security risks.
- If you need to add a non-standard port you have two options.
- First, give it a name: ip port-map user-RDP port tcp 3389
- Second, define an ACL with the ports, and add it to the "match-any" CM_SERVER_PROTOCOLS:
ip access-list extended LTIITEDGE_PROTOCOLS
permit tcp any host 10.50.1.10 eq 5061
permit tcp any host 10.50.1.10 eq 8057
permit tcp any host 10.50.1.10 eq 5062
permit tcp any host 10.50.1.10 eq 3478
permit tcp any host 10.50.1.10 range 49152 65535
DocCD items to reference: