ipv6 - How to set up a 6in4 / 6to4 tunnel server on a Linux gateway?

  • user707854

    I have native IPv6 connection (/64 prefix), and I've been trying to set up IPv6 connection behind a OpenWrt router. But I discovered that I was unable to use ebtables to pass through all IPv6 traffic (firmware limitation) or use ndppd to proxy all ICMPv6 requests (neighbor solicitation / advertisement, upstream router which I have no control is not accepting them with unknown reason).

    It seems that the only option I have now is to tunnel all IPv6 traffic. Below is the network topology:

       Internet  --   Router      --      PC
                wan prefix::/64
                wan 219.242.x.x

    I'm trying to create a tunnel between two 10.224.x.x addresses to tunnel all IPv6 traffic in order to get IPv6 connection.

    I've searched for some tutorials but I can't figure out which address to use as parameters when setting up the tunnel.

    The PC is running Windows. It would be better if a configuration example is provided too.

    (The gateway is running OpenWrt, but I assume it works almost like a Linux gateway?)

  • Answers
    Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

    Related Question

    routing - Forwarding protocol 41 (6to4) to a Linux box?
  • joeforker

    I have a Linux router without an ipv6 stack and a Linux host inside the NAT. How do I use iptables to forward 6to4 traffic back and forth between the NAT router and the host and then configure the 6to4 tunnel on the host using the router's public IPv4 address?

    This recipe (on the router) gets an ipv6 ping to the host's eth0 but they don't make it onto the tun6to4 interface. Wireshark says "ICMP Destination unreachable (Port unreachable)" as an ipv4 response to the 6to4 ping.

    # inbound destination NAT for IPv6 tunnel. ppp0 is router's WAN interface.
    iptables -t nat -A PREROUTING -i ppp0 -p 41 -j DNAT --to
    # inbound forwarding for IPv6 tunnel
    iptables -t filter -A FORWARD -i ppp0 -p 41 -d -j ACCEPT

    I am using this script on the Linux host, passing the router's public ip:

    ### Get the global IPv4 address for your host from the command line:
    ### Compute the 6TO4 tunnel IPv6 address:
    GLOB_IP6TO4=$(printf "2002:%02x%02x:%02x%02x::1" $(echo $GLOB_IP4 | tr . ' '))
    ### Setup the tunnel
    ip tunnel add tun6to4 mode sit remote any local $GLOB_IP4 ttl 64
    ip link set dev tun6to4 up
    ip addr add $GLOB_IP6TO4/16 dev tun6to4
    ip route add 2000::/3 via :: dev tun6to4 metric 1

  • Related Answers
  • womble

    iptables -t nat -A PREROUTING -d -p 41 -j DNAT --to on the router should do the trick, assuming that all flows are initiated from outside to your IP address (given as in this example). If your IPv6-capable box starts things, then regular catch-all SNAT rules should do the trick.

  • joeforker

    The Secret Sauce

    I thought the local tunnel address would affect 6to4 encapsulation and would have to be my global IPv4 address.

    ip tunnel add tun6to4 mode sit remote any local $GLOB_IP4 ttl 64

    It had to be the host's address, in my case Leaving everything else the same, it works!

  • nrc

    Sadly this cannot be done when having a linux router between the internet and your linux box behind the nat.

    As stated by the iptables manual:


    This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It specifies that the destination address of the packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined. It takes one type of option: --to-destination ipaddr[-ipaddr][:port-port] which can specify a single new destination IP address, an inclusive range of IP addresses, and optionally, a port range (which is only valid if the rule also specifies -p tcp or -p udp)

    you can "-j DNAT --to" only if the protocol is TCP or UDP, this will not work with protocol 41 (6to4).