IPv6 tunnels on DD-WRT with 3.x kernel builds

5
DD-WRT Web Interface on the ASUS RT N66U

DD-WRT has recently been compiling firmware’s using the 3.x Linux kernel compared to the 2.4 and 2.6 builds. These newer kernel builds provide various improvements to the firmware. Being someone has been using K2.6 builds for a while, I decided to take the plunge and upgrade and check out how my setup worked on 3.x builds. One major setup I have is a Hurricane Electric tunnel setup on the router for IPv6. This didn’t work the same way it did on K2.6 and required some additional work. Here’s my adventures of IPv6 in DD-WRT on the 3.x builds. Hopefully providing some useful information for anyone else wanting to do the same thing

My setup:

  • Router: ASUS RT N66U
  • Firmware: v24-sp2 22118 Big K3.x

Requirements:

  • jffs – To store custom ipv6 modules, to load into the kernel
  • USB – A flash/hard drive partitioned for Optware (See this guide)
  • Optware using opkg: (See this Trac ticket)

A bit of a note, I’ll use the term Optware loosely here, On K2.6 Optware was available with various custom scripts written by frater and then further developed by basmaf. Optware on K3.x builds requires a complete overall due to the kernel change (ipkg/ipkg-opt can no longer be used). Currently the K3.x version of Optware is literally just using opkg (OpenWRT packages), with none of the previous custom scripts having been rebuilt for 3.x yet (this is a very big task). However the use of opkg will be perfect for IPv6 requirements, plus you can install many additional packages like nano, zabbix_agentd etc.

Assumptions:

  • This article assumes you already know how to setup an IPv6 tunnel on DD-WRT e.g. using HE.net (Hurricane Electric) or SixXS
  • Basic Linux knowledge
  • Comfortable with SSH access
  • Have some spare time to do all of this!

What’s under the hood?

First of all, there are various different 3.x kernel builds around, you first need to establish what kernel you are running, a simple command like:

uname -r

Will give your kernel version number. e.g. 3.10.2. You can run the command below that will automatically search for what IPv6 modules you have already in the firmware.

find /lib/modules/$(uname -r)/kernel/ -name *6*

The returned result will look something like this:

/lib/modules/3.10.2/kernel/crypto/sha256_generic.ko 
/lib/modules/3.10.2/kernel/fs/nls/nls_cp936.ko 
/lib/modules/3.10.2/kernel/lib/crc16.ko 
/lib/modules/3.10.2/kernel/lib/raid6 
/lib/modules/3.10.2/kernel/lib/raid6/raid6_pq.ko 
/lib/modules/3.10.2/kernel/net/ipv6 
/lib/modules/3.10.2/kernel/net/ipv6/ipv6.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6_tables.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6t_MASQUERADE.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6t_NPT.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6t_REJECT.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6t_mh.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6table_filter.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6table_mangle.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/ip6table_nat.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/nf_conntrack_ipv6.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/nf_defrag_ipv6.ko 
/lib/modules/3.10.2/kernel/net/ipv6/netfilter/nf_nat_ipv6.ko 
/lib/modules/3.10.2/kernel/net/l2tp/l2tp_ip6.ko 

The build I am running gives me nearly all the kernel modules required, the modules I was interested in were:

ip6_tables
ip6t_REJECT
ip6table_filter
nf_defrag_ipv6
nf_conntrack_ipv6

Because I am running a fairly large size build, you will probably not have all these modules already in the firmware. If that is the case your going to need to get your hands dirty and compile them manually. Doing this, requires a fair bit of work initially and hence is covered in another post, but its valuable experience.

Regardless of the presence of the above modules there is also one module that I had to compile manually and that was:

ip6t_rt

Why do I need these IPv6 modules?

Assuming you’ve read the other post about compiling modules, hopefully it has been able to help you get the required IPv6 modules. These modules are in fact for ip6tables, which is the firewall solution we will use to protect our network. The truth is, you don’t have to have ip6tables to have IPv6 connectivity, but in reality, having no IPv6 firewall is a bad idea. Because IPv6 has no NAT, so this means ports like 3389 (Microsoft Remote Desktop) and other pretty serious ports are going to potentially be wide open to the outside world. So we need these modules to create strong ip6tables rules to firewall our IPv6 clients, while allowing IPv6 connectivity.

More tunnel related dependencies

Up until recently before the following change committed to SVN. DD-WRT did not automatically load the ip_tunnel module by default in the 3.x builds, this meant that any IPv6 stuff would fail, as ip_tunnel is a must for IPv6 tunnels, the sit module is also required which is loaded but because the ip_tunnel module is a dependency, it wouldn’t actually be loaded either. With this information you will need to make sure that you load the ip_tunnel module before the IPv6 stuff, this will be automatically loaded in builds after 22118, but for now you’ll need to load them.

ip_tunnel
sit

Loading the custom ipv6 modules:

This is where jffs comes in handy, you have the modules but now what? Putting them on your jffs partition is a handy as ultimately you’ll be able to insmod the modules on boot in your .rc_startup script. For now however you’ll want to manually load each module in order to confirm each one loads without error.

Create a directory on jffs to hold the modules

mkdir -p /jffs/lib/modules/$(uname -r)

This will create a directory name matching your kernel version. Now move your custom ipv6 modules into this folder, you can do this via SCP, FTP many different ways. Now its time to test the modules to see if they work. This can be done using insmod, you should load the modules in the following order:

ip_tunnel
sit
ip6_tables
ip6t_REJECT
ip6table_filter
nf_defrag_ipv6
nf_conntrack_ipv6
ip6t_rt

Now, if you are loading modules that are already within the firmware, you can simply run:

insmod [module_name]

If however, you are wanting to insmod a custom compiled module stored on jffs, you will need to specify the full path e.g.

insmod /jffs/lib/modules/$(uname -r)/[module_name].ko

Replace [module_name] with the actual module name e.g. ip6r_rt. Observe any errors when loading the modules (if any), if you run the command and it completes without any output, its usually a good sign that the module loaded successfully, you can re-run the insmod command again, you will most likely get something like this:

insmod: can't insert 'ip_tunnel': File exists

This means the module loaded. If you get any errors, its usually because of dependencies. You can run:

dmesg

To find out what caused the module not to load, often errors include, unknown symbol, which again is nearly always a missing module that is a dependency. See how BrainSlayer (Lead dev of DD-WRT) gave me a quick lesson in module dependencies.

Loading these modules on boot

Now that you have tested the modules, these need to be loaded on boot, you can put something similar to this in your startup script:

insmod ip_tunnel
insmod sit
insmod ip6_tables
insmod ip6t_REJECT
insmod ip6table_filter
insmod nf_defrag_ipv6
insmod nf_conntrack_ipv6
insmod /jffs/lib/modules/$(uname -r)/ip6t_rt.ko

Note: Adjust the location of modules to match your setup. As I said earlier, having the big builds of DD-WRT allows the firmware to have most of the modules compiled in already, adjust paths accordingly for your situation, its likely you’ll be loading most of them off jffs.

Once you’ve done that, click save and these modules will now get loaded on boot permanently. Reboot your router to confirm, you can run:

lsmod

To see the list of modules loaded. Confirm ALL the mentioned modules appear.

Upgrading ip6tables

DD-WRT 3.x builds (or at least bigger builds) does come with ip6tables already compiled in, the problem is the version is a bit old (1.3.7) and this mean you could potentially end up seeing this error with various chains:

ip6tables v1.3.7: Couldn't find match `rt' 

ip6tables 1.3.7 doesn’t work with rt, even if the module is loaded. An updated ip6tables version is required. In comes opkg to solve this problem:

opkg --force-depends install kmod-ip6tables 
opkg --force-depends install ip6tables

The output of this is going to look like it failed horribly, when in fact its actually OK. You don’t need to worry about this messing up your firmware, remember this is all on the /opt partition. Despite all of the errors a newer version of ip6tables should have installed, you can confirm this by running:

whereis ip6tables

You should get two paths returned:

ip6tables: /usr/sbin/ip6tables /opt/usr/sbin/ip6tables

Reboot your router and ip6tables should now be using the opt version when it comes back up, you can confirm this by simply running “ip6tables” which should give you:

ip6tables v1.4.19.1: no command specified
Try `ip6tables -h' or 'ip6tables --help' for more information.

The version number may differ, but if its higher than 1.3.7, you’ve got a newer version of ip6tables. Interestingly, iptables also seems to get a upgrade, but again this will function as normal, any rules you already have in your firewall startup script will continue to work!

This isn’t the most elegant solution to upgrading ip6tables, if you want a more cleaner solution, you could compile ip6tables yourself specifically for the MIPS architecture and then copy the compiled content onto /opt but I won’t go into that here. The dirty way is fine, though this will cause some errors to be printed each time you run opkg.

The IPv6 firewall with ip6tables

Now its time to load ip6tables with some firewall rules, the DD-WRT community has provided some great firewall solutions for two of the major IPv6 tunnel providers, HE.net and SixXS, you can find them here:

If you use another IPv6 tunnel broker, search around for some IPv6 firewall rules, or formulate generic rules.

With the above ip6tables rules, all you need to do is put them in your firewall script (where you put normal iptables a.k.a ipv4 rules). Reboot your router and see if you’ve got IPv6 connectivity. Some good test sites are:

After this you should have IPv6 connectivity with your IPv6 enabled clients protected by the firewall on the router.

Share This:

  • esco

    James, would you be so kind to provide a short info about how to setup Optware with 3.x kernels?

    Thanks!

    • Optware doesn’t really exist for 3.x builds yet. Basmaf has been working on getting opkg packages working on the K3.x but that’s has far as Optware development is so far. I can however write a post about doing that if you’d like?

  • whoiscuriousgeorge .

    Wow, IPv6 support has gotten a lot more complicated since I used it on a WRT54GS router years ago, it used to be a simple case of enabling it in Administration -> Management, enabling radvd, sticking in a stock script for radvd then adding a startup script under Administration -> Commands and rebooting.

    I used to use this method with 6to4 as it doesn’t require a tunnel broker, it uses a generic one from 192.88.99.1 so no signup/IP monitoring, a degree of autoconfig makes it easier.

    How can I apply this in-depth guide to the 6to4 method? I already have a 2.5″ USB2 HDD connected to my TP-Link TL-WR1043ND which works for basic video streaming so I could make jffs/opt partitions if needed.

    • Mostly this write up is to allow proper securing of devices with ip6tables, as critical modules are required in order for filter rules to work, and this has changed slightly since K2.6. I didn’t actually go into configuration an IPv6 setup, seems as there are so many methods, but the general process is still the same, enable IPv6 and Radvd, then setup Radvd config depending on your IPv6 tunnel method.

      With the lack of NAT with IPv6, anyone running a IPv6 tunnel without ip6tables is just exposing their devices directly to the WAN side, possibly without even knowing. Anyone can test how secure their IPv6 setup is with the test below. Common ports like 80,443,3389 are likely exposed without proper firewall rules:

      http://ipv6.chappell-family.com/ipv6tcptest/

      I’d personally discourage the use of 6to4 as there is no liability and no guarantee of service. If you can, you consider using Hurricane Electric or SixXs, there are already scripts written for these tunnel providers to make deploying them on a DD-WRT router easy.

      The DD-WRT wiki does have info on 6to4 however:

      http://www.dd-wrt.com/wiki/index.php/IPv6#6to4_on_k2.6_builds

      It is listed for K2.6 builds, but applying similar thinking in this write up, should allow you to get the same result.

  • GregAndo

    Thanks for these articles James. I have an RT-AC66U and it is running newer DD-WRT firmware with the 3.10 kernel. When I got the tunnel working correctly, I noticed that by default my router had all its ports open on IPv6 and could be connected to by telnet or SSH from the greater IPv6 Internet with no blocking.

    I knew I would have to compile the modules myself as I could not find a precompiled source. I started running into issues with bad / dated documentation – some things still differed over time with your article but it was enough to get me over the line. I am not stateless, but at least I can filter the traffic heading into the router from the Internet now, and therefore it will be secure.

    Now if I can secure the my Windows box whose IPv6 address is now on the same adapter as my regular internal network and is therefore opening IPv6 ports I only want used internally out to the net without specifically blocking them with dedicated IPv6 rules!

    Anyway, thanks a lot. I hope your site keeps itself afloat!