I have written this Tech Tip as I spent a fair amount of time getting this working. This config allows an Outbound PPTP VPN session, to pass through a Cisco IOS Zone Based Firewall, to connect to an external service outside of the local network (in this case a service hosted by a clients business partner).

Firstly, the consultant in me would like to say that this is NOT an architectural approach which I recommend. Where a Remote Access VPN solution is required, I recommend a professional standard IPSec or SSL solution (such as Cisco’s Anyconnect or Palo Alto Networks Global Protect). I immensely dislike the PPTP concept where an un-inspected GRE Tunnel is allowed through an Internet Perimeter Firewall.

With that said, as some parts of this configuration were non-obvious. I thought it worthwhile to document it.

I recommend for people who wish to understand PPTP should consult RFC 2637. Let me provide a quick summary of the pertinent aspects of PPTP. Firstly, it is important to understand that PPTP utilises TCP port 1723 for connection establishment, authentication, and maintenance, then it uses GRE (IP protocol 47) to pass data. By default, the Cisco Zone Based Firewall class-map keyword -

"match protocol pptp"

does not pass the GRE traffic, only the TCP 1723 control traffic. To do so would typically require an Application Level Gateway (ALG). The long and short is that you need to bi-directionally permit GRE through the ZBF to be able to establish an outbound PPTP connection to an external server. While this sounds simple, there were a number of configuration weirdnesses which were encountered. The main one being that GRE is not an inspected protocol, hence it can only be ‘passed’ not inspected.

One more caveat. The security policy in this config may NOT be suitable for you!  It was suitable this particular clients environment. No warranties are either expressed or implied. Please use discretion and understand your own network security requirements.

Anyhow here are the relevant config fragments;

version 15.0
ip inspect log drop-pkt
! The above command is strongly recommended, its logs any FW drops.
! This is very useful for troubleshooting and detecting security policy violations.
class-map type inspect match-any C1-PPTP-OUT
 match protocol pptp
class-map type inspect match-any C1-GRE-OUT
 match access-group name ACL_GRE_OUT
class-map type inspect match-any C2-GRE-IN
 match access-group name ACL_GRE_IN
class-map type inspect match-any C1
 match protocol http
 match protocol https
 match protocol telnet
 match protocol ssh
 match protocol sip
 match protocol icmp
 match protocol dns
 match protocol dnsix
 match protocol ftp
 match protocol ftps
 match protocol irc
 match protocol ntp
 match protocol isakmp
 match protocol pop3
 match protocol pop3s
 match protocol rtsp
 match protocol smtp
 match protocol sip-tls
 match protocol tcp
 match protocol udp
policy-map type inspect P1
 class type inspect C1
 class type inspect C1-PPTP-OUT
 class type inspect C1-GRE-OUT
 class class-default
policy-map type inspect P2
 class type inspect C2-GRE-IN
 class class-default
zone security OUTSIDE
 description Outside Internet Sec Zone
zone security INSIDE
 description Inside security zone
zone-pair security FW1 source INSIDE destination OUTSIDE
 description FW from inside to outside internet
 service-policy type inspect P1
zone-pair security FW1-IN source OUTSIDE destination INSIDE
 description FW from outside internet to inside
 service-policy type inspect P2
interface Vlan1
 description Local Interface
 ip address
 ip nat inside
 ip virtual-reassembly
 zone-member security INSIDE
 ip tcp adjust-mss 1452
 hold-queue 100 out
interface Dialer1
 ip address negotiated
 ip flow ingress
 ip nat outside
 ip virtual-reassembly
 zone-member security OUTSIDE
 encapsulation ppp
 dialer pool 1
 ppp chap hostname <DELETED>
 ppp chap password <DELETED>
ip nat inside source list 1 interface Dialer1 overload
ip route Dialer1
ip access-list extended ACL_GRE_IN
 permit gre host <DELETED-EXT-SERVER>
ip access-list extended ACL_GRE_OUT
 permit gre host <DELETED-EXT-SERVER>