Back in 2014, Tor moved from three guard nodes to one guard node: https://blog.torproject.org/improving-tors-anonymity-changing-guard-paramete... https://trac.torproject.org/projects/tor/ticket/12206
We made this change primarily to limit points of observability of entry into the Tor network for clients and onion services, as well as to reduce the ability of an adversary to track clients as they move from one internet connection to another by their choice of guards.
At the time, I was in favor of two entry guards but did not have a strong preference, and we ended up choosing one guard. After seeing various consequences of using only one entry guard, I think a much stronger case can now be made for bumping back up to two.
Roger suggested that I enumerate the pros and cons of this increase on this mailing list, so we can discuss and consider this switch. So here is my attempt at that list. Let's start with a more in-depth recap of the one-guard arguments, along with some recent observations that change things.
Arguments for staying with just one guard:
1. One guard means less observability.
As Roger put it in the above blog post: "I think the analysis of the network-level adversary in Aaron's paper is the strongest argument for restricting the variety of Internet paths that traffic takes between the Tor client and the Tor network." http://freehaven.net/anonbib/#ccs2013-usersrouted
Unfortunately, we have since learned that Tor's path selection has the effect of giving the adversary the ability to generate at least one additional observation path. We first became aware of this in https://trac.torproject.org/projects/tor/ticket/14917, where the change to one guard allowed an adversary to discover your guard by choosing it as a rendezvous point and observing the circuit failure. After the fix for #14917, the onion service will build a connection to a second guard that it keeps in reserve. By using this attack (as well as a similar but more involved attack with unique exit policies and carefully chosen /16 exit node subnets), the adversary can force clients to be observed over two paths whenever they like.
So while we may get benefit for moving from three guards to two guards, we don't get much (or any) benefit from moving to two guards to one guard against an active adversary that either connects to onion services, or serves content to clients and runs exits.
2. Guard fingerprintability is lower with one guard
An adversary who is watching netflow connection records for an entire area is able to track users as they move from internet connection to internet connection through the degree of uniqueness of their guard choice. There is much less information in two guards than three, but still significantly more than with one guard: https://trac.torproject.org/projects/tor/ticket/9273#comment:3
But, even with one guard, if there are not very many Tor users in your area, you still may be trackable. "Guard bucket" designs are discussed on the blog post and in related tickets, but they are complicated and involve tricky tradeoffs (see https://trac.torproject.org/projects/tor/ticket/9273#comment:4). The best solution that I see to this is to make Tor maintain separate guard choices depending on the current SSID, BSSID, or default gateway router MAC from ARP. The default gateway ARP MAC is probably easiest for us to implement cross-platform and stable across wifi to ethernet.
Arguments in favor of switching to two entry guards:
1. One guard allows course-grained netflow confirmation attacks
The counterargument based on #14917 above also has an additional wrinkle: an adversary watching a suspect list of clients can easily observe the "temporarily use a second guard" activity using just connection-level ISP/AS netflow logs. To a large-scale netflow adversary, the use of a second guard only when the guard is chosen as the RP confirms not only guard choice, but the IP address of the onion service itself.
Again, similar attacks may be possible against exit activity via cleverly crafted exit policies and /16 subnet choice. (Aside: if we allow routers to join any family they like without reciprocation, this attack becomes worse.)
Having a dedicated second guard that is always in use will prevent the creation and exclusive use of a new TLS connection just for this request. Instead, the two TLS connections will both remain open and in regular use as long as the client is active.
2. More than one guard allows us to deploy conflux.
As mentioned in the blog post, moving to one guard prevents us from deploying conflux -- a research design that improves Tor performance by combining two or more circuits together at an exit node or rendezvous point and load balancing between them: https://www.cypherpunks.ca/~iang/pubs/conflux-pets.pdf
Conflux works by giving circuits a 256bit cookie that is send to the exit/RP, and circuits that are then built to the same exit/RP with the same cookie can then be fused together.
Conflux was originally studied exclusively for performance, but the technique has other uses as well.
If our conflux implementation includes packet acking, then circuits can still survive the loss of one guard node due to DoS, OOM, or churn because the second half of the path will remain open and usable.
Furthermore, if exits remember this cookie for a short period of time after the last circuit is closed, the technique can be used to protect against DoS/OOM/guard downtime conditions that take down both guard nodes or destroy many circuits to confirm both guard node choices. In these cases, circuits could be rebuilt along an alternate path and resumed without end-to-end circuit connectivity loss. This same technique will also make things like ephemeral bridges (ie Snowflake/Flashproxy) more usable, because bridge uptime will no longer be so crucial to usability. It will also improve mobile usability by allowing us to resume connections after mobile Tor apps are briefly suspended, or if the user switches between cell and wifi networks.
Furthermore, I believe that conflux will also be useful against traffic analysis and congestion attacks. Since the load balancing is dynamic and hard to predict by an external observer, traffic correlation and website traffic fingerprinting attacks will become harder, because the adversary can no longer be sure what percentage of the traffic they have seen (depending on their position and other potential concurrent activity). Similarly, it should also help dampen congestion attacks, since traffic will automatically shift away from a congested guard.
So those are the major two arguments on each side. There are some additional minor arguments in favor of two guards (Circuit build timeout works better with more guards because it can avoid the slower guard, and a second guard will also prevent information leaks like https://trac.torproject.org/projects/tor/ticket/24487), but for brevity I decided to mention those only in passing.
In terms of deployment, the switch to two guards is an extremely simple one. We should only need to set the NumEntryGuards=2 consensus parameter, and all recent clients will switch over immediately.
What do we think?