Skip to content

Latest commit

 

History

History
285 lines (226 loc) · 11 KB

USAGE-NATIVE-64.MD

File metadata and controls

285 lines (226 loc) · 11 KB

Using 6bed4router under a Native /64 Prefix

Your ISP gave you a natively routed /64 prefix, and you want to use the 6bed4router as a tunnel. The clients of that tunnel might be a mobile device or a home network.

Following are instructions to setup for this. We use the Linux command line because it is the most general. Your distribution may have clever ways of automating the configuration, perhaps even graphically. If you desire such instructions, please use a forum for your distribution.

Assumptions

We assume that your hosting provider gave you a Linux virtual machine with root privileges. We assume that its primary network interface is named eth0 with MAC address a8:bb:cc:00:11:22. The IPv6 prefix awarded to you will be assumed to be 2001:db8:9:10::/64.

When your eth0 interface goes up, it automatically configures a link-local address, meant for communication on the link (to the router of your hosting provider). It will start fall under fe80::/10 and in this case should be fe80::aabb:ccff:fe00:1122. You can see that it contains a mangled form of the MAC address of the interface.

Without explicitly adding an IPv6 address with a global scope, you already have this link-scoped address configured:

shell# ip -6 addr show dev eth0
0: eth0: <...> ...
    inet6 fe80::aabb:ccff:fe00:1122/64 scope link

The upstream router could use ping6 to reach you at this address, and so could you from this virtual machine. However, this being a link-scoped address, nobody else could reach the IPv6 address.

Example Setup

First, the IPv6 default route is set to the address of the upstream router of the hosting provider, something like

shell$ ip -6 route add default via fe80::aabb:ccff:fedd:eeff dev eth0
shell$ ip -6 route show
default via fe80::aabb:ccff:fedd:eeff dev eth0 metric 1024 mtu 1500 ...

Most people configure their hosted machine like they would do with a machine on their home network. So, we shall add a few IPv6 addresses:

shell# ip -6 addr add 2001:db8:9:10::11/64 dev eth0
shell# ip -6 addr add 2001:db8:9:10::30/64 dev eth0
shell# ip -6 addr show dev eth0
0: eth0: <...> ...
    inet6 2001:db8:9:10::30/64 scope global
    inet6 2001:db8:9:10::11/64 scope global
    inet6 fe80::aabb:ccff:fe00:1122/64 scope link

Note how the new addresses are setup with global scope. Indeed, anyone on the Internet should now be able to ping6 you on that address. You are online!

You can now configure programs like a webserver to listen to one or both of these addresses. Inasfar as they are already listening to all addresses they will immediately pickup on the newly added addresses. This applies to ping6 but also to most installations of sshd:

shell# netstat -ptnl6
9378/sshd   0   0   :::22   ...

It would be confusing to parse due to the colon between the address and port, but :::22 indicates address :: and port 22. In other words, sshd with pid 9378 listens to all addresses and will respond to the newly added IPv6 addresses.

Enter 6bed4router

When you are using 6bed4router, chances are it's the first time you start to think of your virtual host as a router. This is indeed the added value of the vast array of addresses that you get with IPv6.

The example setup sketched before is common, but from a router's viewpoint it is flawed. Just look at this:

shell# ip -6 route show
2001:db8:9:10::/64 dev eth0 ...
fe80::/64 dev eth0 ...
default via fe80::aabb:ccff:fedd:eeff dev eth0 ...

Note how silly this is — you are directing your assigned native /64 prefix back to the router of your hosting provider. This is the result of your use of a /64 prefix when you setup your two addresses on eth0.

When your eth0 is attached to a LAN, this setup makes sense; the LAN has numerous hosts under this /64 prefix, and so your networking stack should consider anything under the prefix local to the eth0 link. The prefix is attached to the LAN by a router that connects the LAN to the rest of the IPv6 internet.

In your hosting setup, this is usually not how things are done. Here, the eth0 interface is a direct link to an upstream router whose sole purpose it is to relay your prefix to your eth0 interface. There are no other hosts residing under the same /64 prefix. Still, as long as you enumerate all actual IPv6 addresses in use on the eth0 interface, this is going to work.

But now you want to add 6bed4router, which means you have entered the realm of routing yourself. Now what do you do? If you let it, the 6bed4router creates a 6bed4 network interface with the same /64 prefix, and your system might get confused.

The solution is simple. You can use eth0 for inbound traffic for your /64 prefix, even when it does not have local addresses assigned. All you need to ensure is that it forwards frames that it cannot handle on the interface itself.

shell# sysctl -w net.ipv6.conf.eth0.ip_forwarding=1
shell# sysctl net.ipv6.conf.eth0.ip_forwarding
net.ipv6.conf.eth0.ip_forwarding = 1

and, if you intend to support multicast as well, perhaps even

shell# sysctl -w net.ipv6.conf.eth0.ip_mc_forwarding=1
shell# sysctl net.ipv6.conf.eth0.ip_mc_forwarding
net.ipv6.conf.eth0.ip_mc_forwarding = 1

You could now remove the IPv6 addresses to pass all the traffic, for insance to the 6bed4 interface, which is not desirable if you intend to run servers under your /64 as well. But this is how it would be done:

shell# ip -6 addr del 2001:db8:9:10::11/64 dev eth0
shell# ip -6 addr del 2001:db8:9:10::30/64 dev eth0
shell# ip -6 addr show dev eth0
0: eth0: <...> ...
    inet6 fe80::aabb:ccff:fe00:1122/64 scope link
shell# ip -6 route show
fe80::/64 dev eth0 ...

The trick is to redefine the addresses with a longer prefix than /64. With the /64 assigned to the 6bed4 interface, the longer prefix is a better match for some packets, which are then not forwarded over 6bed4.

There is explicit support in the 6bed4 design for this approach, and that is by being utterly uninterested in certain addresses. The one-but-last word in the address structure of 6bed4 represents an UDP port, and since port 0 is never permitted, there is a whole range of IPv6 addresses that can be bypassed for other uses — such as running a server locally. There just have to take a format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:0000:xxxx to be clearly distinguishable from 6bed4 addresses. In our case, we can use the addresses ending in ::11 and ::30 without confusing with 6bed4. A decent prefix to use would be either /128 for an exact match with the address or, if we wish to offload the routing tables, a /112 prefix that is certain to hold at least the port number.

The next question is where the addresses should go. For /128 prefixes, the eth0 interface would be quite good, so it can match the addresses locally and refrain from further routing. This is also pleasant if there is a preference to route IPv4 and IPv6 over the same interfaces (though that is a subject desire). Aside from the already-coded removal of the old addresses, the procedure would be:

shell# ip -6 addr add 2001:db8:9:10::11/128 dev eth0
shell# ip -6 addr add 2001:db8:9:10::30/128 dev eth0
shell# ip -6 addr show dev eth0
0: eth0: <...> ...
    inet6 2001:db8:9:10::30/128 scope global
    inet6 2001:db8:9:10::11/128 scope global
    inet6 fe80::aabb:ccff:fe00:1122/128 scope link

Where the option of one or more /112 prefixes is preferred, we might instead do that on eth0, or choose to not send packets for the smaller network ranges back upstream by creating a virtual network interface. It may be helpful to create a "dummy" network interface, which holds your local IPv6 addresses and has them routed through the loopback interface,

shell# ip -6 link add dumbo0 type dummy
shell# ip -6 link set dumbo0 up
shell# ip -6 link show dev dumbo0
1: dumbo0: <...> ...
    link/ether 11:22:33:44:55:66 brd ff:ff:ff:ff:ff:ff

Variations on this are many...

  1. You could create virtuel ethernet devices to link directly to others, possibly in another networking name space or container, and so on.
  2. You could setup a tunnel with a tool like socat to relay traffic to another network, where you unleash the address range via Router Advertisements and DHCPv6.
  3. You could setup a translation to logical addresses using the Host Identity Protocol.
  4. You could export an address range over a DNS tunnel.
  5. You could run L2TP to connect networks based on the /112 IPv6 prefix, possibly as a backend to PPPoE clients. Add IPsec and you have a nice, standards-compliant VPN.

And you could mix in any way you like, by assigning different /112 prefixes to each interface. Given the port-0 assumption, you have 4294967296 of those ranges for a total of 281474976710656 hosts, we hope that you will agree that 6bed4 leaves you some room to play.

Again, we should ensure forwarding:

shell# sysctl -w net.ipv6.conf.eth0.ip_forwarding=1
shell# sysctl net.ipv6.conf.eth0.ip_forwarding
net.ipv6.conf.eth0.ip_forwarding = 1

and possibly

shell# sysctl -w net.ipv6.conf.eth0.ip_mc_forwarding=1
shell# sysctl net.ipv6.conf.eth0.ip_mc_forwarding
net.ipv6.conf.eth0.ip_mc_forwarding = 1

Now we can proceed by adding the IPv6 addresses again, but this time with a /112 prefix and to the dumbo0 device:

shell# ip -6 addr add 2001:db8:9:10::11/112 dev dumbo0
shell# ip -6 addr add 2001:db8:9:10::30/112 dev dumbo0
shell# ip -6 addr show dev dumbo0
0: dumbo0: <...> ...
    inet6 fe80::aabb:ccff:fe00:1122/64 scope link
    inet6 2001:db8:9:10::30/112 scope global
    inet6 2001:db8:9:10::11/112 scope global

Do not forget to remove the /64 prefixes from eth0, as coded above.

You can now run 6bed4router without further problems.

Poorly Configured Upstreams

Now that you are running a router, you may be assuming that your uplink does, too. This may not always be true. For instance:

  • You may be running the 6bed4router on an ethernet LAN
  • Your upstream may not be configured with your link-local address for your IPv6 range

In these cases, you may be subjected to Neighbor Solicitation requests for the various IPv6 addresses that make up 6bed4. This is a pitty, as the variety of addresses may be a bit much for the upstream. So if you can, tell your upstream to do something like

shell$ ip -6 route add 2001:db9:9:10::/64 via fe80::aa:bb:cc:ff:fe::dd:ee:ff/64 dev eth0

If this is not an option, for instance because the router is managed by another party that does not respond to such inquiries, you may have to Proxy Neighbor Discovery instead. Once it runs, your connections should magically come alive.