6bed4: Peer-to-Peer IPv6 on any Internetwork

Contents

Upcoming changes

After rather lively feedback ;-) on the dependency on anycast, specifically for the return route, I have decided that the next iteration should do things differently. It is still necessary to recognise remote peers as 6bed4 peers, so a small prefix is used, followed by an IPv4 address and UDP port of a 6bed4 server. These prefixes can be announced in BGP for their IPv6 side. They will relay traffic to a peer address shown in the bottom half of an address.

See an early preview of what I am writing on now, in text, html or xml.

Introduction

Note: The changes relative to v00 are also documented separately.

The intention of 6bed4 is to support IPv6-only applications, even on IPv4-only networks. A specific area of concern is that of peer-to- peer protocols such as SIP or document exchange during a chat session. Such protocols are designed to run in any environment, which means that they cannot rely on IPv6 for themselves, or their peers. The 6bed4 tunnel mechanism ensures that IPv6 can be assumed on all peers, without a need to configure it explicitly.

We have investigated tunnelling techniques, and found that most are not usable for embedded devices, for a variety of reasons. We propose a very simple alternative, and named it 6bed4.

In short, 6bed4 is a stateless tunnel to an anycast address, from which it obtains an IPv6 address through autoconfiguration. The autoconfigured address has a /64 prefix and the interface identifier that completes it involves the node's external IPv4 address and UDP port:

 0                            63              95     111     127
+-------------------------------+-------+-------+-------+-------+
|      IPv6-side /64 PREFIX     |udp udp|v4 0xff|0xfe v4| v4 v4 |
+-------------------------------+-------+-------+-------+-------+

The v4 parts are bytes of the IPv4 address in network order; the udp bytes however, are in reverse network byte order. Only even UPD ports are permitted. The first udp therefore has its low bit reset. It also has the one-but-lowest bit inverted.

This format is the same as that for Ethernet, and this is not a complete coincidence. The 6 bytes of information describing a remote peer are very useful as a link-layer address instead of a MAC address. The v01 design builds on the Neighbor Cache that holds translations from full IPv6 address to these link-layer addresses. The binary format for a link-layer address is:

 0                                            47
+-------+-------+-------+-------+-------+-------+
| UDP.1 | UDP.0 |IPv4.0 |IPv4.1 |IPv4.2 |IPv4.3 |
+-------+-------+-------+-------+-------+-------+

The value UDP.1 is the lower byte of the two, but it does not have its one-but-lowest bit inverted, like with the interface identifier above. This is not because that is very beautiful, but simply to stay in line with the definitions of Ethernet.

Of course, 6bed4 is only a fallback mechanism, to be used in cases where IPv6 is not available locally, or not working. Still, a server might find it useful to also support 6bed4, so as to connect as directly as possible to remote peers, even if this means that it has to rely on IPv4 for the directness of the connection. In 6bed4 terms, an optimal bypass can be found by connecting to IPv4 addresses instead of going through the 6bed4 Public Service.

Public addresses

The following specifies temporary and experimental address information that may be used until IANA registers the real values:

IPv4 address for the remote tunnel service:  145.136.0.1

IPv6 prefix for the remote tunnel service:   2001:67c:127c::/64

UDP port for the remote tunnel service v01:  25788

Updates to these values may occur as long as 6bed4 is not standardised; a low-traffic mailing list 6bed4-infra was created to keep you informed.

surfnet_logo.gif

This first public node for 6bed4 is sponsored by SURFnet. To them it is everyday business to support network innovation, so they were quite open to my request for a well-connected router machine. Thanks guys!

nlnet_logo.gif

The work to lift the 6bed4 tunnel from v00 to v01 has been supported by NLnet. Specifically, this involves the peer-to-peer facilities. NLnet are often a silent funding participant in forward-thinking open source innovation.

Specification

Released on March 12, 2012, here is the 6bed4 specification as an Internet Draft in version 01. The v00 specification is also still available. Please comment if you have anything to improve, this is the phase where the spec is still open and flexible!

INTERNET-DRAFT                                             Rick van Rein
Intended Status: Proposed Standard                          OpenFortress
Expires: September 12, 2012                               March 11, 2012

              6bed4: Peer-to-Peer IPv6 on Any Internetwork
                      draft-vanrein-v6ops-6bed4-01

Abstract

   The intention of 6bed4 is to support IPv6-only applications, even on
   IPv4-only networks.  A specific area of concern is that of peer-to-
   peer protocols such as SIP or document exchange during a chat
   session.  Such protocols are designed to run in any environment,
   which means that they cannot rely on IPv6 for themselves, or their
   peers.  The 6bed4 tunnel mechanism ensures that IPv6 can be assumed
   on all peers, without a need to configure it explicitly.

   The 6bed4 mechanism is meant as a fallback mechanism for IPv6
   connectivity on networks that do not support it natively, by running
   a tunnel over UDP and IPv4.  The IPv4 address is used to support
   traceability of the traffic originator, which means that no user
   account or other configuration is needed.

   The tunnel mechanism builds on existing IPv6 mechanisms; it employs
   Stateless Address Autoconfiguration [RFC4862] to setup an IPv6
   address on a 6bed4 Peer, and Neighbor Discovery [RFC4861] to find the
   most direct route to a remote 6bed4 Peer.

Read the full 6bed4 specification or track it online. Note that the spec is expired a week prior to RIPE65 -- it did not seem to make much sense to renew it with the probability of good feedback that I could incorporate in a newer version.

Intermediate versions of this spec may be posted on the 6bed4-devel mailing list. This is also the proper place for collective discussion and inquiries.

But Teredo...

Oh c'mon!

Nobody really wants Teredo. It is generally advised when you ask for a tunnel, but it hardly works and is most certainly not a turn-key solution for IPv6 acccess by IPv4-only nodes. The fact that it is installed on many machines does not even mean a thing, because it is impaired by those same machines as a result of a DNS hack.

In addition, you should note that hardly anyone has Teredo. It may be part of Windows, but it is usually disabled or crippled to avoid that it is actually used.

In comparison, 6bed4 is more elegant, it is simpler and it is fast. The only thing that could be said in favour of Teredo is that a number of service providers have already committed bandwidth to it, compared with "just" one for 6bed4.

Downloads

Slides, code, background info.

Slides

I presented 6bed4 under the cheeky title IPv6 for the Masses -- with 6bed4 at RIPE65.

Here are some slides of talks held before and after posting v00. Spot the differences ;-)

Code

There also is a reference implementation which builds on Linux, and should cause no difficulties if you have no other form of IPv6 access. You can also browse the source if you like.

Note however, this is alpha software at present. For the time being, you may prefer to skip peer-to-peer optimisation, and instead use the older democode for version 00 of the draft.

Whichever you use, if your setup does not work, please let me know what goes wrong... 6bed4 should work in any sane environment. You will greatly help me with tcpdumps of the UDP traffic over IPv4, and/or the IPv6 traffic on the 6bed4 interface.

Background information

Finally, the document v6embedded is what I generally send to parties interested in supporting IPv6 through hosting tunnels near the backbone of the Internet.

Trying it

Trying it on Linux

These instructions are for the reference implementation of version 01 of the Internet Draft.

If you care to try 6bed4, you are probably looking for the demonstration peer code to give you an idea. You are going to try it in a horrible location, of course, just to see if my claim that it works on any network is really true. I dare you :) but please, keep me posted on your results.

After downloading and unpacking the tarball with the reference implementation code, you would do the following:

./configure
make
./6bed4peer -def

Notes from prior testers of this early test version:

  • The include files /usr/include/linux/if_ether.h and a few more are needed; on Debian, you will find them in the package linux-libc-dev, which may not yet be present on your build system.

The above command runs in the foreground, and provides a lot of (interesting?) feedback. It is really helpful in seeing what the tunnel is doing it. When you trust it, you can resort to simply saying

./6bed4peer -d

The remaining -d option is to setup a default route over 6bed4. You could drop that too, if course.

Go ahead, and see if http://www.sixxs.net/ shows an IPv6 address at the top or bottom of its pages. Or see if http://www.kame.net/ shows a dancing turtle. When done testing, you can simply kill the client process. And by all means, try this anywhere you are -- on trains and busses providing IPv4, or use playing with the tunnel as an excuse to make an overall test of a cafe -- it should all work.

Meanwhile, if you care to see the traffic that this generates, you can make a dump of traffic on your usual IPv4 interface, and specifically on the UDP port to which the daemon has attached. It will log a message with that port, but you may also find it as root, by using:

netstat -puntl | grep 6bed4

If you found port number 44444 and your public interface is eth0, then you could log the traffic with:

tshark -s0 -w /tmp/traffic.tcpdump -ni eth0 udp port 44444

If you are like me, you will use !tshark to repeat the statement later on, and forget to change the port. A way out of this could be to combine the former statements, and hope there is no other application with a similar name running on your machine:

tshark -ni eth0 udp port `netstat -puntl | grep 6bed4 | sed -e 's/^[^:]*://' -e 's/ .*//'`

You could then load the traffic dump into WireShark and use Analyze->DecodeAs to decode traffic from/to [1] UDP port 44444 as IP. After this setting, WireShark lets you inspect 6bed4 in detail.

Alternatively, you could watch it interactively:

tshark -s0 -w /tmp/traffic.tcpdump -ni eth0 udp port 44444 -d udp.port==44444,ip

or even with interpretation of the wrapped IPv6 content:

tshark -ni eth0 udp port `netstat -puntl | grep 6bed4 | sed -e 's/^[^:]*://' -e 's/ .*//'` -d udp.port==`netstat -puntl | grep 6bed4 | sed -e 's/^[^:]*://' -e 's/ .*//'`,ip

Note that the UDP port of the 6bed4peer will change on every run, unless you fixate a port using -p. If you are experimenting with NAT traversal, and certainly if you are generating test results for me, you really should not use this option.

You may prefer to watch the traffic with WireShark; in that case, I can recommend using Ctrl+1 and Ctrl+2 and so on to mark the traffic before you setup Analyze -> DecodeAs. Just assign a new colour to each line that has the lightblue shade of UDP. The colouration will then show the various paths that your traffic follows, unlike when you colourise the traffic after setting up the decoding of the tunnel traffic.

If you review the traffic before the democlient (by fixating the peer's UDP port, or by observing the server's fixed UDP port 25788), you will see the work of the peer as follows:

0.000000      fe80::1 -> ff02::2      ICMPv6 Router solicitation
0.030651       fe80:: -> fe80::1      ICMPv6 Router advertisement

After that, you will see dumps of any traffic that passes through the tunnel in the same dump. Most people continue so predictably that I'd almost build it into the tunnel to save traffic ;-) by ping6'ing to ipv6.google.com which would show the following dumps:

143.311761 2001:610:188:2002:c000:020d:ed8f:1 -> 2a00:1450:8005::63 ICMPv6 Echo request
143.344397 2a00:1450:8005::63 -> 2001:610:188:2002:c000:020d:ed8f:1 ICMPv6 Echo reply

Your addresses will differ a bit, no doubt, as a result of your IPv4 address and UDP port being built in. If you already have IPv6 on another interface, add -I 6bed4 to the command line to ensure ping6'ing over the new interface.

There is a keepalive mechanism, by default occurring once per 30 seconds, to keep NAT routers and firewalls open on the same UDP port. This means that your 6bed4 address should stay the same throughout the time that the peer is active. You might be a bit surprised if you inspect the keepalives -- they are empty UDP packets, so if you are having those interpreted as IP then they will report failure. Furthermore, the TTL is set to 3 by default because you will want to keep your local routers and firewalls open, but there is no need to bother the 6bed4 router or any other router in between. If these settings do not work for you, please supply a -k parameter -- and convince me that the default settings are too tight.

If you think you are missing traffic from your dumps, then chances are that the peer has found a bypass to a remote peer. This can happen at any time, even within what seems like a single session at the IPv6 level. This is why it is advised to monitor the local UDP port instead of the fixed one of the 6bed4 Router.

Trying 6bed4 on Raspberry Pi

Of course your smallest computer should have IPv6. It's the best way to make fun of your friends and family, who still muck around with IPv4 ;-)

The following steps download and build 6bed4 on the Debian Wheezy version of RPi, and construct the 6bed4 interface:

mkdir ~/6bed4
cd ~/6bed4
wget http://devel.0cpm.org/6bed4/download/refimpl-01-alpha2.tgz
tar -xzvf refimpl-01-alpha2.tgz
cd refimpl-01-alpha2
./configure
make
sudo modprobe ipv6
sudo modprobe tun
sudo ./6bed4peer -def &

Trying 6bed4 on Android phones

We have a test version of an Android app for 6bed4. You are welcome to test it. If it fails, we appreciate feedback including tcpdumps, possibly made with the Shark app on a rooted Android device.

Note that this assumes Android >= 4.0 because it is based on the VPN Service that was added with that. This is the Android method of offering a tunnel to applications.

Things that are still missing:

  • some of the security checks on incoming packets
  • possibly some of the peer-to-peer neighboring services
  • glitchy performance of the default route setting; if it fails, please stop it, clear the configuration variables, toggle switches a few times and enable restart after boot, and only then enable the tunnel -- and be aware that we will look into this issue soon
  • without a default route being setup, it should create a /64 for the 6bed4 range
  • ideally, the default route would change when the network configuration changes (even if Android hides routing details and does not permit route preference settings, at least it shows if other IPv6 addresses are available)
  • it would be useful if it displayed the IPv6 address obtained ;-)

Having said that, you are welcome to test it; you can get it in the download directory (for which you could use the QR-code below).

http://chart.apis.google.com/chart?cht=qr&chs=350x350&chld=L&choe=UTF-8&chl=http%3A%2F%2Fdevel.0cpm.org%2F6bed4%2Fdownload%2F

To find your IPv6 address, you can use:

adb shell ip -6 address show

To check your default route, ensure that ::/1 and 8000::/1 are sent through tunX with:

adb shell ip -6 route show

To find your IPv6 address without adb, you could install MyIPv6 or a terminal app, or visit a website that tells on your IPv6 address. As for the Advanced Settings:

  • You should normally Send All IPv6 Traffic Through 6bed4 if you don't have native IPv6
  • The Tunnel Server Address can be overridden if you are running your own server
  • The Local UDP Port is there to make your IPv6 address as static as your IPv4 address; this is useful for running servers

Trying 6bed4 in Java (for developers)

We have a generic package java-socket6bed4 which implements a DatagramSocket subclass with all of 6bed4 behind this general API. So if you want to write software that has all the facilities of 6bed4 without more effort than a proper factory procedure, take a look!

Testing on an IPv6-ready network

If you are on an IPv6-ready network you may have a hard time testing/debugging 6bed4. A good chance of overcoming this is "stealing" the autoconfigured IPv6 address that the node would like to have. For example, you could steal away the IPv6 address that your Android phone would configure on your WLAN if you were to try out Android6bed4. To this end:

  1. Find the node's autoconfigured IPv6 address

  2. On another system, start entering (but do not press Enter yet) this command:

    ip -6 addr add <node_autocfg_addr> dev eth0
    
  3. Switch off networking on the node

  4. Press enter on the other host, verify that it got the address:

    ip -6 addr show dev eth0 | grep <node_autocfg_addr>
    

    The address should not be listed as tentative, which would be the case if you pressed enter while the original node was still defending it.

  5. Switch on networking on the node. It should not succeed in autoconfiguring an address. It depends on the node whether it will try something else, but it probably won't.

  6. Now continue to test 6bed4 as if it were on an IPv4-only network.

  7. When done testing, reverse the address assignment with:

    ip -6 addr del <node_autocfg_addr> dev eth0
    

Might you land in trouble, then you are best off contacting the 6bed4-user mailing list for help.

[1]I still don't understand why our lovely traffic dumping tools lack the ability to filter on remote UDP port 25788. That is more to the point than from/to and save us from false positives.

Running a supportive site

Starting with protocol v01, the clients are supposed to try if direct routes to remote peers are possible. This is done by Neighbor Discovery sent over the paths under test; if it works both ways, then plain IPv6 can also travel that path.

A supportive site, for example a server, could welcome 6bed4 traffic by making sure that 6bed4 traffic can detect the direct route to its IPv4/UDP interface. Behind NAT, this would require an open port to an internal 6bed4 service that responds to Neighbor Discovery; on a public IPv4 address it is simply enough to have a 6bed4 service listening to a IPv4/UDP combo that is encapsulated in a widely known IPv6 address.

So, if you run a server on a public IPv4 address and (aside from native IPv6) it can be reached from 6bed4 peers, you may want to setup a 6bed4 instance on the server's IPv4 address.

And, if you run a server behind NAT, your best bet is to setup port forwarding for a UDP port that occurs in a publicly announced 6bed4 IPv6 address. Behind the forwarded port should, again, be a listening 6bed4 service.

Discussion

A concrete specification is light to cause discussion...