Sunday, 27 February 2011

Compiling ping6 for DD-WRT

Hi all, time for another relatively easy build, but one I've been asked for before, ping6. I used gun inetutils ping6, here's how to get going.

With your cross compile environment set up using instructions from my previous post, get and unpack the inetutils source:

# wget http://ftp.gnu.org/gnu/inetutils/inetutils-1.8.tar.gz
# tar xzvf inetutils-1.8.tar.gz
# cd inetutils-1.8

You'll see what I mean when I say this is one of the easy ones. This package contains a lot of other applications with you probably don't want, including ifconfig (which I haven't yet worked out how to compile). To configure and build ping6, just do the following 2 commands:

# ./configure --host=mipsel-linux-uclibc --disable-clients --disable-servers --disable-ifconfig
# make

Assuming that went without a hitch, your new shiny ping6 binary can be found in the ping6 subdirectory. Copy that to your router and give it a go!

Next week I have a quick guide to an alternative use for DNSmasq.

Sunday, 20 February 2011

Compiling ISC DHCP 4.2.0 DD-WRT

Afternoon all, time for me to share how I compiled dhcpv6. This is not the smallest implementation by a long way, so make sure you have plenty of free space on your rotuer for it. I have been looking at compiling other, smaller implementations but as yet I don't have any working builds. Here's how I got ISC DHCP 4.2 compiled and working.

Firstly you'll need to grab and unpack the source:
# wget http://ftp.isc.org/isc/dhcp/dhcp-4.2.0-P2.tar.gz
# tar xzvf dhcp-4.2.0-P2.tar.gz
# cd dhcp-4.2.0-P2

As I said before, this one was a little tricky, and getting it passed the configure stage involved many hours of Googling. The first issue is that it fails trying to work out where /dev/random should be as it is a cross compile environment, the for the bind libraries it fails to set the correct compilers up. So here's what we do.

# echo ac_cv_file__dev_random=yes > config.cache

This fools the configure script into thinking it's found /dev/random, we can now configure.

# ./configure --prefix=/opt --host=mipsel-linux-uclibc --cache-file=config.cache

The next bit is a little strange, but it works. We will run make, but we will cancel it as soon as it has unpacked the bind source with Ctrl+C. So:

# make

As soon as it says "Configuring BIND Export libraries for DHCP" press Ctrl+C to cancel. We need to make some small changes. (I probably should do a patch for this).

Open this file in your favorite text editor:

bind/bind-9.7.1/lib/export/dns/Makefile.in

Change ${CC} on line 163 to ${BUILD_CC}. Next modify this Makefile:
bind/Makefile

Line 48, replace ./configure with
BUILD_CC=gcc ./configure --host=mipsel-linux-uclibc --with-randomdev=/dev/random

Change back into the DHCP directory and start the build again.

# make
# make install

Copy the files over the same way we did last time. Now you've got it installed, time to get it working. DHCPv6 does not work the same way as DHCP, and is not the first port of call for clients. First, tell radvd that we have DHCPv6 for 'other' configuration information, not IPv6 addresses, so modify radvd config to look like to following in the UI:

interface br0 { 
    AdvSendAdvert on; 
    AdvHomeAgentFlag on; 
    AdvLinkMTU 1480; 
    MinRtrAdvInterval 3; 
    MaxRtrAdvInterval 10;
    AdvOtherConfigFlag on; // this is the new flag to add
    prefix 2001:db8:: { 
        AdvOnLink on; 
        AdvAutonomous on; 
        AdvRouterAddr on; 
    };
};

Next, we need to configure DHCP itself. Create the /opt/etc/dhcpd6.conf

default-lease-time 600;
max-lease-time 7200;

lease-file-name "/tmp/dhcp6.leases";

subnet6 2001:db8::/64 {
        option dhcp6.name-servers 2001:db8::1;
}

This is all that is required to tell clients to use IPv6 DNS servers. Change the prefix and name server as applicable for your network. DNSmasq supports IPv6 for dns forwarding, so we'll configure that next. In the UI for DNSmasq Additional Options, add:

interface=br0
server=2a01:348:0:1::e:1
server=2a01:348:0:1::f:1
server=8.8.8.8
server=8.8.4.4
no-resolv
strict-order

Replacing all the server= lines with the addresses of the upstream DNS servers you wish to use. The eagle eyed amongst you will notice that the IPv4 addresses are Google's dns service. The IPv6 ones are provided by Goscomb Technologies. Upstream IPv6 DNS servers are a requirement to access services that use what is known as 'dns whitelisting', that is, AAAA records are only served with end-to-end IPv6 connectivity.

The other 2 options override the resolv.conf and force it to try the IPv6 DNS servers first.

We now need to allow these new services in the firewall, with these commands:

# ip6tables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
# ip6tables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
# ip6tables -A INPUT -i br0 -p tcp -m tcp --dport 547 -j ACCEPT
# ip6tables -A INPUT -i br0 -p udp -m udp --dport 547 -j ACCEPT

Add these to startup/firewall.

Also add this following line to startup make DHCPv6 start at boot:
dhcpd -6 -cf /opt/etc/dhcpd6.conf br0

Because of the amount of settings we've just change, I recommend you reboot your router. Once it's started you should have a working DHCPv6 server! Not all clients support DHCPv6 out of the box so you may need to do some tweaking. I can however confirm that this setup does work with Windows 7.

Now assuming I've not made any silly mistakes, that should be all you need to get that going. If there are any I'm sure you guys will be kind enough to point them out for me. I will be attempting other implementations of DHCPv6 that will hopefully be smaller and more lightweight. Next time (by request) will be instructions on compiling your own ping6. Those of you who asked about kismet will have to wait a while, as I am having more difficulty with that than DHCP.

Edit 2011-02-22: Added interface=br0 to the DNSmasq options as I discovered it didn't listen on IPv6 by default.

Sunday, 13 February 2011

Compiling ip6tables DD-WRT

Firstly, I'd just like to inform you all that it appears that I'm not the only person to have done this. Whilst Googleing certain terms, I discovered another blog containing posts on setting up aiccu, radvd and ip6tables on DD-WRT here: http://blog.dest-unreach.be/. Please be aware that these blog have both been written independently no-one has stolen anything from the other.

Right then, back to the post topic, compiling ip6tables. For this, not only did I compile the kernel modules but the ip6tables binaries. From last time you should have the cross-compile environment set up. Add the toolchain relevant to you to you path:
# PATH=$PATH:/opt/toolchain-mipsel_3.3.6_BRCM24/bin
I've used the gcc3.3 version of the toolchain as I had some display issues when compiling with 4.2.

First, we'll compile the needed kernel modules. This line I did steal from the other blog. I distinctly remeber running into this error, so in you linux source directory, run
# echo "#define JHASH_GOLDEN_RATIO    0x9e3779b9" >> include/linux/jhash2.h
I added to following kernel options to .config
CONFIG_NF_CONNTRACK_IPV6=m
CONFIG_IP6_NF_IPTABLES=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_OWNER=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
CONFIG_IP6_NF_MATCH_AH=m
CONFIG_IP6_NF_MATCH_MH=m
CONFIG_IP6_NF_MATCH_EUI64=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
Once you've added that, make sure that all dependencies are selected. You may also be asked for more options.
# make oldconfig
And to compile
# make modules
If you get errors about madwifi that force the build to fail, and don't need the madwifi drivers, the other blog mentioned earlier has a small snippet to get rid if that error.

The next thing to do is cd into the folder with the ip6tables modules and strip debugging symbols to make it nice and small.
# cd net/ipv6/netfilter
# mipsel-linux-uclibc-strip --strip-unneeded *.ko
And that should be it. You have now compiled all the modules we need to make ip6tables work. Copy these onto your router.

Now we'll move on to something more useful to our followers, compiling applications. The first one we'll do is the ip6tables userspace utilities. Please bear in mind that not all applications will compile easily or without tweaking. Firstly, grab and unpack the source code.
# wget http://www.netfilter.org/projects/iptables/files/iptables-1.4.10.tar.bz2
# tar -xjvf iptables-1.4.10.tar.bz2
# cd iptables-1.4.10
Now ip6tables is one of the easiest things to compile, as it seems to need little or now tweaking. Most configure scripts support a --host parameter which enables you to specify which platform to cross compile to. I also use --prefix=/opt so I can find just the binaries once compiled easily. We also only want the IPv6 version, as the IPv4 version is already installed.
# ./configure --prefix=/opt --host=mipsel-linux-uclibc --disable-ipv4
If that worked without any errors, you can now build ip6tables and optionally install them to whatever you set prefix as above. If you need to, run the install as root.
# make
# sudo make install
As I install DD-WRT stuff only to /opt, we can go though all the directories to strip the binaries to make them smaller.
$ cd /opt/bin
$ mipsel-linux-uclibc-strip --strip-unneeded *
$ cd /opt/sbin
$ mipsel-linux-uclibc-strip --strip-unneeded *
$ cd /opt/lib
$ mipsel-linux-uclibc-strip --strip-unneeded *.so
$ cd /opt/libexec/xtables
$ mipsel-linux-uclibc-strip --strip-unneeded *.so
We can also dispense with any man pages
$ rm -rf /opt/share
I find the easiest way to get these files onto the router is to tar them, scp the tar and extract it on the router. I have my usb stick mounted to /opt, too.
$ tar czvf ~/opt.tar.gz /opt
$ scp ~/opt.tar.gz root@router:/tmp
$ ssh root@router
(ssh) $ tar xzvf /tmp/opt.tar.gz -C /
(ssh) $ rm /tmp/opt.tar.gz
If all went well, you should now be able to run the following command without errors:
$ ip6tables -L
That's about it really, doesn't that look less painful. No we just need to create some rules! There are some things to remember here, certain classes of icmpv6 messages are required in all cases. I've not distinguished between them, however. For now, this should be sufficient:
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
ip6tables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -P INPUT DROP
That allows the required icmpv6, related connections and ssh connections over IPv6 to the router. We'll add more later on when we come to use DHCPv6 and then DNS over IPv6. It may be wise to add these commands to startup.

Next time we'll have a go at DHCPv6, a more complicated example which took me many hours and much Googling just to get passed the configure stage. I'm also going to attempt kismet drone at some point in the near future.

Monday, 7 February 2011

DD-WRT Cross Compile Environment

At some stage you'll want to build and run software on your router that wasn't bundled with it, especially if you bought an open source one like I did. You will need a 64bit Linux environment, as the DD-WRT mips toolchains are built for I used Debian Lenny in Virtual Box to do this. You'll need a basic toolchain and subversion installed, so if like me you use Debian you'll need to install the subversion and build-essential packages. This page is adapted from the guides on the DD-WRT wiki.


Firstly get yourself the toolchains from http://www.dd-wrt.com/dd-wrtv2/downloads/others/sourcecode/toolchains/current-toolchains.tar.bz2 and extract. Be sure to add them to your path.

The next thing you need is the kernel source for the kernel you are running. I'm currently using 2.6.24.111 (which is wrongly labelled 2.6.23 in subversion). To get that run

svn co svn://svn.dd-wrt.com/DD-WRT/src/linux/brcm/linux-2.6.23

This also quite handily comes with the configuration they used to build the image. To use it:

cp .config_std .config
make oldconfig

That's the kernel sorted. From what I can remember at this stage, that's all I required to get going. Next time, we'll build ip6tables and get that installed on the router.