L2tp

From SixXS Wiki
Jump to: navigation, search

L2TP allows you to create IPv6 capable tunnel from behind the dynamic IP/NAT since it encapsulates data into UDP packets, and uses PPP as transport layer.

Usage

If you need to connect your garage or cottage to the home IPv6 network via public IPv4 cloud - l2tp could be best solution. It is industry standard, packages included into major distributives, even win supports it (big deal, eh?).

Configuration usually includes two common steps - client and server side, each side in turn includes configuring L2TP and PPP components.

Below example is built around Ubuntu Natty client, which includes xl2tpd fork in Universe repository, to Gentoo server.

Configuring L2TP

L2TP configuration aimed to penetrate firewalls, NATs and other IPv4 "features" creating physical (wire) transport layer for PPP. In our case we're building simple garage2home connectivity, thus we can neglect all the complexities, not forgetting about security though.

Server side

Server side will be located at the place having static IP - usually at home. My server side is based on Gentoo linux, but it does not matter. Simply install xl2tpd portage

~# emerge xl2tpd

and create /etx/xl2tpd/xl2tpd.conf file with straight forward content. Global section [global] with its default settings is more than enough for us. In default fallback server section [lns default] we will put all our configuration directives, keeping in mind following points:

  • chap authentication
  • no ip allocation - it will allocate IPv4 IPs - I don't need them, but you can of course assign some ip
  • ppp peer glue - name of l2tp session should match to the PPP names - my l2tp name will be remote PPP name for peer.

with that in mind our config will look like this

; I'm content with default settings
[global]
; Let define some default LNS config - our peer will use it
[lns default]
assign ip = no
require chap = yes
refuse pap = yes
require authentication = yes
unix authentication = no
name = home
ppp debug = no
pppoptfile = /etc/ppp/options.l2tpd

here pppoptfile is our glue to the PPP daemon. Will review it later. Once we've defined authentication in L2TP - let define our user. Edit "/etc/xl2tpd/l2tp-secrets" with following content:

# us them secret
home garage sillypass

Client side

On client (Ubuntu) install xl2tpd package:

~# aptitude install xl2tpd

and edit /etc/xl2tpd/xl2tpd.conf:

[global]
[lac home]
lns = home.my.name
redial = yes
redial timeout = 15
require chap = yes
refuse pap = yes
require authentication = yes
name = garage
ppp debug = no
pppoptfile = /etc/ppp/options.l2tpd.client

nothing new here - we're redialing (reconnecting) to home in case of connection loss, using chap auth, launching PPP with options from /etc/ppp/options.l2tpd.client.

Do not forget to put authentication line into /etc/xl2tpd/l2tp-secrets:

# us them secret
garage home sillypass

PPP Configuration

PPP will serve as transport (logical) layer, creating tunnel for us. Since we're doing authentication on L2TP layer we need to disable authentication for PPP, also disabling all IPv4 bells and whistles - we need pure transport tunnel at the end.

Server Side

On server our main point isto enable IPv6 negotiation, while disabling all default crap. Hence, our /etc/ppp/options.l2tpd, defined in xl2tpd.conf for server will look like this:

refuse-eap
noccp
noauth
nodefaultroute
crtscts
idle 1800
mtu 1410
mru 1410
lock
connect-delay 5000
+ipv6
ipv6 ::1,::2
ipv6cp-accept-local

Here we're enabling IPv6 by +ipv6 option, then assigning IPv6 suffixes for tunnel endpoints - by default it will use link local prefix (fe80) and provided suffixes for 'local,remote' sides. ipv6cp-accept-local option tells to accept such link local prefixes.

Client PPP

On client side configuration looks pretty the same except suffixes assignment:

refuse-eap
noccp
noauth
nodefaultroute
crtscts
idle 1800
mtu 1410
mru 1410
lock
connect-delay 5000
+ipv6
ipv6cp-accept-local

nothing new here.

Tuning

When PPP is bringing up the tunnel it executes /etc/ppp/ip-up script (and ip-down on tunnel destruction) thus we can add here trigger to reload radvd daemon to learn new interface and start sending adverts to it. You can append following line to achieve this:

ping6 fe80::1 -I $1 -c 1 -q && ( ifconfig $1 add 2001:db8:1:1::1/64 && kill -1 `cat /var/run/radvd/radvd.pid` )

here we're checking the interface has IPv6 configuration (link local address) and if so configure IPv6 address on interface and reload radvd to learn new interface - given radvd's config already has proper section for this interface.

In my case both Linux boxes are routers - ipv6.forwarding enabled - hence radvd doesn't have much sense here. Instead I'm running quagga and ospf6 which automatically announces my prefixes and creates appropriate routing entries.


Follow up

Now that we have our connectivity with home, and running local Master DNS server to manage or zones locally, we can create secondary server to publish zones from home's static IPv4 address.

References

[1] [2]