PPTP/L2TP: RFCs and How-To

Maintained by Tina Bird

Last modified: 13-Feb-2003 6:44


Layer 2 Tunneling Protocol

Securing L2TP using IPsec

Point-to-Point Protocol Extensions

Deriving Keys for use with Microsoft Point-to-Point Encryption MPPE is the encryption algorithm provided by Microsoft, and used by Windows-based implementations of the Point to Point Tunneling Protocol.

L2TP Overview

Cisco Factsheet: Layer 2 Tunneling Protocol

Building a VPN with L2TP Compulsory Tunneling


PPTP/L2TP on Sidewinder, Cisco, PIX or FW-1.

PPTP/L2TP on Linux:

Linux PPTP client PPTP client for Linux and other UNIX flavours.

Linux PPTP server Information on a PPTP server for Linux (now also ported to Solaris, OpenBSD, FreeBSD, and others), how-tos for PPTP and IPSec on Linux, other useful pointers.

An L2TP daemon for Linux One of the annoying things about the Win2000 IPsec implementation is that it only does transport mode IPsec. So if you want to do connections to remote networks, you need to run L2TP on top of IPsec.



PPTP uses TCP/1723 to set up its control channel, and IP protocol 47 (Generic Routing Encapsulation) to move data. Enabling PPTP traffic to flow through a firewall requires you to establish bi-directional rules for both sets of traffic.

On a Sidewinder:

Create a generic proxy on TCP/1723 to allow the PPTP control traffic. The ACL entry should redirect traffic destined for the external IP address of the firewall (or the appropriate alias'ed address) to the PPTP server on the private network. The TCP/1723 proxy must be configured to pass incoming client addresses transparently. This means adding the -X flag to /etc/sidewinder/nss.common.conf (in the appropriate stanza for the newly created generic proxy). In addition, the configuration file for the proxy (/etc/sidewinder/proxy/newproxy.conf, where newproxy.conf is whatever you named the thing) must be modified to pass the client address from the external to the internal burb.

Add an ipfilter rule to allow the GRE traffic to flow through the firewall. In /etc/sidewinder/ipfilter.conf, add the following lines:

allow( 0 external internal-addr 32 internal 47 3 10000)
translate(external-addr internal-addr 47 3)

(remember that the placeholder in the external address field above allows
connections from all external IP addresses.)

On a Cisco:

interface Serial0/0
description Internet interface
ip address xxx.xxx.xxx.xxx
ip access-group inet_inbound in

ip access-list extended inet_inbound #define the access-list
deny ip any
deny ip any
deny ip any #reject RFC1918 addresses
permit tcp any host xxx.xxx.xxx.xxx eq 1723 #permit PPTP control traffic
permit gre any host xxx.xxx.xxx.xxx #permit GRE for PPTP payload

You may have to use an alternative syntax for GRE on some IOS versions:
permit 47 any host xxx.xxx.xxx.xxx #permit GRE for PPTP payload

If you have a pre-11.2 IOS that does not support named IP access-lists, you need to precede each access-list line with the access-list xxx command (where xxx=101-199), ie:

access-list 101 permit tcp any host xxx.xxx.xxx.xxx eq 1723
access-list 101 permit 47 any host xxx.xxx.xxx.xxx

On a PIX:

! These statements apply to current PIX versions (4.X(Y) or later).

! Following examples use for the inside, private host,
! and for the public, translated address for the same host.

conduit permit tcp any eq 1723 host

conduit permit gre any host