Wrote USAGE-NATIVE-64 for deploying 6bed4router under a single /64 prefix
authorRick van Rein <rick@openfortress.nl>
Thu, 28 Sep 2017 05:30:11 +0000 (07:30 +0200)
committerRick van Rein <rick@openfortress.nl>
Thu, 28 Sep 2017 05:35:42 +0000 (07:35 +0200)
USAGE-NATIVE-64.MD [new file with mode: 0644]

diff --git a/USAGE-NATIVE-64.MD b/USAGE-NATIVE-64.MD
new file mode 100644 (file)
index 0000000..5f0f7e9
--- /dev/null
@@ -0,0 +1,242 @@
+# 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 &mdash; 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 &mdash; 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 possible.  You could create virtuel ethernet devices
+to link directly to others, possibly in another networking name space, and so
+on.  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.
+