Cisco IOS PPTP Inspect
Recently I came across the issue of having to pass PPTP traffic from an internally PAT’ed LAN to an external PPTP server. For the sake of not taking the time of drawing an entire diagram, here is the ASCII version:
[Internal LAN] –>(internal address) [Cisco IOS Router] (external address)—> [Internet] —> [PPTP Server]
Please note that even though PPTP VPNs have made many appearances to this site so far, by no means do I recommend using them for most systems. In fact, as I will explain, using them in conjunction with Cisco IOS gear can be especially frustrating if you have not been informed of several caveats.
With the configuration I was using, there was a standard access list on the external interface of the IOS router only allowing in things for regular IPsec VPN’s such as UDP port 500, and ISAKMP. I also made sure to include the #inspect pptp line in my default inspect list. If you are not aware of what the inspect lines do, please refer to this document which gives a general overview:
http://www.cisco.com/en/US/docs/ios/security/command/reference/sec_i2.html#wp1068224
The purpose for inspect lines is basically to “fix” the protocols passing through NAT devices to allow them to properly function behind IP translations. For example, an oddball (but favorite) protocol like FTP actually uses two channels, port 21 for the initial control connection, but then additionally the FTP server sends a request to the client from port 21. If normal ACL and NAT rules were applied, the traffic going through port 21 would be allowed through and back just fine, while port 20 would get completely blocked since it would be seen as a new incoming connection with no translation.
The “ip inspect” commands along with the ASA inspect or PIX fixup syntax tells the underlying processing system “hey, this is a weird protocol, help it out”. In the case of FTP this then opens up both port 21, and then allows an incoming flow on port 20 back in from the same source. Sort of a “it’s cool, I’m with him” approach. Then FTP works as expected, configuration was a bit easier, and life goes on.
So back to our original topic, PPTP. This protocol also does some wonky stuff (but for better reasons than FTP). Read up on this in bored-to-tears depth here. The boiled down version is that the connection initiates on TCP port 1723, a control channel if you will, and the PPTP server will respond back by opening up a GRE tunnel for data. Sound familiar? Control channel, data channel, much like FTP. So one would assume that the inspect commands for both of these protocols would work the same way. You’d be wrong, just as I was.
After having to TAC the case, and having the Cisco engineer struggle with things a little while, he eventually came to the conclusion that, yes the inspect command usually opens up that second line of communication for other protocols just fine, in the case of PPTP this is not the case, and by design apparently. The inspect pptp command lets the control channel work just fine…but it never allows the returning GRE tunnel. Fantastic.
So what does inspect pptp actually do? Well the same thing inspect tcp would do actually, only to a more limited scope. Instead of allowing stateful inspection of all TCP, you just allow for PPTP connections. However, in order to allow an actual tunnel to b established, Cisco recommends allowing all GRE from the needed hosts on the outside access list inbound. How elegant.
Long story short, inspect pptp is a useless command in any situation I’ve seen, and having to open up full GRE allow rules is a bit of a hack. One more reason for PPTP VPN servers to go by the wayward side.

