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.
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.
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 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
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 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.
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.
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.
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.