Raspberry
This should be a manual for how to set up a IPv6-tunnel using a Raspberry Pi running on Debian. We assume you have a little experience on how to use your Raspberry with a tool like Putty, so the doing is just shown, not explained too much.
Feel free to edit.
Contents
Prerequisites
- an approved user account
- an approved tunnel with subnet, you chose the AYIYA-tunnel. If not, change it (that will cost credits)
- a ready-to-go Raspberry (if not, please do
sudo apt-get upgrade && sudo apt-get update
) - connection to Raspberry with Putty is open
You will see, when logged into your user account, that there is an approved "Subnet" containing a few information:
- Details, a Rxxxxx-number: We do not need that now.
- A Subnet-prefix like 2001:xxxx:xxxx:xxxx::/64. That is what we need!
- Tunnel endpoint: Not important now.
- Tunnel ID: We do not need that for setting up.
- Subnet name: Also not important now.
- State: Enabled. It should be enabled, right?
Setting up the Raspberry
Aiccu
First, we'll set up Aiccu, the client, which opens the tunnel and keeps it alive:
-
sudo -i
-
apt-get install aiccu
- During the installation, you will be asked for your SixXS-account. That is the user account information.
- If you installed the package without typing in the proper information, or you just did a mistake, finish the installation and open:
nano /etc/aiccu.conf
- Here, you will find right at the first lines the "# Login information". Add your details there and save the file.
- Restart the service afterwards:
service aiccu restart
- Let's check, if the tunnel is up:
ifconfig
- There should be a separate entry called something like "sixxs". An IP-address in IPv6 should be written next to a tag called "Scope:Global". If yes: Fine.
- I am sure you would love to see the result of your work, so let's ping an IPv6-page:
ping6 google.de
IPv6-Forwarding
We have to activate the routing between our LAN and the new tunnel:
-
sudo -i
-
nano /etc/sysctl.conf
- Search for the line containing
#net.ipv6.conf.all.forwarding=0
, uncomment it and set the value to "1":net.ipv6.conf.all.forwarding=1
- Let's restart our Raspberry:
reboot
- wait for restarting it and reconnect to it
-
sudo -i
- Now, we do need a fixed IP-address for our machine:
-
nano /etc/network/interfaces
- Add new lines:
# IPv6 iface eth0 inet6 static pre-up modprobe ipv6 address 2001:db8::1 netmask 64
Attention: Replace "2001:db8::1" completely by the "subnet prefix" information provided by Sixxs, the one we noted above and add "1" at the very end. The /64-thing is noted at "netmask"
Attention: If your are connected to your LAN not using interface "eth0", change that as well!
- Reboot it.
reboot
- wait for reboot and connect to your Raspberry again.
-
sudo -i
-
ifconfig
- Check at eth0 by using
ifconfig
if your new address has been applied. The tag is once again "Scope:Global".
Radvd
Now we need a tool called "Radvd", which does "Router-Advertising". It will distribute your IPv6-addresses to your network.
-
sudo -i
-
apt-get install radvd
-
nano /etc/radvd.conf
- Now enter the following code:
interface eth0 { AdvSendAdvert on; AdvManagedFlag on; AdvOtherConfigFlag on; AdvLinkMTU 1280; MaxRtrAdvInterval 300; prefix 2001:db8::/64 { AdvOnLink on; AdvAutonomous on; AdvRouterAddr on; }; };
Attention: Remember to use your own prefix. And enter another interface, if you are not connected to your LAN with "eth0"!
-
service radvd start
orservice radvd restart
, if the deamon is already up (you'd get an error message). - Now try to have a look, if the world can reach your Raspberry using IPv6. Visit Test-IPv6.com and ping it by entering the fixed IP-address you defined at /etc/network/interfaces.
Firewall
Well, we are connected now, but everybody can access each machine in your network just as he or she wants. That's probably the worst idea we ever had.
Setup
-
sudo -i
-
cd /etc/network
-
nano ip6tables.rules.sh
#!/bin/sh # Flush all existing rules ip6tables -F ip6tables -X ip6tables -t mangle -F ip6tables -t mangle -X # Allow all connections via the tunnel which came from inside our LAN ip6tables -A INPUT -i sixxs -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow connections from localhost to localhost ip6tables -A INPUT -i lo -j ACCEPT ip6tables -A OUTPUT -o lo -j ACCEPT # Allow all connections from our own LAN ip6tables -A INPUT -i eth0 -j ACCEPT ip6tables -A FORWARD -i eth0 -o eth0 -j ACCEPT ip6tables -A OUTPUT -o eth0 -j ACCEPT # Allow all outgoing connections via our tunnel ip6tables -A OUTPUT -o sixxs -j ACCEPT # Allow forwarding packages with No-Next-Header ip6tables -A FORWARD -p ipv6-nonxt -m length --length 40 -j ACCEPT # Allow all link-local connections ip6tables -A INPUT -s fe80::/10 -j ACCEPT ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT # Allow all multicast-connections ip6tables -A INPUT -d ff00::/8 -j ACCEPT ip6tables -A OUTPUT -d ff00::/8 -j ACCEPT # Allow ICMPv6 ip6tables -I INPUT -p icmpv6 -j ACCEPT ip6tables -I FORWARD -p icmpv6 -j ACCEPT ip6tables -I OUTPUT -p icmpv6 -j ACCEPT # Allow forwardings ip6tables -A FORWARD -m state --state NEW -i eth0 -o sixxs -j ACCEPT ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT ip6tables -A FORWARD -m state --state INVALID -j DROP # Drop all packages with RH0-header ip6tables -A INPUT -m rt --rt-type 0 -j DROP ip6tables -A FORWARD -m rt --rt-type 0 -j DROP ip6tables -A OUTPUT -m rt --rt-type 0 -j DROP ## Incoming connections from outside we wish to have ## # Allow incoming connections to port 22 (SSH) #ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT # Allow incoming connections to port 80 (HTTP) #ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT # Default-Settings ip6tables -P INPUT DROP ip6tables -P FORWARD DROP ip6tables -P OUTPUT DROP
ATTENTION: Please uncomment the "incoming port 22" and "incoming port 80" rules, or perform further rules, if you want to accept incoming connections on any port you need.
ATTENTION: Please note that these rules may not be correct and can cause severe damages to your network. SixXs and the author recommend to check these rules by yourself before applying them.
- Let's make this file executable and execute it.
-
chmod 744 ip6tables.rules.sh
-
./ip6tables.rules.sh
- We'll check at IPv6Scanner.com, if the firewall is working as we wish. Do a ping on your Raspberry-IP (remember, the one you defined at /etc/network/interfaces). We should now see orange buttons only. If we allowed connections to specific ports, we should see them in green.
- You can see at
ip6tables -nvL
, what has been accepted and which connections have been dropped. - If that is ok, we want to have these rules to be applied after each reboot. Otherwise, our Raspberry will forget them after rebooting.
-
cd /etc/network/if-pre-up.d
-
nano ip6tables-load
- Enter text:
#!/bin/sh ip6tables-restore < /etc/ip6tables.rules exit 0
- Making it executable:
chmod 755 /etc/network/if-pre-up.d/ip6tables-load
- Execute it:
cd /etc/network/if-post-down.d
-
nano ip6tables-save
- Enter text:
#!/bin/sh ip6tables-save -c > /etc/ip6tables.rules if [ -f /etc/ip6tables.downrules ]; then ip6tables-restore < /etc/ip6tables.downrules fi exit 0
- Making it executable:
chmod 755 /etc/network/if-post-down.d/ip6tables-save
- And execute it:
/etc/network/if-post-down.d/ip6tables-save
Now you should be able to see all of your clients in the LAN to get IPv6-addresses. This should work pretty fast.
We're done!
NTP issues
On a Raspberry Pi (with Raspbian 8), the system clock is not set correctly on startup (although, thanks to the fake-hwclock package, on simple reboots it is only off by about 30 seconds which is within the 120 second margin AICCU demands). So, we want aiccu to start only when the time is synced. I (PVD99-RIPE) have tried various approaches regarding systemd's time-sync target, but that target does not promise synced time, it just promises the systemd-timesyncd has started. If you are using ntp, the time-sync target does nothing at all. For now I have worked around this by editing /etc/init.d/aiccu like this (inserting the until .. line at line 75):
# Verify that it is in daemonize mode, otherwise it won't ever return if [ `grep -c "^daemonize true" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then log_failure_msg "AICCU is not configured to daemonize on run" exit 1; fi until ntpq -c 'rv 0' | grep -qw sync_ntp ; do sleep 1 ; done # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started
With this change, aiccu comes up for me reliably. This hack could be turned into a systemd unit file that waits for NTP to be synced in the same way and only then allows aiccu to start.
Note: the ntp-wait tool, which comes recommended for these situations, needs 15 minutes to be happy for leap second related reasons. The hack above introduces a 5-10 second delay for me for starting aiccu (while not holding up the rest of system boot, including sshd).
Another way could be installation of ntpdate (apt-get install ntpdate -y) and put "@ reboot /usr/bin/ntpdate -s 0.pool.ntp.org" in your crontab (crontab -e).