mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-13 13:53:07 +00:00
tahoe.cfg: add tub.location, to override the location hints we include in our FURL. This replaces advertised_ip_addresses, which doesn't remain useful enough to retain it. Helps with #517 (Tor).
This commit is contained in:
parent
74ce1cdc00
commit
9976bd439a
7
NEWS
7
NEWS
@ -53,9 +53,10 @@ connection. docs/frontends/webapi.txt has details.
|
||||
The Tahoe node is now configured with a single INI-format file, named
|
||||
"tahoe.cfg", in the node's base directory. Most of the previous
|
||||
multiple-separate-files are still read for backwards compatibility (the
|
||||
embedded SSH debug server is the exception), but new directives will only be
|
||||
added to tahoe.cfg . The "tahoe create-client" command will create a
|
||||
tahoe.cfg for you, with sample values commented out. (ticket #518)
|
||||
embedded SSH debug server and the advertised_ip_addresses files are the
|
||||
exceptions), but new directives will only be added to tahoe.cfg . The "tahoe
|
||||
create-client" command will create a tahoe.cfg for you, with sample values
|
||||
commented out. (ticket #518)
|
||||
|
||||
tahoe.cfg now has controls for the foolscap "keepalive" and "disconnect"
|
||||
timeouts (#521).
|
||||
|
@ -77,22 +77,83 @@ tub.port = (integer, optional)
|
||||
port. The port will be written to a separate file (named client.port or
|
||||
introducer.port), so that subsequent runs will re-use the same port.
|
||||
|
||||
advertised_ip_addresses = (comma-separated host[:port] string, optional)
|
||||
tub.location = (string, optional)
|
||||
|
||||
The node normally uses tools like 'ifconfig' to determine the set of IP
|
||||
addresses on which it can be reached from nodes both near and far. The node
|
||||
introduces itself to the rest of the grid with a FURL that contains a series
|
||||
of (ipaddr, port) pairs which other nodes will use to contact this one. By
|
||||
providing this file, you can add to this list. This can be useful if your
|
||||
node is running behind a firewall, but you have created a port-forwarding to
|
||||
allow the outside world to access it. Each line must have a dotted-quad IP
|
||||
address and an optional :portnum specification, like:
|
||||
In addition to running as a client, each Tahoe node also runs as a server,
|
||||
listening for connections from other Tahoe clients. The node announces its
|
||||
location by publishing a "FURL" (a string with some connection hints) to the
|
||||
Introducer. The string it publishes can be found in
|
||||
$BASEDIR/private/storage.furl . The "tub.location" configuration controls
|
||||
what location is published in this announcement.
|
||||
|
||||
123.45.67.89
|
||||
44.55.66.77:8098
|
||||
If you don't provide tub.location, the node will try to figure out a useful
|
||||
one by itself, by using tools like 'ifconfig' to determine the set of IP
|
||||
addresses on which it can be reached from nodes both near and far. It will
|
||||
also include the TCP port number on which it is listening (either the one
|
||||
specified by tub.port, or whichever port was assigned by the kernel when
|
||||
tub.port is left unspecified).
|
||||
|
||||
Lines that do not provide a port number will use the same client.port as the
|
||||
automatically-discovered addresses.
|
||||
You might want to override this value if your node lives behind a firewall
|
||||
that is doing inbound port forwarding, or if you are using other proxies
|
||||
such that the local IP address or port number is not the same one that
|
||||
remote clients should use to connect. You might also want to control this
|
||||
when using a Tor proxy to avoid revealing your actual IP address through the
|
||||
Introducer announcement.
|
||||
|
||||
The value is a comma-separated string of host:port location hints, like
|
||||
this:
|
||||
|
||||
123.45.67.89:8098,tahoe.example.com:8098,127.0.0.1:8098
|
||||
|
||||
A few examples:
|
||||
|
||||
Emulate default behavior, assuming your host has IP address 123.45.67.89
|
||||
and the kernel-allocated port number was 8098:
|
||||
|
||||
tub.port = 8098
|
||||
tub.location = 123.45.67.89:8098,127.0.0.1:8098
|
||||
|
||||
Use a DNS name so you can change the IP address more easily:
|
||||
|
||||
tub.port = 8098
|
||||
tub.location = tahoe.example.com:8098
|
||||
|
||||
Run a node behind a firewall (which has an external IP address) that has
|
||||
been configured to forward port 7912 to our internal node's port 8098:
|
||||
|
||||
tub.port = 8098
|
||||
tub.location = external-firewall.example.com:7912
|
||||
|
||||
Run a node behind a Tor proxy (perhaps via tsocks), in client-only mode
|
||||
(i.e. we can make outbound connections, but other nodes will not be able to
|
||||
connect to us). The literal 'unreachable.example.org' will not resolve, but
|
||||
will serve as a reminder to human observers that this node cannot be
|
||||
reached. "Don't call us.. we'll call you":
|
||||
|
||||
tub.port = 8098
|
||||
tub.location = unreachable.example.org:0
|
||||
|
||||
Run a node behind a Tor proxy, and make the server available as a Tor
|
||||
"hidden service". (this assumes that other clients are running their node
|
||||
with tsocks, such that they are prepared to connect to a .onion address).
|
||||
The hidden service must first be configured in Tor, by giving it a local
|
||||
port number and then obtaining a .onion name, using something in the torrc
|
||||
file like:
|
||||
|
||||
HiddenServiceDir /var/lib/tor/hidden_services/tahoe
|
||||
HiddenServicePort 29212 127.0.0.1:8098
|
||||
|
||||
once Tor is restarted, the .onion hostname will be in
|
||||
/var/lib/tor/hidden_services/tahoe/hostname . Then set up your tahoe.cfg
|
||||
like:
|
||||
|
||||
tub.port = 8098
|
||||
tub.location = ualhejtq2p7ohfbb.onion:29212
|
||||
|
||||
Most users will not need to set tub.location .
|
||||
|
||||
Note that the old 'advertised_ip_addresses' file from earlier releases is no
|
||||
longer supported. Tahoe 1.3.0 and later will ignore this file.
|
||||
|
||||
log_gatherer.furl = (FURL, optional)
|
||||
|
||||
@ -345,7 +406,7 @@ exists, it will take precedence over the corresponding item in tahoe.cfg .
|
||||
[node]tub.port : BASEDIR/client.port (for Clients, not Introducers)
|
||||
[node]tub.port : BASEDIR/introducer.port (for Introducers, not Clients)
|
||||
(note that, unlike other keys, tahoe.cfg overrides the *.port file)
|
||||
[node]advertised_ip_addresses : BASEDIR/advertised_ip_addresses (one per line)
|
||||
[node]tub.location : replaces BASEDIR/advertised_ip_addresses
|
||||
[node]log_gatherer.furl : BASEDIR/log_gatherer.furl (one per line)
|
||||
[node]timeout.keepalive : BASEDIR/keepalive_timeout
|
||||
[node]timeout.disconnect : BASEDIR/disconnect_timeout
|
||||
@ -367,6 +428,13 @@ file provided the ssh public keys to accept. Support for these files has been
|
||||
removed completely. To ssh into your Tahoe node, add [node]ssh.port and
|
||||
[node].ssh_authorized_keys_file statements to your tahoe.cfg .
|
||||
|
||||
Likewise, the functionality of [node]tub.location is a variant of the
|
||||
now-unsupported BASEDIR/advertised_ip_addresses . The old file was additive
|
||||
(the addresses specified in advertised_ip_addresses were used in addition to
|
||||
any that were automatically discovered), whereas the new tahoe.cfg directive
|
||||
is not (tub.location is used verbatim).
|
||||
|
||||
|
||||
== Example ==
|
||||
|
||||
The following is a sample tahoe.cfg file, containing values for all keys
|
||||
@ -374,8 +442,10 @@ described above. Note that this is not a recommended configuration (most of
|
||||
these are not the default values), merely a legal one.
|
||||
|
||||
[node]
|
||||
port = 34912
|
||||
advertised_ip_addresses = 123.45.67.89,44.55.66.77:8098
|
||||
nickname = Bob's Tahoe Node
|
||||
tub.port = 34912
|
||||
tub.location = 123.45.67.89:8098,44.55.66.77:8098
|
||||
web.port = 8123
|
||||
log_gatherer.furl = pb://soklj4y7eok5c3xkmjeqpw@192.168.69.247:44801/eqpwqtzm
|
||||
timeout.keepalive = 240
|
||||
timeout.disconnect = 1800
|
||||
@ -384,8 +454,6 @@ ssh.authorized_keys_file = ~/.ssh/authorized_keys
|
||||
|
||||
[client]
|
||||
introducer.furl = pb://ok45ssoklj4y7eok5c3xkmj@tahoe.example:44801/ii3uumo
|
||||
nickname = Bob's Tahoe Node
|
||||
web.port = 8123
|
||||
helper.furl = pb://ggti5ssoklj4y7eok5c3xkmj@helper.tahoe.example:7054/kk8lhr
|
||||
|
||||
[storage]
|
||||
|
@ -50,7 +50,6 @@ class Node(service.MultiService):
|
||||
NODETYPE = "unknown NODETYPE"
|
||||
PORTNUMFILE = None
|
||||
CERTFILE = "node.pem"
|
||||
LOCAL_IP_FILE = "advertised_ip_addresses"
|
||||
|
||||
def __init__(self, basedir="."):
|
||||
service.MultiService.__init__(self)
|
||||
@ -116,21 +115,6 @@ class Node(service.MultiService):
|
||||
except EnvironmentError:
|
||||
pass
|
||||
|
||||
try:
|
||||
addresses = []
|
||||
ipfile = os.path.join(self.basedir, self.LOCAL_IP_FILE)
|
||||
tubport = int(self.get_config("node", "tub.port", "0"))
|
||||
for addrline in open(ipfile, "rU"):
|
||||
mo = ADDR_RE.search(addrline)
|
||||
if mo:
|
||||
(addr, dummy, aportnum,) = mo.groups()
|
||||
if aportnum is None:
|
||||
aportnum = tubport
|
||||
addresses.append("%s:%d" % (addr, int(aportnum),))
|
||||
self.set_config("node", "advertised_ip_addresses",
|
||||
",".join(addresses))
|
||||
except EnvironmentError:
|
||||
pass
|
||||
copy("keepalive_timeout", "node", "timeout.keepalive")
|
||||
copy("disconnect_timeout", "node", "timeout.disconnect")
|
||||
|
||||
@ -320,18 +304,16 @@ class Node(service.MultiService):
|
||||
# running, which means after startService.
|
||||
l = self.tub.getListeners()[0]
|
||||
portnum = l.getPortnum()
|
||||
# record which port we're listening on, so we can grab the same one next time
|
||||
# record which port we're listening on, so we can grab the same one
|
||||
# next time
|
||||
open(self._portnumfile, "w").write("%d\n" % portnum)
|
||||
|
||||
addresses = [ "%s:%d" % (addr, portnum,) for addr in local_addresses ]
|
||||
extra_addresses = self.get_config("node", "advertised_ip_addresses", "")
|
||||
if extra_addresses:
|
||||
extra_addresses = extra_addresses.split(",")
|
||||
addresses.extend(extra_addresses)
|
||||
|
||||
location = ",".join(addresses)
|
||||
base_location = ",".join([ "%s:%d" % (addr, portnum)
|
||||
for addr in local_addresses ])
|
||||
location = self.get_config("node", "tub.location", base_location)
|
||||
self.log("Tub location set to %s" % location)
|
||||
self.tub.setLocation(location)
|
||||
|
||||
return self.tub
|
||||
|
||||
def when_tub_ready(self):
|
||||
|
@ -73,7 +73,7 @@ def write_node_config(c, config):
|
||||
c.write("web.port = %s\n" % webport)
|
||||
c.write("web.static = public_html\n")
|
||||
c.write("#tub.port =\n")
|
||||
c.write("#advertised_ip_addresses =\n")
|
||||
c.write("#tub.location = \n")
|
||||
c.write("#log_gatherer.furl =\n")
|
||||
c.write("#timeout.keepalive =\n")
|
||||
c.write("#timeout.disconnect =\n")
|
||||
|
@ -29,11 +29,12 @@ class TestCase(unittest.TestCase, testutil.SignalMixin):
|
||||
d.addCallback(flushEventualQueue)
|
||||
return d
|
||||
|
||||
def test_advertised_ip_addresses(self):
|
||||
basedir = "test_node/test_advertised_ip_addresses"
|
||||
def test_location(self):
|
||||
basedir = "test_node/test_location"
|
||||
fileutil.make_dirs(basedir)
|
||||
f = open(os.path.join(basedir, 'advertised_ip_addresses'),'w')
|
||||
f.write('1.2.3.4:5')
|
||||
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
||||
f.write("[node]\n")
|
||||
f.write("tub.location = 1.2.3.4:5\n")
|
||||
f.close()
|
||||
|
||||
n = TestNode(basedir)
|
||||
@ -47,31 +48,22 @@ class TestCase(unittest.TestCase, testutil.SignalMixin):
|
||||
d.addCallback(_check_addresses)
|
||||
return d
|
||||
|
||||
def test_advertised_ip_addresses2(self):
|
||||
basedir = "test_node/test_advertised_ip_addresses2"
|
||||
def test_location2(self):
|
||||
basedir = "test_node/test_location2"
|
||||
fileutil.make_dirs(basedir)
|
||||
f = open(os.path.join(basedir, 'tahoe.cfg'), 'wt')
|
||||
f.write("[node]\n")
|
||||
f.write("tub.location = 1.2.3.4:5,example.org:8091\n")
|
||||
f.close()
|
||||
|
||||
n = TestNode(basedir)
|
||||
n.setServiceParent(self.parent)
|
||||
d = n.when_tub_ready()
|
||||
# this lets the 'port' file get written
|
||||
d.addCallback(lambda res: n.disownServiceParent())
|
||||
def _new_node(res):
|
||||
f = open(os.path.join(basedir, 'advertised_ip_addresses'),'w')
|
||||
f.write('1.2.3.4\n')
|
||||
f.write("6.7.8.9\n")
|
||||
f.close()
|
||||
n2 = self.node = TestNode(basedir)
|
||||
n2.setServiceParent(self.parent)
|
||||
return n2.when_tub_ready()
|
||||
d.addCallback(_new_node)
|
||||
|
||||
def _check_addresses(ignored_result):
|
||||
portfile = os.path.join(basedir, self.node.PORTNUMFILE)
|
||||
port = int(open(portfile, "r").read().strip())
|
||||
furl = self.node.tub.registerReference(n)
|
||||
self.failUnless(("1.2.3.4:%d" % port) in furl, furl)
|
||||
self.failUnless(("6.7.8.9:%d" % port) in furl, furl)
|
||||
furl = n.tub.registerReference(n)
|
||||
self.failUnless("1.2.3.4:5" in furl, furl)
|
||||
self.failUnless("example.org:8091" in furl, furl)
|
||||
|
||||
d.addCallback(_check_addresses)
|
||||
return d
|
||||
|
Loading…
x
Reference in New Issue
Block a user