ProL2TP Advanced Configuration

L2TP and VLANs

The Linux kernel has included full VLAN support since around 2.6.29, offering flexible options for VLAN tagging of L2TP traffic.

Adding VLAN tags to traffic

Linux allows VLAN tags to be added to traffic at the device level using the ip tool, for example:

ip link add link eth1 name eth1.802 type vlan id 802
This creates a new VLAN device eth1.802 on device eth1. All traffic sent from eth1.802 will be tagged with the VLAN ID 802. Incoming traffic with be filtered for the VLAN ID 802, and will have the VLAN tags stripped. This creates the equivalent to a VLAN access port on a managed switch.

Since L2TP pseudowires are represented as virtual devices in the network stack, it is possible to add a VLAN tagging interface to a pseudowire in exactly the same way as a standard device:

site-A:# ip l2tp add tunnel \
		remote 192.168.1.127 \
		local 192.168.1.131 \
		tunnel_id 1 \
		peer_tunnel_id 1
site-A:# ip l2tp add session \
		name l2tpeth0 \
		tunnel_id 1 \
		session_id 1 \
		peer_session_id 1
site-A:# ip link add link l2tpeth0 name l2tpeth0.500 type vlan id 500
This creates a new VLAN device l2tpeth0.500 with VLAN ID 500.

Bridging VLAN devices

Once you have created one or more tagged VLAN devices it is possible to bridge them using the brctl tool:

site-A:# brctl addbr br0
site-A:# brctl addif br0 l2tpeth0.500
site-A:# brctl addif br0 eth1
This creates a new bridge, br0, and adds eth1 and l2tpeth0.500 to the bridge. Since incoming traffic on l2tpeth0.500 is stripped of VLAN tags by the kernel this effectively removes the VLAN tags from the L2TP traffic before bridging that traffic onto eth1 at site-A.

Combining the ip and brctl tools it is possible to employ sophisticated VLAN schemes with L2TP. Incoming L2TP traffic may have its VLAN tags stripped or modified; and untagged traffic may be tagged to be sent out on a local VLAN.

Example configurations

Bridge traffic from VLAN ID 300 on eth0 to L2TP pseudowire l2tpeth0:

site-A:# ip link add eth0 name eth0.300 type vlan id 300
site-A:# brctl addbr br0
site-A:# brctl addif br0 eth0.300
site-A:# brctl addif br0 l2tpeth0

Bridge traffic from VLAN ID 501 on L2TP pseudowire l2tpeth0 to eth0 VLAN ID 501:

site-A:# ip link add eth0 name eth0.501 type vlan id 501
site-A:# ip link add l2tpeth0 name l2tpeth0.501 type vlan id 501
site-A:# brctl addbr br0
site-A:# brctl addif br0 eth0.501
site-A:# brctl addif br0 l2tpeth0.501

Bridge traffic from VLAN ID 999 on L2TP pseudowire l2tpeth0 to L2TP pseudowire l2tpeth1 VLAN ID 345:

site-A:# ip link add l2tpeth0 name l2tpeth0.999 type vlan id 999
site-A:# ip link add l2tpeth1 name l2tpeth1.345 type vlan id 345
site-A:# brctl addbr br0
site-A:# brctl addif br0 l2tpeth0.999
site-A:# brctl addif br0 l2tpeth1.345

Large Bridges

By default the Linux kernel limits bridges to a maximum of 1023 interfaces. Although more than sufficient for most applications, this limitation may be restrictive when attempting to bridge large numbers of L2TP sessions.

Linking bridges

To work around the bridge interface limit, multiple bridges may be linked using the Linux Virtual Ethernet driver. This driver provides a simple tunnel operating at the link layer. It appears as a pair of interconnected Ethernet interfaces to the rest of the Linux system.

Diagram of linked network bridges

As the diagram shows, L2TP pseudowires are connected to a number of bridges, br1, br2, and br3. Each of these is then linked to a single "master" bridge, br0, using veth tunnels. In this way it is possible to bridge large numbers of L2TP sessions.

The ip tool can be used to create veth tunnels:

ip link add name vt0-0 type veth peer name vt0-1
This creates two virtual interfaces vt0-0 and vt0-1 which provide a tunnel. These two interfaces can be added to a bridge using the brctl tool:
brctl addif br0 vt0-0

Example configurations

Bridge three L2TP pseudowires using linked bridges:

# First create the bridges
site-A:# brctl addbr br0
site-A:# brctl addbr br1
site-A:# brctl addbr br2
site-A:# brctl addbr br3

# Now create veth tunnels to link the bridges
site-A:# ip link add name vt1-0 type veth peer name vt1-1
site-A:# ip link add name vt2-0 type veth peer name vt2-1
site-A:# ip link add name vt3-0 type veth peer name vt3-1

# Link the bridges using the veth interfaces
site-A:# brctl addif br0 vt1-0
site-A:# brctl addif br0 vt2-0
site-A:# brctl addif br0 vt3-0
site-A:# brctl addif br1 vt1-1
site-A:# brctl addif br2 vt2-1
site-A:# brctl addif br3 vt3-1

# Bring up the bridges and veth tunnels
site-A:# ip link set vt1-0 up && ip link set vt1-1 up
site-A:# ip link set vt2-0 up && ip link set vt2-1 up
site-A:# ip link set vt3-0 up && ip link set vt3-1 up
site-A:# ip link set br0 up
site-A:# ip link set br1 up
site-A:# ip link set br2 up
site-A:# ip link set br3 up

# Now add in the l2tpethX interfaces
site-A:# brctl addif br1 l2tpeth0
site-A:# brctl addif br2 l2tpeth1
site-A:# brctl addif br3 l2tpeth2
Although this example is small and simple, the linking of br1, br2, and b3 in this way allows the bridging of some 3066 L2TP sessions. The same configuration could be extended to add further bridge capacity by linking further bridges to br0.

L2TP and IPsec

IPsec is a suite of protocols which secure IP communications by authenticating and encrypting IP packets. It operates at the network layer of the stack, and hence is transparent to the transport layer. This makes it a good choice for securing L2TP tunnels and sessions, and the combination of L2TP with IPsec is common.

A number of IPsec implementations exist for Linux, including openSwan, strongSwan, and ipsec-tools.

An example IPsec configuration

Diagram L2TP traffic secured using IPsec

This simple example will use strongSwan to provide IPsec protection for the traffic between an LNS and LAC as shown in the diagram above.

Installing strongSwan

The strongSwan project is packaged for most of the mainstream distributions, including Debian, Ubuntu, and Fedora. The project website includes installation guidance, including information on building from source.

Generating self-signed certificates

IPsec uses the IKE protocol for host authentication and key exchange. To support this, each IPsec host needs a certificate signed by some trusted authority, along with the private key corresponding to that certificate.

For demo purposes it is possible to self-sign certificates for the LNS and LAC machines. The strongSwan wiki details setting this up using the ipsec tool. This approach works well under Debian and Ubuntu. Under Fedora the ipsec is not bundled with the strongSwan package, however certificates and keys may still be generated using OpenSSL ( this tutorial explains one way of using OpenSSL for self-signing).

Configuring strongSwan

Configuration is similar for LNS and LAC machines -- this set of instructions is for the LNS.

First, install the host's certificate and key, as well as the remove host's certificate (this is necessary as we're self-signing):

cp lnsCert.pem /etc/strongswan/ipsec.d/certs
cp lnsKey.pem /etc/strongswan/ipsec.d/private
cp lacCert.pem /etc/strongswan/ipsec.d/certs

Now edit the file /etc/ipsec.secrets (or /etc/strongswan/ipsec.secrets under Fedora) and add configuration to point strongSwan to the host's private key:

: RSA lnsKey.pem

Next, edit the file /etc/ipsec.conf to define the connection between the local ("left" in strongSwan nomenclature) and remote ("right") hosts. The host ids here are the "Subject:" lines from the host certificate, which you can examine using "openssl x507 -in -text":

conn prol2tp_ipsec
	left=
	right=
	auto=start
	leftid=""
	leftcert=lnsCert.pem
	rightid=""
	rightcert=lacCert.pem

Running strongSwan and testing the connection

Once strongSwan is configured on both the LNS and LAC machines, use your distribution's service control tool to bring up strongSwan. On Fedora:

systemctl start strongswan.service
And on Ubuntu:
service ipsec start
Check /var/log/messages for any errors reported from either strongswan or the IKE2 daemon charon. Assuming the IPsec connection between the LNS and LAC has been correctly configured, you can now check traffic is protected using netcat and tcpdump:
# On the LNS:
tcpdump -i  &
nc -l 50001

# On the LAC:
tcpdump -i  &
nc 50001

# Now type messages on the LAC.  They will be forwarded to the LNS.  Note the
# packets shown by tcpdump are all ESP!
Finally, if you create a ProL2TP tunnel and session over the IPsec connection, all L2TP control traffic, as well as transmitted user data, will be IPsec-protected. No configuration modifications for ProL2TP are required.

Index

L2TP and VLANs
Adding VLAN tags to traffic
Bridging VLAN devices
Example configurations
Large Bridges
Linking Bridges
Example configurations
L2TP and IPsec
An example IPsec configuration
Installing strongSwan
Generating self-signed certificates
Configuring stronSwan
Running strongSwan and testing the connection