[tor-dev] Proposal 312: Automatic Relay IPv6 Addresses

teor teor at riseup.net
Wed Feb 5 02:56:46 UTC 2020

Hi Nick,

Thanks so much for your review!

I've made most of the changes you've suggested, you can see the latest
version of the proposal here:

I've also made changes in response to s7r's feedback about IPv6 privacy
extensions. Since sending the draft, I've also noticed some missing
information, and some things that could be explained better.

I'm trying to keep a clear distinction in this proposal, to keep the
sponsor 55 scope manageable. So I am keeping different sections for:
  * required changes: changes that we must make to achieve the objectives
                      of sponsor 55
  * optional changes: good ideas that we can implement if we have time left
                      in sponsor 55, or in future IPv6 work

There's some flexibility, particularly if we decide that an optional
change is the fastest way to get something implemented.

I'll send another full text to the list when all the reviews are done.

I've also responded to your comments below individually:

> On 31 Jan 2020, at 08:08, Nick Mathewson <nickm at torproject.org> wrote:
> On Wed, Jan 29, 2020 at 9:04 AM teor <teor at riseup.net> wrote:
> Hello again!  This looks like another fine proposal.  I'm leaving
> comments inline, and clipping sections that I'm not commenting on.
>> Filename: 312-relay-auto-ipv6-addr.txt
>> Title: Tor Relays Automatically Find Their IPv6 Address
>> Author: teor
>> Created: 28-January-2020
>> Status: Draft
>> Ticket: #33073
>> 0. Abstract
>>   We propose that Tor relays (and bridges) should automatically find their
>>   IPv6 address, and use it to publish an IPv6 ORPort. For some relays to find
>>   their IPv6 address, they may need to fetch some directory documents from
>>   directory authorities over IPv6. (For anonymity reasons, bridges are unable
>>   to fetch directory documents over IPv6, until clients start to do so.)
>> 1. Introduction
>>   Tor relays (and bridges) currently find their IPv4 address, and use it as
>>   their ORPort and DirPort address when publishing their descriptor. But
>>   relays and bridges do not automatically find their IPv6 address.
> At the beginning of this document, we should be a bit more clear about
> which address specifically we're trying to find.  If we wanted _some_
> address, or if NAT and firewalls didn't exist, we could just open a
> socket, call getsockname(), and be done with it.  What we are looking
> for specifically is an address that we can advertise to the rest of
> the world in our server descriptor.  [I know you know this, but we
> should say so.]

Thanks, that's a great reminder. I've explained how we use the detected
IP addresses, and what kind of addresses we are looking for.

I've left a detailed description of how we ignore private addresses, and
use other methods, to later in the proposal.

Please see this commit:

> [...]
>> 3. Finding Relay IPv6 Addresses
>>   We propose that tor relays (and bridges) automatically find their IPv6
>>   address, and use it to publish an IPv6 ORPort.
>>   For some relays to find their IPv6 address, they may need to fetch some
>>   directory documents from directory authorities over IPv6. (For anonymity
>>   reasons, bridges are unable to fetch directory documents over IPv6, until
>>   clients start to do so.)
>> 3.1. Current Relay IPv4 Address Implementation
>>   Currently, all relays (and bridges) must have an IPv4 address. IPv6
>>   addresses are optional for relays.
>>   Tor currently tries to find relay IPv4 addresses in this order:
>>     1. the Address torrc option
>>     2. the address of the hostname (resolved using DNS, if needed)
>>     3. a local interface address
>>        (by making a self-connected socket, if needed)
>>     4. an address reported by a directory server (using X-Your-Address-Is)
> Any server, or only an authority?  Over any connection, or only an
> authenticated one?

Thanks for picking up on this inconsistency.

In the current implementation, when a tor relay doesn't know its address, it
tried to fetch from directory authorities. But it will believe an addresses from
any directory server.

Relays try to use DirPorts, even if they don't know their own IP address. But if
they select a directory mirror that only has an ORPort, they will use its ORPort.

I've fixed this particular inconsistency in this commit:

Ideally, relays should use authenticated directory authorities to discover their
addresses. But it's not a simple change, because it affects directory authority
load balancing.

So I've put it in the "optional changes" section of the proposal. If we have time,
we should make these changes, with high priority.

For more details, see sections 3.5.1, 3.5.2, and 3.5.3 in:

> [...]
>> 3.2. Finding Relay IPv6 Addresses
>>   We propose that relays (and bridges) try to find their IPv6 address. For
>>   consistency, we also propose to change the address resolution order for
>>   IPv4 addresses.
>>   We use the following general principles to choose the order of IP address
>>   methods:
>>     * Explicit is better than Implicit,
>>     * Local Information is better than a Remote Dependency,
>>     * Trusted is better than Untrusted, and
>>     * Reliable is better than Unreliable.
>>   Within these constraints, we try to find the simplest working design.
> We should make sure to be clear about the impact of using an untrusted
> source.  Anybody who can fool a relay about its IP can effectively
> MITM that relay's incoming connections (traffic patterns only), so
> using a non-trusted source can be risky for anonymity.

I've explained the attack here:

And some potential mitigations in sections 3.5.1, 3.5.2, and 3.5.3 in:

> [...]
>>   (Each of these address resolution steps is described in more detail, in its
>>   own subsection.)
>>   While making these changes, we want to preserve tor's existing behaviour:
>>     * resolve Address using the local resolver, if needed,
>>     * ignore private addresses on public tor networks, and
>>     * when there are multiple valid addresses, choose the first or latest
>>       address, as appropriate.
> Instead of "first or latest" I suggest "first-listed or most recently
> received" here, to help non-native speakers.

I expanded the explanation so it says *when* we use each address selection
heuristic. And I made sure that the heuristics are not described as (exclusive)

Some methods may actually deliver a list of addresses, *and* that list may change
over time (DNS, local interfaces). So tor may need to use both heuristics for a
single method.

See commit:

>> 3.2.1. Make the Address torrc Option Support IPv6
> [...]
>>   It is an error to configure an Address option with a private IPv4 or IPv6
>>   address, or with a hostname that does not resolve to any publicly routable
>>   IPv4 or IPv6 addresses.
> We should say "on a public network" here -- private addresses are fine
> on private networks.

Thanks, I made a similar change in:

> Also, this seems to mean that if the relay's DNS resolver goes down,
> the relay should give an error and exit, even if it was already
> running.  That seems undesired.

I changed it to "tor should warn" in:

> [...]
>> 3.2.2. Use the Advertised ORPort IPv4 and IPv6 Addresses
>>   Next, we propose that relays (and bridges) use the first advertised ORPort
>>   IPv4 and IPv6 addresses, as configured in their torrc.
>>   The ORPort address may be a hostname. If it is, tor should try to use it to
>>   resolve an IPv4 and IPv6 address, and open ORPorts on the first available
>>   IPv4 and IPv6 address. Tor should respect the IPv4Only and IPv6Only port
>>   flags, if specified. (Tor currently resolves IPv4 addresses in ORPort
>>   lines. It may not look for an IPv6 address.)
>>   Relays (and bridges) currently use the first advertised ORPort IPv6 address
>>   as their IPv6 address. We propose to use the first advertised IPv4 ORPort
>>   address in a similar way, for consistency.
>>   Therefore, this change may affect existing relay IPv4 addressses. We expect
>>   that a small number of relays may change IPv4 address, from a guessed IPv4
>>   address, to their first advertised IPv4 ORPort address.
>>   In rare cases, relays may have been using non-advertised ORPorts for their
>>   addresses. This change may also change their addresses.
>>   We propose ignoring private configured ORPort addresses on public tor
>>   networks. (Binding to private ORPort addresses is supported, even on public
>>   tor networks, for relays that use NAT to reach the Internet.) If an ORPort
>>   address is private, address resolution should go to the next step.
>> 3.2.3. Use the Advertised DirPort IPv4 Address
>>   Next, we propose that relays use the first advertised DirPort IPv4 address,
>>   as configured in their torrc.
> I think that we could omit this method; it seems unlikely to me that
> anybody is going to configure an advertised DirPort address but not an
> advertised ORPort address.   In the long run, I think we want DirPorts
> to disappear entirely as part of our official protocol.

I agree that:

ORPort 8888

is probably a rare configuration.

I originally added this method, because of a bug with DirPort addresses:

But I don't think the DirPort method would actually fix that bug. So I've
removed the DirPort method entirely:

>> 3.2.4. Use Local Interface IPv6 Address
>>   Next, we propose that relays (and bridges) use publicly routable addresses
>>   from the OS interface addresses or routing table, as their IPv4 and IPv6
>>   addresses.
>>   Tor has local interface address resolution functions, which support most
>>   major OSes. Tor uses these functions to guess its IPv4 address. We propose
>>   using them to also guess tor's IPv6 address.
>>   We also propose modifying the address resolution order, so interface
>>   addresses are used before the local hostname. This decision is based
>>   on our principles: interface addresses are local, trusted, and reliable;
>>   hostname lookups may be remote, untrusted, and unreliable.
>>   Some developer documentation also recommends using interface addresses,
>>   rather than resolving the host's own hostname. For example, on recent
>>   versions of macOS, the man pages tell developers to use interface addresses
>>   (getifaddrs) rather than look up the host's own hostname (gethostname and
>>   getaddrinfo). Unfortunately, these man pages don't seem to be available
>>   online, except for short quotes (see [getaddrinfo man page] for the
>>   relevant quote).
>>   If the local interface addresses are unavailable, tor opens a self-connected
>>   UDP socket to a publicly routable address, but doesn't actually send any
>>   packets. Instead, it uses the socket APIs to discover the interface address
>>   for the socket.
> I don't understand in which sense this socket is  "self-connected" --
> maybe "unused" or something?

Thanks, I've made this change in:

> Also I'd suggest that Tor should use an
> authority's IP address for this purpose.  Currently, we use,
> which tends to confuse people who are looking at their firewall's
> warnings.

Or for IPv6, we use [2002::].

I've described this optional change in a new section:

>>   Tor already ignores private IPv4 interface addresses on public relays.
>>   (Binding to private DirPort addresses is supported, for networks that use
>>   NAT.) We propose to also ignore private IPv6 interface addresses. If all
>>   IPv4 or IPv6 interface addresses are private, address resolution should go
>>   to the next step.
>> 3.2.5. Use Own Hostname IPv6 Addresses
>>   Next, we propose that relays (and bridges) get their local hostname, look
>>   up its addresses, and use them as its IPv4 and IPv6 addresses.
>>   We propose to use the same underlying lookup functions to look up the IPv4
>>   and IPv6 addresses for:
>>     * the Address torrc option (see section 3.2.1), and
>>     * the local hostname.
>>   However, OS APIs typically only return a single hostname.
>>   Even though the hostname lookup may use remote DNS, we propose to use it on
>>   directory authorities, to maintain compatibility with current
>>   configurations. Even if it is remote, we expect the configured DNS to be
>>   somewhat trusted by the operator.
> Do you mean to say "directory authorities" here? I don't understand that part.

I agree it's unclear.

I've changed the proposal to require explicitly configured addresses on
directory authorities, in:

> [...]
>> 3.2.6. Use Directory Header IPv6 Addresses
>>   Finally, we propose that relays get their IPv4 and IPv6 addresses from the
>>   X-Your-Address-Is HTTP header in tor directory documents. To support this
>>   change, we propose that relays start fetching directory documents over IPv4
>>   and IPv6.
> Can we specify use of NETINFO cells additionally or instead?  Unlike
> DirPort connections, ORPort connections are authenticated, so we know
> who is telling us what our address is.

I've added an optional section for NETINFO cells:

>>   We propose that bridges continue to only fetch directory documents over
>>   IPv4, because they try to imitate clients. (Most clients only fetch
>>   directory documents over IPv4, a few clients are configured to only fetch
>>   over IPv6.) When client behaviour changes to use both IPv4 and IPv6 for
>>   directory fetches, bridge behaviour can also change to match. (See
>>   section 3.4.1 and [Proposal 306: Client Auto IPv6 Connections].)
>>   We propose that directory authorities should ignore addresses in directory
>>   headers. Allowing other authorities (or relays?) to change a directory
>>   authority's published IP address may lead to security issues. Instead,
>>   if interface and hostname lookups fail, tor should stop address resolution,
>>   and return a permanent error. (And issue a log to the operator, see below.)
> I suggest that we simplify the whole directory authority logic and say
> that authorities must have configured Address lines, or nothing.

That's a breaking change for most directory authority operators, including
all operators whose authorities have IPv6 ORPorts.

I've tweaked this change slightly, so that directory authorities:
* only use IPv4 and IPv6 address literals
* use the addresses configured in Address, then ORPort, then stop

This design has the following benefits:
* support current configs that set ORPort [IPv6]:Port
* only use explicitly configured addresses
* no DNS, or any other dynamic lookups, even for Address or ORPort,
  (authorities currently use DNS to lookup hostnames in Address lines)
* no implicit addresses, even using local information, like interface
  addresses (it's not necessary)

It's only a breaking change when necessary for security: that is, when
authorities are depending on hostnames, or other implicit address

Here's the detailed design:

> [...]
>> 3.3. Consequential Tor Client Changes
>>   We do not propose any required client address resolution changes at this
>>   time.
>>   However, clients will use the updated address resolution functions to detect
>>   when they are on a new connection, and therefore need to rotate their TLS
>>   keys.
> Do clients have meaningful TLS keys any more, now that they have
> dropped client support for the v1 link protocol?
> (This is just a side question -- clients should still have a working
> ip_address_changed() function.)

I'm really not sure. I'm working off the functions and comments, which are all
still in the current codebase.

I think it's out of scope for this proposal, but maybe worth opening a ticket.

Is there a specific change you'd like to this proposal?

Deleting ", and therefore need to rotate their TLS keys." ?

> [...]
>> 3.5. Optional Efficiency and Reliability Changes
>>   We propose some optional changes for efficiency and reliability, and
>>   describe their impact.
>>   Some of these changes may be more appropriate in future releases, or
>>   along with other proposed features.
>> 3.5.1. Only Use Authenticated Directory Header IPv4 and IPv6 Addresses
>>   We propose this optional change, to improve relay address accuracy and
>>   reliability.
> I am +1 here, with a proviso that we should be able to use NETINFO cells.

That's an optional change, in:

> [...]
>> 3.5.5. Add IPv6 Support to AuthDirMaxServersPerAddr
>>   We propose this optional change, to improve the health of the network, by
>>   rejecting too many relays on the same IPv6 address.
>>   Modify get_possible_sybil_list() so it takes an address family argument,
>>   and returns a list of IPv4 or IPv6 sybils.
>>   Use the modified get_possible_sybil_list() to exclude relays from the
>>   authority's vote, if there are more than AuthDirMaxServersPerAddr on the
>>   same IPv4 or IPv6 address.
>>   Since these relay exclusions happen at voting time, they do not require a
>>   new consensus method.
> Since it's trivial for one host to have a staggering number of IPv6
> addresses, should this specify a /80 or /96 or something as being
> sybil-like?

You're thinking way too small :-)

The typical host allocation is /64, and the smallest provider site allocation
is also usually /64.

Therefore, I think we should add a new AuthDirMaxServersPerIPv6Site option,
and analyse the current network to choose its default value:

(Personally, I've run 6 relays on one IPv6 address.)

> [...]
>> 3.5.7. Add IPv6 Support Using gethostbyname2()
> I agree that this change should be unnecessary; I'd suggest that we
> not do it and just require getaddrinfo() for meaningful IPv6
> resolution.
> Alternatively, we could use libevent's DNS.

I agree that this change may be unnecessary. It's already in the list of
optional changes in the proposal.

I've added libevent as our preferred DNS API, if we discover that a large
number of systems don't support IPv6 DNS, because they're using


>> 3.5.8. Change Relay OutboundBindAddress Defaults
>>   We propose this optional change, to improve the reliability of
>>   IP address-based filters in tor.
>>   For example, the tor network treats relay IP addresses differently when:
>>     * resisting denial of service, and
>>     * selecting canonical, long-term connections.
>>   (See [Ticket 33018: Dir auths using an unsustainable 400+ mbit/s] for the
>>   initial motivation for this change: resisting significant bandwidth load
>>   on directory authorities.)
>>   Now that tor knows its own addresses, we propose that relays (and bridges)
>>   set their IPv4 and IPv6 OutboundBindAddress to these discovered addresses,
>>   by default. If binding fails, tor should fall back to an unbound socket.
> I think this change might be unnecessary, but it shouldn't hurt.  I'd
> suggest not prioritizing it very high.

I agree it's low-priority right now.

But if directory authorities start blocking all non-relay addresses to reduce
load, then we may have to make this change.

For the latest progress on the current authority load issue, see:

> [...]
> In general, this plan above looks solid.
> I have a suggestion before we get into the implementation, though: I
> think we should, for each check, make sure that we write down _when_
> it happens, what makes it happen, and where we store the result.  That
> is, some of these checks are things we need to launch (like looking up
> our own hostname), whereas others will happen passively pretty often
> (like connecting to a directory authority).  Of the ones that we need
> to launch, some will happen only when other methods have failed,
> whereas some will happen on startup.  Some are things that can time
> out, whereas others aren't.  Writing this all down will make sure that
> we aren't making our state machine more complex than it needs to be.
> IMO, we should record the status of all possible IP lookup methods,
> with "not yet tried" being a possible status: it will help us keep our
> implementation and our logging simple -- or at least, as simple as
> can be.

The current state machine is implicit, but it seems to be fit for
purpose. So I didn't propose any modifications to it, because we're
trying to keep the Sponsor 55 work as small as possible.

For similar reasons, I didn't analyse or describe the current or
proposed state machines.

But it was a useful exercise, so I added it to the proposal:

Thanks again for the review!


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Message signed with OpenPGP
URL: <http://lists.torproject.org/pipermail/tor-dev/attachments/20200205/692dfcfd/attachment-0001.sig>

More information about the tor-dev mailing list