Tuesday, March 3, 2015

IPv6 linux gateway for home network with Telenet (Belgian ISP)

This took me a while to figure out, but I finally got the missing piece figured out.  I'm using Telenet as an ISP to provide access from my home network.  I have a linux box acting as a gateway router for the home network with some basic services that I use in my home.
The ISP has IPv6 enabled on their cable modems for a while, and I've been trying to extend that IPv6 network into my home network.  After all, they're handing out a /64 to all end users.  Here's how I got it to work.

The situation looks like this. The Telenet router is the ISP provided cable modem.  After that I have my Ubuntu linux gateway.  For the examples later, eth0 is the home network, eth1 is towards the internet.

The address range for the home network can be found on the admin pages from the ISP (warning - dutch content)

To turn on IP forwarding, configure in /etc/ufw/sysctl.conf:

I'll focus on the IPv6 specific settings in the remainder of the post.
In /etc/network/interfaces:
iface eth0 inet6 static
 address 2a02:1810:2088:5b00::100
 netmask 64
 up ip route add 2a02:1810:xxxx:xxxx::/64 dev eth0 metric 100
 down ip route del 2a02:1810:xxxx:xxxx::/64 dev eth0 metric 100

Note that I added an explicit metric.  If I didn't do this, the default route that is assigned to eth1 would get the upperhand, and I wouldn't be able to properly communicate within my home network since the gateway would send all traffic out the door.

Install radvd to autoconfigure devices on the home network:
sudo apt-get install radvd

And configure it:
interface eth0
   AdvSendAdvert on;
   MinRtrAdvInterval 30;
   MaxRtrAdvInterval 100;

   # There's no DHCPv6
   AdvManagedFlag off;
   AdvOtherConfigFlag off;

   prefix 2a02:1810:xxxx:xxxx::/64
        AdvOnLink on;
        AdvAutonomous on;
        AdvRouterAddr on;

Now before we add the last piece, make sure you have proper firewall rules in place.  I suggest configuring /etc/default/ufw to have disable forwarding by default (and potentially the other chains too):
Then specifically add firewall rules as required for your network.  Two things to know about:
  • There's no need for NAT with IPv6, so you can allow access directly to internal hosts
  • Ensure to configure the firewall on the "Mijn Telenet" ISP admin page in addition to the firewall on the linux gateway.

Now the last piece, which I couldn't figure out for the longest time: when requests come in from the internet (or responses from outgoing packets) the telenet router relies on IPv6 neighbor discovery to figure out who's behind it.  The linux gateway router doesn't proxy such requests by default.
You can compare this with ARP in IPv4.  The Telenet gateway is trying to figure out who has got a certain IPv6 address, and sends out neighbor solicitations.  The linux gateway will respond only when it hears its own address.  We can tell it to respond on behalf of the hosts on the home network by installing ndppd.

wget http://priv.nu/projects/ndppd/files/ndppd_0.2.3-1_amd64.deb
sudo dpkg -i ./ndppd_0.2.3-1_amd64.deb

Then configure it (/etc/ndppd.conf):
proxy eth1 {
    rule 2a02:1810:xxxx:xxxx::/64 {

Now start ndppd:
sudo service ndppd start

And that's it.. now the gateway will respond to IPv6 neighbor solications on eth1 for the entire /64 network.
You should not be able to get to IPv6 enabled websites from within your home network.  Most modern Windows computers will automatically configure themselves after the setup above.  Give it a try and navigate to http://test-ipv6.vyncke.org/  and you should see a confirmation.