IPv6 SpeedTouch
The Thomson Speedtouch USB modem provides a very low cost way of getting a native IPv6 connection running over PPPoA, giving you the full 1500 Byte MTU. They can be bought second hand on eBay for £5 to £10.
My configuration is based on a Linksys NSLU2 running Debian Squeeze (testing). However, any Debian (or Ubuntu) box should work fine, and I am not aware of anything in this configuration that would not work in Debian Lenny (stable).
Debian on the NSLU2
The NSLU2 has the advantage of running on very low power (<5W) and silently. A Sheevaplug or similar would be a good alternative. An excellent guide to installing Debian on the NSLU2 (and Sheevaplug) can be found on Martin Machlmayr's site.
Configuring the Speedtouch modem
Configuring the Speedtouch modem on recent versions of Debian is straightforward. Firstly, you need to obtain the USB firmware for the Modem. I obtained my copy here. Other possible locations and more comprehensive guide to setting up the Speedtouch USB modem on Ubuntu (or Debian) can be found here.
Download the firmware and unpack it:
# wget http://ftp.linux.it/pub/People/md/warez/speedtouch-firmware.tgz
# tar -xvzf speedtouch-firmware.tgz
The files you have just unpacked are driver files for the modem. They are architecture independent, so whether you're using an ARM based system like the NSLU2 or an x86 box doesn't matter. However, the files you use do depend on the version of the modem you have. My modem is the silver v4 variant, and the files ending in '.4' were the versions I needed. So, for example:
# cp firmware/speedtch-1.bin.4 /lib/firmware/speedtch-1.bin
# cp firmware/speedtch-2.bin.4 /lib/firmware/speedtch-2.bin
Next, install the necessary ppp and atm libraries:
# apt-get install ppp libatm1
Configuring the ADSL Connection
Copy the example ADSL configuration file for PPPoA to the /etc/ppp/peers directory and call it aaisp:
# cp /usr/share/doc/ppp/examples/peers-pppoa /etc/ppp/peers/aaisp
Next, edit /etc/ppp/peers/aaisp for the aaisp connection. Change the username near the top of the file to your aaisp username, so the line should read (for example):
user "myusername@a.1"
The VPI and VCI need to be replaced with the values in use in the UK (0 and 38 respectively), so replace the existing line with:
0.38
The rest of the file worked OK for my configuration.
IPv6 Configuration
Again in /etc/ppp/peers/aaisp, you need to add a line to the file to tell it to bring up ipv6. The addresses after the ipv6 option are the link local addresses, and are not related to the ipv6 address range for aaisp. So just use something like ::1 and ::2 unless you've reason to do otherwise. Just add a line to the file:
ipv6 ::1,::2
When ppp is started, if ipv6 comes up correctly, any files in the /etc/ppp/ipv6-up.d/ directory will be run. Create a file and call it, say, /etc/ppp/ipv6-up.d/start-ppp0-ipv6. This file holds the ipv6 range given to you by aaisp. You'll also need to tell it that the default route is through the new ppp link as this doesn't seem to happen automatically when ppp is started. Include the following lines in the file:
#!/bin/bash
/sbin/ip -6 addr add 2001:8b0:xxxx::1/64 dev $1
/sbin/ip -6 route add default dev $1
Replacing xxxx by the appropriate address given to you by Andrews & Arnold. You'll need to chmod 755 the file you just created so that it can be executed when ppp comes up.
This should be everything you need to bring up ADSL and ipv6. Keep your fingers crossed and type:
# pon aaisp
You'll also probably want to execute this command when the system starts. I included it in /etc/rc.local (as /usr/bin/pon aaisp). I'm not entirely happy with this, as there may be an issue with timing and debian reaching rc.local before the modem is fully initialised, but it's always worked fine for me. More elegant suggestions are welcome.
ifconfig should now show a ppp0 connection with the ipv4 address allocated automatically, and the newly configured ipv6 address.
LAN configuration
On the LAN side of your Linux box you want to configure a LAN address. This will usually be a different subnet. In my case, I chose 2001:8b0:xxxx:1::/64. Edit /etc/network/interfaces, and include the following lines (assuming your LAN interface is eth0):
iface eth0 inet6 static address 2001:8b0:xxxx:1::1 netmask 64 up echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
Also, install and configure radvd if you wish to advertise the appropriate ipv6 subnet on the LAN.
Firewall
You'll probably also want to ensure your LAN is protected from the big bad internet by a firewall. I did this by including two files in /etc/network/if-up.d/.
Here's my iptables for ipv4 (/etc/network/if-up.d/iptables):
#!/bin/sh PATH=/usr/sbin:/sbin:/bin:/usr/bin # # delete all existing rules # iptables -F iptables -t nat -F iptables -t mangle -F iptables -X # # Set the defaults to drop packets # iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # # Always accept loopback traffic # iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # # Accept all packets to/from the local LAN # iptables -A INPUT -i eth0 -j ACCEPT iptables -A OUTPUT -o eth0 -j ACCEPT # # Allow established connections, and new connections established on the LAN # iptables -A INPUT -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -o ppp0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -i ppp0 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -o ppp0 -i eth0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # # Masquerade (NAT) # iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE # # Here's an example port forwarding rule to forward all traffic to port 80 to 192.168.1.2 # iptables -t nat -A PREROUTING -i ppp0 --dport 80 -j DNAT --to-destination 192.168.1.2 iptables -A FORWARD --dport 80 -d 192.168.1.2 -j ACCEPT # Enable routing echo 1 >/proc/sys/net/ipv4/ip_forward
And here's the slightly simpler ip6tables (/etc/network/if-up.d/ip6tables):
#! /bin/bash # # Flush all tables and establish default policy # ip6tables -F INPUT ip6tables -F OUTPUT ip6tables -F FORWARD # ip6tables -P INPUT DROP ip6tables -P OUTPUT DROP ip6tables -P FORWARD DROP # # Accept all packets on the loopback interface # ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT # # Accept anything from/to the local LAN (eth0) # ip6tables -A INPUT -i eth0 -j ACCEPT ip6tables -A OUTPUT -o eth0 -j ACCEPT # # Accept sessions established by this box # ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # # Accept sessions created inside the firewall # ip6tables -A FORWARD -i eth0 -o ppp0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD -o eth0 -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT # # Here's an example of accepting a request to port 80 from an external address to a specific server # ip6tables -A FORWARD -i ppp0 --dport 80 -d 2001:8b0:xxxx:1::2 -j ACCEPT
Finally don't forget to chmod +x these two files to ensure they'll execute when the interfaces come up.