TrackHostExits forces circuits to same exit, regardless of SOCKSPort isolation flags
I've noticed that adding the line
TrackHostExits . interferes with SOCKSPort 9050 IsolateClientProtocol IsolateSOCKSAuth SOCKSPort 9060 IsolateClientProtocol IsolateSOCKSAuth and possibly other isolation flags.
Steps to reproduce:
- Disable TrackHostExits
- Run two Tor Browser instances pointed at different SOCKSPorts, or run twice
torsocks curl https://check.torproject.org
with IsolatePID=1. You should get two different exit IPs. - Enable TrackHostExits and repeat step 2. You will get the same IP accross different Tor Browser instances using different SOCKSPorts, or two instances of torsocks even when IsolatePID=1.
Expected result: With TrackHostExits, Tor should track the host exit node within the scope of the client SOCKSPort (IsolateClientProtocol) and in compliance with other isolation flags. That is, 127.0.0.1:9050 to check.torproject.org should use the same exit until TrackHostExitsExpire, but should NOT use that same exit for 127.0.0.1:9060 to check.torproject.org if IsolateClientProtocol is enabled. The same should go for IsolateSOCKSAuth (used by torsocks IsolatePID=1), but for the SOCKS username and password rather than port, and all other isolation flags based on their respective criteria.
Note, from the Torrc manual page:
IsolateClientProtocol Don’t share circuits with streams using a different protocol. (SOCKS 4, SOCKS 5, TransPort connections, NATDPort connections, and DNSPort requests are all considered to be different protocols.) Although TransPort 9040 and SOCKSPort 9050 are different protocols subject to isolation from one another, the language does not make it completely clear whether SOCKSPort 9050 is different from SOCKSPort 9060, for example. In my testing, different SOCKSPorts do seem to be treated as different protocols, subject to isolation when TrackHostExits is disabled. Even if they are considered the same protocol, not subject to isolation, this doesn't explain why unique SOCKS usernames/passwords are not isolated.
Actual result: With TrackHostExits enabled, Tor appears to share circuits to the same exit across all combinations of SOCKSPorts and SOCKS username/password combinations. This effectively negates the effects of IsolatePID=1 and the "New Tor circuit for this site" button in Tor Browser, as well as Tor Browsers connecting on different SOCKSPorts, and possibly violates all other isolation flags.
Use cases:
- Using multiple Tor Browsers on different SOCKSPorts that all use the system-installed Tor, or the same instance of the user-installed Tor. Ideally the user should be able to simultaneously take advantage of:
- Browser-level (cache, etc) isolation between instances of Tor Browser.
- Circuit-level exit isolation between those instances.
- TrackHostExits within, but not between, those instances, in cases where sites expire authentication cookies when the exit changes.
- Using the "New Tor circuit for this site" button in Tor Browser.
- Using IsolatePID=1 with torsocks. Long lived applications should be able to reuse exits until TrackHostExitsExpire, but NOT share them with other PIDs.
Workarounds:
- Run multiple instances of Tor.
- Requires multiple users, or some kind of chroot, in order to work around hardcoded paths, and manual torrc/browser port configuration. Running multiple instances of Tor as the same user is non-trivial.
- Consumes additional bandwidth and machine resources.
- Makes it more difficult to firewall non-Tor traffic using
iptables -m owner --uid-owner "tor"
- Disable TrackHostExits
- Some sites will expire authentication cookies frequently and require the user to login again. As this is often a security measure, it is not really a bug on the site's part.
- Use the site's .onion address.
- Many sites do not have a .onion address.
Possible fixes: TrackHostExits in compliance with existing isolation flags, the same way as if TrackHostExits is disabled, as described above.
Alternatively, allow TrackHostExits to be set on a port-by-port basis. E.g.
SocksPort 9050 IsolateClientProtocol TrackHostExits="." SocksPort 9060 IsolateClientProtocol TrackHostExits="example.org,example.com" SocksPort 9070 IsolateClientProtocol In this example, exit tracking is disabled for 9070, enabled for 9050 and 9060, but Tor should NOT share circuits between 9050 and 9060. This alternative solution is more of an enhancement while the first one is a bug fix.
Not tested: IsolateClientAddr IsolateDestAddr IsolateDestPort SessionGroup