[tahoe-dev] Tahoe-lafs and nodes behind NAT (behind another NAT)

Brian Warner warner at lothar.com
Thu Dec 17 16:24:27 PST 2009


Jody Harris wrote:

> Well, I figured it out.
> 
> If you have a helper configured, you can "defeat" multiple layers (at
> least two) of NAT addressing problems.

There are actually two potential things going on here.

The first is that a helper acts as a sort of proxy. Suppose you have
your CLIENT1 and there's a SERVER2 out there that you want to store
shares on, but both machines are behind NAT boxes and can't accept
inbound connections. If CLIENT1 is configured to use HELPER3, and
HELPER3 is publically-visible, then the CLIENT1->HELPER3 connection
works, and the SERVER2->HELPER3 connection works, and the helper will
encode the client's shares and send them on to the server.

Unfortunately the Helper is not complete: it only helps with immutable
uploads. There's no fundamental reason why it couldn't be enhanced to
help with the other three operations (immutable download, mutable
upload, mutable download), but we didn't write the code to do that,
because the main purpose of the Helper is to improve upload speed by
moving the post-encoding expanded bandwidth requirement off of the
(slow) consumer ADSL line over to the (fast) intra-colo LAN connection.
The other three operations don't benefit very much from this (we assume
that mutable files are usually small), so we didn't bother.

That means that, while the uploads might work, the downloads might not,
and directory operations (which use mutable files) might not. Those
operations may use a smaller set of servers than you'd expect.

The second thing going on is that Tahoe's connection layer makes
bidirectional connections between everything, and a successful A->B
connection can then be used for messages from B to A. In the normal
case, when all nodes are publically visible, this results in
redundant+discarded connections (if the A->B connection is established
first, the subsequent B->A connection is rejected).

Basically, every node that might possibly want to be a client (which is
all of them, until we change the code to create "server-only nodes")
will try to establish connections to every server they hear about. And
every node that runs a storage server (controlled by the tahoe.cfg
[storage]enabled flag) will announce themselves to every client. So if
SERVER2 is behind a NAT box, but CLIENT1 is publically-visible, and
CLIENT1 is also running a storage server (so it's really
CLIENT1+SERVER1), then SERVER2's never-turned-off client code will
establish a connection to SERVER1, which is then available for when
CLIENT1 wants to talk to SERVER2.

So the aggressive bidirectional connection establishment code can save
connectivity when a few "server" nodes are actually behind NAT boxes. I
think the result is that a grid can tolerate a single NATted node
without loss of functionality. Two NATted nodes won't be visible to each
other, but will be visible to everyone else, etc.

This also means that if you have a client with a public IP address, you
might want to leave the storage server enabled (but perhaps mark it
readonly, or set the reserved_space really high, to avoid getting any
shares), since that will cause other nodes to connect to you, which
might get you access to NATted servers that would otherwise be
unreachable.

Of course, if you're running a server, you should really make sure it's
reachable by all of your clients, otherwise it's not providing much
utility to them, and relying upon this trick isn't a big improvement. If
the server is behind a NAT box but it is possible to set up a port
forwarding from a static IP address, then the tub.location configuration
setting can help teach the rest of the grid where to find it.

cheers,
 -Brian


More information about the tahoe-dev mailing list