Hi,
I'll try to sum up Exit Enclaving in no certain terms and hope that Nick or someone else will chime in to correct my assumptions. This should probably be formalized and put into the path-spec at some point. I was surprised to not see it in there to begin with but I probably just missed it. Anyway, without further delay...
When Tor builds a circuit it does so with certain constraints in mind - most of these are described in the path-spec. Exit Enclaving is a set of client circuit building constraints that all go together. When a user wishes to connect to a given IP address, Tor will check this IP against all of the Tor nodes in the Tor consensus. If the IP address in question is a Tor node in the consensus, the Tor client will check the selected Tor node's exit policy. If the Tor node's exit policy allows connections to *itself* - that is the IP address of Tor node - we check that the requested port is allowed by that policy. If we find that this set of constraints is matched, we build a *four* hop circuit to the Tor node that has the same IP as our request. The Tor node that matches is the fourth hop and we force exiting to the service offered by that node. The user then exits from the Tor node that met the constraints and they're connected to the service offered by that Tor node. As a result, client security is greatly improved by using Tor as the full path to the services offered on that Tor node.
Obviously, with a bit of firewall trickery, it would be possible to offer the services on another physical host but the general point still stands - the service on a given IP address may only be enclaved by an IP address that is a confirmed Tor relay.
I think Exit Enclaving is confusing for the uninitiated. It is documented but not in the standard Tor ways and it appears to be one of the lesser understood things in Tor land. Here's the official documentation as far as I've found it : https://trac.torproject.org/projects/tor/wiki/doc/ExitEnclave
Here's the important bits from that page:
SocksPort 9050 # what port to open for local application connections SocksListenAddress 127.0.0.1 # accept connections only from localhost ORPort 9001 Nickname archivetpo ExitPolicyRejectPrivate 0 ExitPolicy accept 38.229.70.19:443 ExitPolicy reject *:*
There are a few references to the term (Exit) Enclave in the torspec.git repo but none of them actually define how it works with absolute authority. At best we've described how to try to become one without actually explaining the essence concretely in a specification. I think we should add a paragraph to the man page as well as the torspec. I'd be happy to write it once we actually hammer out the current and pas client behaviour.
There is a problem with the current Exit Enclaving approach and if anything, it's not the worst one to have. If the user attempts to connect with a name, we are unable to try to satisfy the constraints that require an IP address; so we just skip Enclaving entirely for that connection. After the first sucessful connection or the first time Tor resolves the name, we're able to take the above steps in our attempt to opportunistically enclave. Before that - the Tor client only knows the name and thus the IP address is a mystery. Generally this results in the first connection exiting via any other node that allows exiting to the target host. I think this is perhaps an anonymity concern as it shows that the Tor client has likely not connected to the host in question - an evil Exit might take note of this and watch for correlated streams over time, etc.
Here's an example of a semi-popular website documenting their enclaving experience: http://www.gabrielweinberg.com/blog/2010/08/duckduckgo-now-operates-a-tor-ex...
Recently the CCC jabber server became an exit enclave and a hidden service, similar to the DuckDuckGo setup: https://twitter.com/#!/jabbercccde/status/107850926638895104 https://twitter.com/#!/jabbercccde/status/107850540842627072
As I stated previously, I think that the use of Exit Enclaves greatly improves client security. It reduces the chances of a network sniffer getting lucky, it helps to mitigate the severity of services getting crypto stuff wrong, etc.
I think it would be nice to make this easier to set-up and configure for server administrators. I'd also like to make this more flexible for Tor clients and if possible, find some methods for making Tor clients automatically enclave on the first connection.
There are a few ways that we might see Exit Enclaving happen on the first connection. It is possible to make the first connection enclave if the client is using the TorDNSPort; Tor will have resolved and cached the names used by all clients, connections by names should then Enclave and connections by IP will Enclave as well. Alternatively, having all connections to Tor happen by IP address only would force all clients to Enclave on first connection. I think this is probably dangerous in all cases except a Transparent Tor network. Another possible hack is to set MapAddress for the hosts that matter to you - this doesn't scale very well and it's confusing for most people; it isn't dynamic and it seems that it will likely desynchronise over time.
I'd like to advocate for a simple set of options to make this stuff easier to use and more likely to be used by a server admin.
Here's a bug where I suggest an option OfferExitEnclave that is either a bool or a port list: https://trac.torproject.org/projects/tor/ticket/800
My thought was that a service provider who wants to offer enhanced service to Tor users could set a single flag and it would create a Tor Exit node that only exits to itself; I imagine that it might make sense to change the advertised bandwidth. It might even be a good idea to set a reasonable bandwidth cap of sorts but I think this is probably not great until we can automatically guess intelligently. I imagine that flipping the hypothetical OfferExitEnclave switch would actually be short hand for the following:
ORPort auto Nickname exitenclave MaxAdvertisedBandwidth 20KB ExitPolicyRejectPrivate 0 ExitPolicy accept ORListenConfirmedPublicAddress:* ExitPolicy reject *:*
Thus when we want to help someone enclave their entire host - we tell them to flip a single flag like so:
OfferExitEnclave 1
If they want to enclave a specific service on their host - we tell them to flip the same flag like so: OfferExitEnclave 1 ExitEnclavePorts 5222
I'm not sold on that set of options but I think offering at least the OfferExitEnclave option as a bool would result in a lot more clarity for a server admin who wants to enhance their services for use with Tor.
I think that generally, the nice part about Exit Enclaving is that it works as well as the rest of Tor - it does not really rely on external dependencies at all - no need for DNS or DNSSEC stuff, no need for the authorities to do any extra work on a per node basis, the client can use a different exit if they like, etc.
On the client side, I think that would could make some improvements that aren't merely cosmetic but when enabled would improve client security. As I've already stated, Transparent Tor networks with TorDNSPort do this automatically by the nature of how they function. Other than the Torouter and probably TAILS, I'm not sure of other projects that takes advantage of this option. I'm not even certain that it will work in the long term for Torouter because of SRV records and jabber clients.
Generally the client situation as it stands today lacks a general switch to force attempts at Exit Enclaving by name. Such an option would force a full round trip. Certainly we lack a general manner that attempts to Exit Enclave for all hosts and I'd like to see that change.
I think it would be nice to have a few options and I'm far from sold on any of them. I'll lay them out as if they were already implemented.
LearnExitEnclaveNames 0|1
This option could learn what possible names are frequently used and opportunistically resolve them, perhaps even caching some meta-data about exit enclaves that we've used, if it was stable, etc - this is could be something like a mash up TrackHostExits, LongLivedPorts, MapAddress, and something that learns overtime the hosts you use regularly.
I think it would need some work to be done in a privacy preserving manner, probably with something like scrypt, if it needed to be cached on disk. This would solve the problem of a host being a known Exit Enclave after the first resovle and then later expiring from Tor's internal DNS cache. I think this is a common problem for IM connections and simply marking that name as something worth the round trip would be a huge gain, even if only for a single Tor run where the results are never cached on disk. My Tor often runs for days at a time and I think that the DNS cache internally expires before my Tor client exits. I'm pretty sure that means that it's up to my IM client or other software to cache the IP or we're back to square zero.
AttemptExitEnclaving 0|1
This option could simply force the full round trip for all connections. Simple enough but likely a major performance hit. The default would be zero and keep things as they are today.
AttemptExitEnclavingPorts [port list]
This option could attempt Enclaving for any connections to any host if the connection is to one of the listed ports.
AlwaysAttemptEnclaveNames [list of names]
This option could take a list of names where we want to force a full round trip and that we'd like to enclave. Perhaps it would even fail to work if the Enclaving would fail and perhaps it could fail in a helpful manner. I imagine that some people might like this for customised browser bundles or if they're a power user who knows what they want, etc.
I know that Nick had some suggestions - perhaps adding known Exit Enclaving names into the consensus or into descriptors or something that the directory authorities handle. I'm not sure that I fully understand his suggestions and I look forward to his reply to this email. :)
All the best, Jake