1 (edited by hnyman 2011-02-24 20:17:32)

Topic: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

Configuring OpenWrt Backfire 10.03.1-rc4 for a static 6in4 tunnel from SixXS to get IPv6 connectivity


I was looking for information about configuring my router (originally Netgear WNDR3700) for supporting a static 6in4 tunnel from SixXS for getting the IPv6 connectivity. The router is currently running OpenWrt Backfire 10.03.1-rc4, published in November 2010, the rc4 version of the forthcoming Backfire Interim Release 1.

Current OpenWrt Backfire 10.03.1-rc4 has an installable package for supporting the 6in4 tunnels, which should make the process relatively easy. However, finding the exactly correct configuration is not that easy. I found useful information in internet, but it was scattered around and to some extent also outdated or incomplete. I write this article to summarize my findings and to list my configuration as an example for others trying to do the same.

Additionally, the rc4 version does not enable configuring some of the required steps through the Luci GUI, so some tasks have to be done by editing configuration files manually.

Background assumptions: you have a "Static" 6in4 tunnel with a fixed tunnel endpoint from SixXS. You also have a subnet, which is routed through that tunnel. You also have installed the OpenWrt to the router.

Main steps in the process:
Configuring the tunnel
Configuring iptables to make sure that the tunnel stays up
Configuring IPv6 address autoconfiguration inside local LAN by using RADVD
Configuring ipv6 firewall - ip6tables


1) Configuring the tunnel

The main steps are explained pretty well in http://wiki.openwrt.org/doc/howto/ipv6 , which is mostly up-to-date. However, it does not discuss SixXS specific issues.

First you need to make sure that the IPv6 support modules and the 6in4 tunnel module have been installed either by using Luci GUI or by running the following command:
  opkg install kmod-ipv6 radvd ip kmod-ip6tables ip6tables 6in4

The file '/etc/config/network' needs to be manually edited to include a new interface for the tunnel that will be called 'sixxs':

  config 'interface' 'sixxs'
    option 'proto' '6in4'
    option 'peeraddr' '62.78.96.38'
    option 'ip6addr' '2001:14b8:XXXX:XXXX::2/64'
    option 'ipaddr' '62.78.XXX.XXX'

(peeraddr is the remote PoP tunnel endpoint IPv4 address and optional, ip6addr is the IPv6 tunnel endpoint address at your end, ipaddr is the router's IPv4 WAN address.)
Note: Make sure that there is no "defaultroute=0" statement added by Luci. It may try to automatically add that statement if you just visit the interface's settings in Luci. If you later experience IPv6 traffic problem, double check this.

Additionally, the IPv6 address in the local subnet is added to the router's LAN interface either through Luci (Network/Interfaces/LAN) or by editing the file '/etc/config/network' :

  config 'interface' 'lan'
    option 'ifname' 'eth0'
    option 'type' 'bridge'
    option 'proto' 'static'
    option 'ipaddr' '192.168.1.1'
    option 'netmask' '255.255.255.0'
    option 'defaultroute' '0'
    option 'peerdns' '0'
   option 'ip6addr' '2001:14b8:YYYY:YYYY::1/64'

(ip6addr is the router's IPv6 address in the new local subnet.)

Third step is to add the new 'sixxs' interface to the 'wan' zone of the firewall. Either use Luci (Network/Firewall/Zones) or edit '/etc/config/firewall' :

  config 'zone'
    option 'name' 'wan'
    option 'network' 'wan sixxs'

Fourth task is to make sure that the following line in '/etc/sysctl.conf' is uncommented:

  net.ipv6.conf.all.forwarding=1

2) Making sure that the tunnel stays up - iptables

SixXS pings the static tunnel every 30 minutes and the router needs to respond to that ping, otherwise the tunnel gets turned off. With the default iptables configuration, the router may forget the tunnel connection in the NAT table if there is no IPv6 traffic for a while. You have to make sure that the incoming IPv6 pings from SixXS get accepted even then.

The suggested entry in the SixXS FAQ does not work properly in the OpenWRT 10.03.1-rc4 ( https://www.sixxs.net/faq/connectivity/?faq=conntracking ).

Instead you need an iptables rule for enabling the IPv4 firewall to accept IPv6 connections (protocol 41) from the PoP tunnel endpoint even if they are not related to existing connections. Good discussion e.g. here: https://www.sixxs.net/forum/?msg=setup-2860037

The following line needs to be added to file '/etc/firewall.user' :

  iptables -I INPUT 1 -s <remote_ipv4_pop_endpoint_addr>  -p 41 -j ACCEPT

In my case:   iptables -I INPUT 1 -s 62.78.96.38 -p 41 -j ACCEPT

Alternatively, you can add an accept rule through Luci (Network/Firewall/Traffic Control): add there a new advanced rule (you need to add the additional field for the source IPv4 address and set custom protocol as 41).


3) Configuring IPv6 address autoconfiguration inside local LAN by using RADVD

As explained in http://wiki.openwrt.org/doc/howto/ipv6#radvd , the file ' /etc/config/radvd' is edited to contain the prefix for the local IPv6 subnet and to make sure that the ignore options are 0. Key fields there:

  config interface
    option interface 'lan'
    option ignore 0

  config prefix
    option interface    'lan'
    option prefix    '2001:14b8:YYYY:YYYY::/64'
    option AdvOnLink    1
    option AdvAutonomous    1
    option AdvRouterAddr    0
    option ignore    0

See also: https://www.sixxs.net/wiki/Aiccu/Installing_on_OpenWRT#Kamikaze_2

To make sure that RADVD get started after the next reboot of the router, run the command:
  /etc/init.d/radvd enable

You can also check from Luci (Services/Initscripts), that all services like RADVD are enabled so that they are started automatically afetr reboots.


4) Configuring ipv6 firewall - ip6tables

Good overview in: https://www.sixxs.net/wiki/IPv6_Firewalling#Example_IPv6_firewall_script_.28with_state.29

Regarding ip6tables rules in the router, the key is to understand that the main configuration is related to the FORWARD chain that handles connectivity to clients in LAN, while INPUT and OUTPUT concern direct traffic to the router itself and remain mostly unused. INPUT and OUTPUT practically handle only the ICMPv6 traffic (at least the SixXS pings).

Note: although you named the tunnel interface as just 'sixxs', it got automatically prefixed with '6in4-', so the name to be used in ip6tables rules is '6in4-sixxs'.

Note: OpenWrt's firewall v2, in Backfire since February 2011 and in Kamikaze/trunk already earlier, does not need the following rules, except for the part where you want to open a certain port (e.g. 49001) for forwarding.

The possible additional rules get set in file '/etc/firewall.user' that is edited manually.

The FORWARD rules should allow all traffic with existing connections, new connections from inside and then selected connections from outside.
I simplified the FORWARD rule regarding new connections from the version presented in Wiki (see below). Additionally my rules allow incoming packets to port 49001 to get accepted for forwarding to clients in local LAN.
Key part:

# Allow forwarding
ip6tables -A FORWARD -i br-lan -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#allow MLDHT packects
ip6tables -A FORWARD -p tcp --dport 49001:49001 -j ACCEPT
ip6tables -A FORWARD -p udp --dport 49001:49001 -j ACCEPT

(See the full '/etc/firewall.user' below.)

That is practically all the necessary steps to get a static 6in4 IPv6 tunnel from SixXS configured in OpenWrt Backfire 10.03.1-rc4.

Finally you need to reboot the router to get it to read the configuration in and to start the tunnel. You might first test connectivity from router's command prompt, e.g. just ping ipv6.google.com from there.


-------------------------

The full contents of '/etc/firewall.user' file. (The rules are meant for OpenWrt's firewall v1, which was used in older releases and also in Backfire until February 2011):

# This file is interpreted as shell script.
# Put your custom iptables rules here, they will
# be executed with each firewall (re-)start.

#allow incoming SixXS IPv6 traffic
iptables -A input_wan -s 62.78.96.38 -p 41 -j ACCEPT

# First, delete all:
ip6tables -F

# Allow ICMPv6 everywhere
ip6tables -A INPUT  -p icmpv6 -j ACCEPT
ip6tables -I OUTPUT -p icmpv6 -j ACCEPT
ip6tables -I FORWARD -p icmpv6 -j ACCEPT

# Allow anything on the local loopback link
ip6tables -A INPUT  -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT

# Allow anything out on the internet
ip6tables -A OUTPUT -o sixxs -j ACCEPT

# Allow the localnet access us:
ip6tables -A INPUT  -i br-lan -j ACCEPT
ip6tables -A OUTPUT -o br-lan -j ACCEPT

# Filter all packets that have RH0 headers:
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

# Allow Link-Local addresses
ip6tables -A INPUT -s fe80::/10 -j ACCEPT
ip6tables -A OUTPUT -s fe80::/10 -j ACCEPT

# Allow multicast
ip6tables -A INPUT -s ff00::/8 -j ACCEPT
ip6tables -A OUTPUT -s ff00::/8 -j ACCEPT

# Allow forwarding
#ip6tables -A FORWARD -m state --state NEW -i br-lan -o 6in4-sixxs -s 2001:14b8:119:ABAD::/64 -j ACCEPT
ip6tables -A FORWARD -i br-lan -j ACCEPT
ip6tables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#allow packets to port X to get forwarded
ip6tables -A FORWARD -p tcp --dport 49001:49001 -j ACCEPT
ip6tables -A FORWARD -p udp --dport 49001:49001 -j ACCEPT

#log the activity that will get dropped (optional)
#ip6tables -A INPUT -j LOG
#ip6tables -A FORWARD -j LOG
#ip6tables -A OUTPUT -j LOG

# Set the default policy
ip6tables -P INPUT   DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT  DROP

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

After Backfire branch was recently upgraded to use the Luci 0.10 branch for the user interface, more IPv6 related options can now be edited through the Luci user interface:

- 6in4 tunnel: Luci / Network / Interfaces  (except the local IPv4 address for the tunnel, which can't be entered through Luci. I have entered it manually to /etc/config/network . I am not 100% sure that it is needed, but having it there has not hurt me...)
- radvd: Luci / Network / Radvd
- custom iptables & ip6tables rules: Luci / Network / Firewall / Custom rules

My current Backfire build for WNDR3700 (with IPv6 6in4 tunnel, radvd and USB storage device hotplug enabled) can be found here: http://koti.welho.com/hnyman1/Openwrt/

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

I have noticed a probem in creating/editing the 6in4 tunnel interface through Luci 0.10 interface:
after the tunnel is created in Luci and you go to its options page in Luci, it automatically creates a config value "defaultroute=0" for the tunnel interface. That is unnecessary and will actually prevent the tunnel from announcing itself as the default route to the outer IPv6 internet.

(6in4 package has = '1' as the default, so Luci behaviour is clearly wrong: https://dev.openwrt.org/browser/trunk/package/6in4/files/6in4.sh#L47 )

I have filed a ticket about that in Luci bug tracker, so hopefully this annoying behaviour gets corrected.
http://luci.subsignal.org/trac/ticket/192

Until that is done, you may have to edit the /etc/config/network manually to delete that  "defaultroute=0" config line from the tunnel's config block. Another option might be to explicitly add a route through the tunnel to internet, but that should be unnecessary as the tunnel tries to do that automatically (unless you have blocked it by that explicit defaultroute=0 statement).

Finding that problem can be pretty difficult, so hopefully devs fix the Luci behaviour soon.

4 (edited by zoo 2011-02-07 07:14:58)

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

I am using PPPoE and NAT on my IPv4 WAN link. My problem is that I am loosing my ipv6 tunnel regularly. According to
http://wiki.openwrt.org/oldwiki/ipv6_howto#iptables and http://wiki.openwrt.org/doc/uci/firewall#note.on.connection.tracking.notrack I need to disable connection tracking. But I am not sure, how I should disable connection tracking the best way with 10.03.1-rc4.

Please give some advises

and please update http://wiki.openwrt.org/doc/howto/ipv6 accordingly.

5 (edited by hnyman 2011-02-07 08:10:43)

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

I have not disabled conntracking. I got the same result by allowing in iptables (IPv4 firewall) rules all incoming proto41 traffic from the tunnel provider, step 2 in the previous mail. I didn't get the good resuls with the Wiki's suggested rules, so after some searching, I followed the advice here https://www.sixxs.net/forum/?msg=setup-2860037 , and just put the accept rule there, without needing any other related rules.


EDIT:
Unrelated note, but I will use this message anyway to note that based on recent SVN logs, the firewall in Backfire was changed last week (with r25353) from firewall1 to firewall2. At least on trunk the new/current firewall has decent IPv6 rules built-in. So, the need for tinker with basic firewall rules will probably decrease, although the need to make sure that tunnel stays up, will remain.

6 (edited by hnyman 2011-02-20 21:21:37)

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

I am currently running trunk r25595, but this applies also to Backfire. I investigated why my 6in4 tunnel dies, when I touch some network settings. And after some research, I found the reason and patched the 6in4.hotplug. Explanation and patch below.

A static 6in4 tunnel from SixXS dies if network settings are touched even lightly. For example, just going into Wifi settings and not changing anything, but selecting Save&Apply, makes the network interfaces to boot again, but sadly the 6in4 tunnel stays dead. In Luci's Network/Interfaces screen, the tunnel stays with the status as "Interface not present or not connected yet". Manually restarting the tunnel from that screen brings it nicely back to life.

The reason seems to be that the whole 6in4 package has probably been originally designed for Hurricane Electric (tunnelbroker.net) tunnels. Those tunnels have a tunnel name, username and password. The current hotplug script only restarts the tunnel interface if there is username & password, and it even first HTTP-connects to HE in the hotplug script. The "ifup" command is hidden so deep into the conditions, that it does not get launched for other service providers. It only gets run, if the tunnel update with HE succeeded.

Logic in 6in4.hotplug  (/etc/hotplug.d/iface/90-6in4 in a live Openwrt system):

...
                        [ -n "$tunnelid" ] && [ -n "$username" ] && [ -n "$password" ] && {
                                [ "${#password}" == 32 -a -z "${password//[a-f0-9]/}" ] || {
                                        password="$(echo -n "$password" | md5sum)"; password="${password%% *}"
                                }
                                uci_set_state network "$cfg" ipaddr "$wanip"

                                (
                                        local url="http://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=AUTO&user_id=$username&pass=$password&tunnel_id=$tunnelid"
                                        local try=0
                                        local max=3

                                        while [ $((++try)) -le $max ]; do
                                                wget -qO/dev/null "$url" 2>/dev/null && {
                                                        logger -t 6in4-update "Updated tunnel #$tunnelid endpoint to $wanip"
                                                        ifup "$cfg"
...

The static tunnels from SixXs do not use username/password, so I have never entered that kind of information to the tunnel's config. And thus the tunnel interface never got the ifup command again from the hotplug script.

I patched the 6in4.hotplug script so that in case some information required for HE is missing, it still tries to set the tunnel working again (setting wan ip and ifup'ing the interface). I also added some logging for understanding the process better.

Patch is included in my 25595 builds. 
http://koti.welho.com/hnyman1/Openwrt/

The patch below applies both to Backfire and Trunk, and will help all those using OpenWrt with SixXS static tunnels.

There is still one piece of the full solution missing, and I think that this applies both for HE and SixXS users:
If the 6in4 interface is restarted and radvd is not, then there will be errors in syslog every 5 minutes about "resetting ipv6-allrouters membership" etc. That is due to the known "feature" in radvd, that if interfaces get updated IDs (interface indexes) when restarting, then radvd gets confused and needs to be restarted.


6in4.hotplug patch:

Relevant files in source code, r25595 as the current version:
https://dev.openwrt.org/browser/trunk/package/6in4/files/6in4.hotplug
https://dev.openwrt.org/browser/branches/backfire/package/6in4/files/6in4.hotplug

Those files get copied into /etc/hotplug.d/iface/90-6in4 in a live Openwrt system.

Index: /Openwrt/backfire/package/6in4/files/6in4.hotplug
===================================================================
--- /Openwrt/backfire/package/6in4/files/6in4.hotplug    (revision 25595)
+++ /Openwrt/backfire/package/6in4/files/6in4.hotplug    (working copy)
@@ -13,11 +13,13 @@
         config_get proto "$cfg" proto
         [ "$proto" = 6in4 ] || return 0
 
+                logger -t 6in4-update "$ACTION for tunnel '$cfg'"
         local wandev
         config_get wandev "$cfg" wan_device "$(find_6in4_wanif)"
         [ "$wandev" = "$DEVICE" ] || return 0
 
         local wanip=$(find_6in4_wanip "$wandev")
+                logger -t 6in4-update "Tunnel '$cfg' Wan IP: $wanip"
 
         [ -n "$wanip" ] && {
             local tunnelid
@@ -51,7 +53,11 @@
                         }
                     done
                 )&
-            }
+            } || {
+                                logger -t 6in4-update "Tunnel '$cfg': No HE-related info, just try to bring tunnel up."
+                                uci_set_state network "$cfg" ipaddr "$wanip"
+                                ifup "$cfg"
+                        }
         }
     }

EDIT:
I also created a crude hotplug that only monitors the first interface listed in radvd config and restarts radvd, if the interface gets 'ifup'. (I used the miniupnpd hotplug as a model.)

It seems to work for me and in now included in my r25626 builds.

/etc/hotplug.d/iface/92-radvd

#!/bin/sh

/etc/init.d/radvd enabled && [ -n "`pidof radvd`" ] && {
        local intif="$(uci_get radvd @interface[0] interface)"
        [ "$ACTION" = "ifup" ] && [ "$INTERFACE" = "$intif" ] && {
                logger -t radvd-hotplug "Ifup for interface '$intif', restart radvd"
                /etc/init.d/radvd restart
        }
}

EDIT 2:
As Jow has patched both Trunk and Backfire 6in4 source at r25628 (and also Luci trunk), it looks like the patches here are unnecessary in any later builds. ;-)

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

Thanks for your thorough explenation, it really helped me a lot. I noticed one thing however, regarding your method of adding the sixxs interface to the wan zone of the firewall. You add it to the file /etc/config/network (and create a new zone entry) which is not the preferred way to do it, because there already exists a special file which handles zones: /etc/config/firewall. So the only thing you need to do is adding the "sixxs" interface to the 'network' option in this file.

config 'zone'
        option 'name' 'wan'
        option 'output' 'ACCEPT'
        option 'masq' '1'
        option 'mtu_fix' '1'
        option 'input' 'DROP'
        option 'forward' 'DROP'
        option 'network' 'wan sixxs'

Adding the tunnel interface to the WAN zone is also kind of a hack because masqurading ("NAT") is active for forwarded packets (this is needed for IPv4) and does not exist for IPv6. It works but causes a warning by the iptables module.

8 (edited by hnyman 2011-02-24 20:19:22)

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

Superwayne wrote:

... I noticed one thing however, regarding your method of adding the sixxs interface to the wan zone of the firewall. You add it to the file /etc/config/network (and create a new zone entry) which is not the preferred way to do it, because there already exists a special file which handles zones: /etc/config/firewall...

Thanks for spotting the typo there. I corrected my original message.

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

To hnyman, you said:
"The reason seems to be that the whole 6in4 package has probably been originally designed for Hurricane Electric (tunnelbroker.net) tunnels. Those tunnels have a tunnel name, username and password. The current hotplug script only restarts the tunnel interface if there is username & password, and it even first HTTP-connects to HE in the hotplug script. The "ifup" command is hidden so deep into the conditions, that it does not get launched for other service providers. It only gets run, if the tunnel update with HE succeeded."
I am coming from a quite different world, I am using an HE tunnel from a CentOS-5 system, but opening the tunnel
is very similar to what you are doing, and my HE tunnel
doesn't need username and password. Might it be that the
code with the login information has become obsolete and
should be change? In any case, it isn't needed for a current HE tunnel.

I am currently considering moving my tunnel to a router +
basestation, and your reporting is most helpful!

Thanks, AG

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

Alfred Ganz wrote:

To hnyman, you said:
"The reason seems to be that the whole 6in4 package has probably been originally designed for Hurricane Electric (tunnelbroker.net) tunnels. Those tunnels have a tunnel name, username and password. The current hotplug script only restarts the tunnel interface if there is username & password, and it even first HTTP-connects to HE in the hotplug script. The "ifup" command is hidden so deep into the conditions, that it does not get launched for other service providers. It only gets run, if the tunnel update with HE succeeded."
I am coming from a quite different world, I am using an HE tunnel from a CentOS-5 system, but opening the tunnel
is very similar to what you are doing, and my HE tunnel
doesn't need username and password. Might it be that the
code with the login information has become obsolete and
should be change? In any case, it isn't needed for a current HE tunnel.

Jow modified the 6in4 package after my message, along my suggestions. Now there is a second ifup command in 'else' branch of the decision tree for the non-HE tunnels.

If a password and username are defined, the package still "calls home" to HE.net at each startup to make sure that the tunnel endpoint IP address in set correctly at HE to match your current IP. The username and password are used for that purpose (and are not actually used for getting the tunnel up).

If you look into the current source code, you will understand what I mean.
https://dev.openwrt.org/browser/trunk/package/6in4/files/6in4.hotplug

Re: Configure Backfire 10.03.1-rc4 for a static 6in4 IPv6 tunnel (SixXS)

If you look into the current source code, you will understand what I mean.
Got it, thanks for the pointer!