Note

The Funtoo Linux project has transitioned to "Hobby Mode" and this wiki is now read-only.

Funtoo:User Services/IPv6 Tunnel

From Funtoo
Jump to navigation Jump to search

Some Funtoo Linux datacenters do not have native IPv6 support, so we rely on IPv6 tunnel services provided by he.net.

This page will document how to reliably set up an IPv6 tunnel under Funtoo Linux. This particular configuration is focused on setting up a tunnel router, which means that it's not just about providing IPv6 to a single server. Instead, the server we will configure will provide IPv6 for an entire bridged network.

To follow these exact steps, you will need to visit https://tunnelbroker.net and register for an account. This process is free. You may be required to complete some IPv6 training first. Once you have done this, you should be able to configure a tunnel, which will have settings similar to this one:

tunnelbroker.net example tunnel

To make sense of the critical settings of this tunnel, let's talk a bit about how this IPv6 tunnel works. For those who are impatient, here is the actual file we will use to bring up the tunnel -- but please note that additional configuration is required to get the tunnel working properly. We will cover this in the rest of the document. But for now, create this file:

   /etc/netif.d/ipv6-tunnel-router (bash source code)
#!/bin/sh

netif_pre_up() {
    try ip tunnel add $interface mode sit remote $endpoint_remote local $endpoint_local ttl 255
    try ip link set $interface up
    try ip addr add $tunnel_local_ipv6 dev $interface
}

netif_post_up() {
    # all IPv6 traffic should go out the tunnel:
    try ip route add ::/0 dev $interface
    # ...except traffic to our assigned IPv6 block, which all sits on $route_interface:
    try ip route add $route_assigned_block dev $route_interface
}

netif_pre_down() {
    ip route del $route_assigned_block dev $route_interface
    ip route del ::/0 dev $interface
}

netif_post_down() {
    ip tunnel del $interface
}

Now, let's create /etc/conf.d/netif.6to4:

   /etc/conf.d/netif.6to4 (bash source code)
# If you are not using a bridge, replace this with e.g. netif.eth0:
rc_need=netif.brwan
template=ipv6-tunnel-router
route_interface="brwan"
route_assigned_block="2001:470:1f0f:24b::/64"
endpoint_local=172.97.103.202
endpoint_remote=184.105.250.46
tunnel_local_ipv6=2001:470:1f0e:24b::2/64

Above, set:

  • rc_need to the netif device that will be connecting to your LAN devices
  • template to ipv6-tunnel-router
  • route_interface to what you set for route_interface, minus the netif.
  • route_assigned_block to your "Routed /64" from the tunnelbroker.net details page
  • endpoint_local to "Client IPv4 Address" from the tunnelbroker.net details page (this IPv4 should be active on this system.)
  • endpoint_remote to "Server IPv4 Address" from the tunnelbroker.net details page.
  • tunnel_local_ipv6 to "Client IPv6 Address" from the tunnelbroker.net details page. This will be your side of the tunnel's IPv6 network.

Since we don't have IPv6, and are relying on IPv4 to create our tunnel, we need to link both ends of the tunnel using IPv4 first. The tunnelbroker.net end is the "Server IPv4 Address" ($endpoint_remote, above), and our end is the "Client IPv4 Address" $endpoint_local, above. The tunnel will be used to shuffle IPv6 traffic to and from our IPv6 router system. On our IPv6 router system, we will set up radvd, which is the IPv6 router advertisement daemon, and is a key piece of IPv6 local daemon infrastructure to inform your network of what IPv6 addresses are available. It works similar to DHCP for IPv4 in that it allows all your local network devices to acquire an IPv6 addresses.

Tunnelbroker.net gives us a "slash 64" (/64), which is a block of 2^64 IPv6 addresses. All these addresses are expected to exist on "our side" of the tunnel. These are "our" IPv6 addresses, and radvd advertises them so that they are available to all your network devices.

On our Funtoo IPv6 tunnel router system, we are going to rely on a network interface. In our specific example, it is brwan, which is a network bridge, but it could also be a physical interface like eth0, which is plugged into a physical switch that has all your other LAN devices attached. We are going to configure our system to essentially be a gateway for this IPv6 network. Here is some ASCII art which may help you:

[ tunnelbroker.net ]                                 [ our server ]

<-- remote endpoint ------Tunnel IPv6 Network------ local endpoint -->
                                                    <-- brwan ------------------Our Routed /64 network-----------------> our devices

To make things even more confusing, please note there are two IPv6 networks. The second IPv6 network is used exclusively by the tunnel itself. Then we have our local IPv6 network with "our" addresses (our "slash /64" or "Routed /64") we are setting up, which consists of brwan, radvd, and our connected devices. This is a frequent source of confusion. Often, the IPv6 addresses look very similar, so as we continue, be sure to understand the concepts well so you don't mix them up!

   /etc/radvd.conf
interface brwan {
        AdvSendAdvert on;
        AdvHomeAgentFlag off;
        MinRtrAdvInterval 30;
        MaxRtrAdvInterval 100;
        prefix 2001:470:1f0f:24b::/64 { 
            AdvOnLink on; 
            AdvAutonomous on; 
            AdvRouterAddr on; 
        };
};

Above, we configure /etc/radvd.conf to advertise our routed /64 to our LAN. Note that the address we use is the "Routed /64" from the tunnelbroker.net page.

Next, equally critical, we want to configure netif.brwan to use the first address of the Routed /64 range. Please note that this address does not appear on the tunnelbroker.net page, even though one looks a lot like it. You construct this IPv6 address by taking the "Routed /64" and adding a "::1" so that your local network device has the first address in your Routed /64 range.

   /etc/conf.d/netif.brwan (bash source code)
template=bridge
slaves=netif.eth0
# see https://ipv6.he.net/presentations/ra-radvd.pdf page 5 -- we want the first IP in our
# routed range to be on the LAN interface of the router. Please note that the IPv6 address
# we add here is NOT what you assume -- you take the **Routed /64** and add a <code>::1</code>,
# so this is the FIRST address of your private routed /64. It is NOT the server IPv6 address,
# which is the tunnelbroker.net side of the tunnel. Instead, it is the FIRST address from
# the routed /64 that radvd is advertising for us. This is ESSENTIAL so that responses can
# be received by radvd to router advertisements. Otherwise, your devices will get IPv6 
# addresses but they will lose their address in a few minutes due to inability to communicate
# with radvd.
ipaddr="172.97.103.202/24 2001:470:1f0f:24b::1/64"
gateway=172.97.103.1
nameservers="1.1.1.1 1.0.0.1"
domain=funtoo.org
multicast=no

If you were using eth0 plugged into a shared switch, your configuration would look something like this instead:

   /etc/conf.d/netif.eth0 (bash source code)
template=interface
# see https://ipv6.he.net/presentations/ra-radvd.pdf page 5 -- we want the first IP in our
# routed range to be on the LAN interface of the router. Please note that the IPv6 address
# we add here is NOT what you assume -- you take the **Routed /64** and add a <code>::1</code>,
# so this is the FIRST address of your private routed /64. It is NOT the server IPv6 address,
# which is the tunnelbroker.net side of the tunnel. Instead, it is the FIRST address from
# the routed /64 that radvd is advertising for us. This is ESSENTIAL so that responses can
# be received by radvd to router advertisements. Otherwise, your devices will get IPv6 
# addresses but they will lose their address in a few minutes due to inability to communicate
# with radvd.
ipaddr="172.97.103.202/24 2001:470:1f0f:24b::1/64"
gateway=172.97.103.1
nameservers="1.1.1.1 1.0.0.1"
domain=funtoo.org
multicast=no
   Note

In the examples above, our brwan interface also happens to hold the external IP for IPv4 Internet access, and is the IP for one side of our IPv6 tunnel. It doesn't have to be this way. You could have a dedicated interface for IPv4 Internet which is not this particular interface if you wanted.

Dependencies

For our above network configuration, we will have our LAN bridge device brwan, represented by /etc/init.d/netif.brwan. Then we will have a radvd daemon, represented by /etc/init.d/radvd -- this script is installed by radvd itself. Then we will have our tunnel, which will be represented by /etc/init.d/netif.6to4, which will be a symlink to /etc/init.d/netif.tmpl. Then we have one slave device netif.eth0.

Here's how we set up all of that and their associated dependencies:

root # emerge radvd
root # cd /etc/init.d
root # ln -s netif.tmpl netif.eth0
root # ln -s netif.tmpl netif.brwan
root # ln -s netif.tmpl netif.6to4
root # rc-update add radvd default

Since netif.eth0 is just a slave device for the bridge, we can add the following to /etc/conf.d/netif.eth0:

   /etc/conf.d/netif.eth0 (bash source code)
template=interface-noip

At the top of /etc/conf.d/radvd, place the following:

   /etc/conf.d/radvd (bash source code)
rc_need=netif.6to4

This tells OpenRC that radvd needs the tunnel to be up.

Scroll up and you'll see that the rc_need line in /etc/conf.d/netif.6to4 (created much earlier) says that our tunnel needs netif.brwan to be up for the tunnel to be active. We also explicitly reference brwan via route_interface, and since we are using brwan for our IPv4 Internet access, we also reference its IP in endpoint_local, although this could very well be another interface on your system.

When this is all done, radvd depends on netif.6to4 which in turn depends on netif.brwan. This is what we want.

In addition, netif.brwan is configured with the first IPv6 address of our Routed /64, radvd is advertising this entire range to all devices on the LAN, and radvd can receive responses from these devices because it is using the first address of the Routed /64. So all communication on that network should work. In addition, our Funtoo IPv6 router will have a functioning tunnel with an IPv6 default route, so it will happily shuffle IPv6 traffic and and out of the tunnel. We are ready! Let's restart netif.brwan to ensure it has the IPv6 address assigned to it, and then ensure radvd is running:

root # /etc/init.d/netif.brwan restart
root # rc

You should now be able to ping6 IPv6 addresses, on both your IPv6 tunnel router as well as devices on your network. You should find that devices on your LAN that are IPv6-capable will immediately receive an IPv6 address via radvd and be able to communicate to the IPv6 Internet.