To strengthen an "isolating proxy"-style approach to client security, I'd like to allow a Tor bridge node to not reveal its external address(es) in its bridge descriptor. The following patch leaves the address as 0.0.0.0 when it's not going to be published:
diff --git a/src/or/router.c b/src/or/router.cindex 1063eda..30749b9 100644--- a/src/or/router.c+++ b/src/or/router.c@@ -1772,7 +1772,7 @@ router_rebuild_descriptor(int force) { routerinfo_t *ri; extrainfo_t *ei;- uint32_t addr;+ uint32_t addr = 0; char platform[256]; int hibernating = we_are_hibernating(); const or_options_t *options = get_options();@@ -1780,11 +1780,16 @@ router_rebuild_descriptor(int force) if (desc_clean_since && !force) return 0;- if (router_pick_published_address(options, &addr) < 0 ||- router_get_advertised_or_port(options) == 0) {+ /* If we're not trying to publish our descriptor, it's OK to use 0.0.0.0+ * as the address therein.+ */+ if ((options->PublishServerDescriptor_ != NO_DIRINFO) &&+ (router_pick_published_address(options, &addr) < 0 ||+ router_get_advertised_or_port(options) == 0)) { /* Stop trying to rebuild our descriptor every second. We'll * learn that it's time to try again when ip_address_changed() * marks it dirty. */
Trac: Username: nwf
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
...
Show closed items
Linked items
0
Link issues together to show that they're related.
Learn more.
I have been testing with 0.2.2.39 as my proxy and it seems to work fine, FWIW.
Bridge-side, tho', I note that unless I set AssumeReachable 1 and use ExcludeNodes and StrictNodes that the bridge continues to try to test its own reachability by building circuits to 0.0.0.0, which seems wrong. At least there's a workaround.
This is a really neat idea. It could potentially (though not currently, with this patch) allow clients who use bridges which are not contained in BridgeDB to verify the onion-key, signing-key, and fingerprint of their bridge. Although to do that, there ought to be some sort of challenge-response between the client and the bridge, i.e. something like:
client connects to bridge and asks it to sign a nonce.
bridge signs and sends it back.
client checks that the signature was made with the key received from the bridge-server-descriptor, and that both sigs are valid.
I am worried also that private bridges creating falsified descriptors will break things, since BridgeDB, as well as anything else which parses descriptors looking for addresses -- such as (probably) metrics-tasks, stem, and arm, would need to be changed to understand this.
Also, there is much more identifying information in the bridge-server-descriptors than just the IP. I see the following problems:
Would such a bridge report its extrainfo descriptor? Because the @type bridge-extrainfo contains read-history and write-history lines, which, if a bridge has very few users, could possibly damage those user's anonymity. For example, if a bridge had only one user (which could be quite likely, since it is a private bridge), anyone who had this information could possibly determine some information about the browsing habits of the user (though likely no more than sitting outside the user's house in a black van and wiretapping everything).
The @type bridge-server-descriptor contains the contact line which is likely also problematic.
The @type bridge-extrainfo contains also the geoip-client-origins / bridge-ips, these might be problematic. Also, the transport line, if it has one.
Currently, a bridge descriptor (@type bridge-server-descriptor) looks like this:
@purpose bridgerouter thisisafakebridge 11.11.11.11 9001 0 0platform Tor 0.2.3.25 on Linuxopt protocols Link 1 2 Circuit 1published 2013-08-21 12:00:00opt fingerprint 26E5 B0C0 0C5D F12A 3C96 9D35 BA71 4527 8AEC 2B96uptime 2171396bandwidth 5243880 10585760 160875opt extra-info-digest D34DB33FD1511CDDAF9486D8615CCBD48E1C07F8001onion-key-----BEGIN RSA PUBLIC KEY-----MIGJ3oGBAJMrq17ZyIxZBAVwbQXUiY2ZpzNj/fLINjo4snw75wx+sex6iwM+kYsrJMyGOU1oFDUpz6dHXmk/tZw0F46B7TV4Ae+f6iEkRLWNuxah2Jvr8wci55ZAJWV9rVR1sHndj4y3CJeCqYjPxmWUJSxO9evPKjjOZbmbyeJox7alRUkTAgMBAAE=-----END RSA PUBLIC KEY-----signing-key-----BEGIN RSA PUBLIC KEY-----MIGJAoGBALhRvLOjvM2pUSA6Njq29rq23rawYIsk6fvWo9mwucSCQrw75whCMzj8VVWbrpvxkT1bxxEpwuxeawef98u323rqg4ffpsL7riUcKlL4GAG7QhOKVdqCx6FJsvvHOUKCAHTxsqjit2/LzPhQ/DuUxFn9awef8mEUgBs0tIdnaowe24LMBAAE=-----END RSA PUBLIC KEY-----opt hidden-service-dircontact SoAndSo <soandso@example.com>ntor-onion-key AYZTRGjUdo+VuurT3VkgNzPWuUf/LT4VCq78wMwlWio=reject *:*router-signature-----BEGIN SIGNATURE-----PAUsG3Pcz7X39bE8NlCmBBoCOEPQwNhNO52IebNUqnh7gfyoq3dqGqHMIC0PJ5WJSW6P6LAqpi0MopIl8D8YxcD69xWO/0mTBZDaZT3EOEBW2PcYinNg4vwOCj/kxpaMZbl3BpbnudVGzASc7UgxQcjWBtXVOiI44FdX3RtG7tM=-----END SIGNATURE-----
I am worried also that private bridges creating falsified descriptors will break things, since BridgeDB, as well as anything else which parses descriptors looking for addresses -- such as (probably) metrics-tasks, stem, and arm, would need to be changed to understand this.
Arm does not presently use bridge descriptors (it only uses general descriptor information available through the controller interface).
Wiping the address would prevent metrics from producing the sanaitized addresses in the bridge format it publishes. I suspect for Karsten's purposes he would like the address to be something unique (not blanked to 0.0.0.0), though it probably fine for it to be inaccurate. You should double check with him.
If you do write a spec for this please be clearer about the reason for it. When I first read the ticket I thought "Huh? Clients already need the address to get unpublished bridges so what's the purpose of scrubbing the address we respond with?" but then I remembered flash proxies and the other fancy schemes you folks have been coming up with. :)
Arm does not presently use bridge descriptors (it only uses general descriptor information available through the controller interface).
Derp. Misremembered. I think I had a dream once where arm showed me all kinds of magical statistics about bridges, perhaps some of that interface accidentally melded.
Wiping the address would prevent metrics from producing the sanaitized addresses in the bridge format it publishes. I suspect for Karsten's purposes he would like the address to be something unique (not blanked to 0.0.0.0), though it probably fine for it to be inaccurate. You should double check with him.
Although, keeping them all the same might be neat, because it would allow aggregate statistics on private bridge usage. That might be safer, or more privacy-preserving, Karsten would probably know.
The other thing that could be neat is if some range were set aside, like using 127.255.0.0/16 (though this might raise other problems), but then we run into problems if we ever expect to have more than 2^16^ IPv4 bridges. Using entirely random addresses would definitely be a bad idea, because BridgeDB would think these were real bridges at these addresses, and start handing them out to users, who wouldn't be able to connect to them. Not to mention the birthday problem would apply to collisions, but this seems negligible because the total ipv4 address space is 2^24^. Still, I'm not sure what tor does if two ORs claim to have the same address with different keys. Or what the DirAuths do.
Derp. Misremembered. I think I had a dream once where arm showed me all kinds of magical statistics about bridges, perhaps some of that interface accidentally melded.
Maybe it will in the future. I plan on returning to arm development soon so feature requests welcome. :)
Still, I'm not sure what tor does if two ORs claim to have the same address with different keys. Or what the DirAuths do.
Good question. Same address is fine, but duplicate address/orport combination of course would be problematic. My hunch is that they'd reject the descriptors for the newcomer until the old relay disappeared but haven't checked the code.
If you do write a spec for this please be clearer about the reason for it.
The intention here is to allow someone (i.e. me) who might otherwise run a Tor proxy and an "isolating proxy"-style setup to instead run an unpublished Tor bridge and expose its bridge port to the isolated node, which in turn runs a Tor proxy set to use that bridge. The advantages here are
Bridging Tor rather than bringing the SOCKS proxy across the link allows running self-contained hidservs and gives the isolated node full control over its behavior within Tor.
The mechanism of exposure for the bridge port need not be an IP network -- a serial stream will do just fine. This reduces the attack surface available to a would-be de-anonymizing adversary who has compromised the VM, but this reduction is only meaningful if the bridge doesn't announce its address to the isolated node, which is why I had it scrub the address information. (Concretely, consider, for example, that by default Linux responds to ARP requests arriving on any interface for any address configured on any interface; a compromised user node in a typical "isolating proxy" setup would therefore be able to probe the network link between the end node and the Tor proxy, and, if the machine hosting the proxy has a public IP address, thereby de-anonymize the proxy's user. This is just one example; UNIX IP stacks tend to be large and complex and I am doubtful that they could be made believably free of such information exposures. The advantage of using something like a high-speed serial link is that the only attack surface available is the inside of the bridge port, the socat-like tool for bridging serial to TCP on the bridge, and the bridge's kernel's serial layer. Unfortunately, this is currently immaterial due to #7144 (moved); a compromised proxy host in this setup easily reveals its bridges by making circuits through adversary-controlled 2nd hops.)
I recognize that this is something of an abuse of the intended functionality of bridges -- I'm trying to control the proxy's choice of first hops so that I can get a machine which can be said to be reasonably well connected to the Internet but that cannot discover any IP address information for said first hops (and has no non-127/8 address for itself). (Though again see #7144 (moved).)
It could potentially (though not currently, with this patch) allow clients who use bridges which are not contained in BridgeDB to verify the onion-key, signing-key, and fingerprint of their bridge.
I am confused. When I ran this experimentally, the Tor proxy had
in its config file; I thought the wad of hex there was the bridge's fingerprint and that the proxy's connection to the bridge and the bridge's proffered self-descriptor would be verified against it?
I am worried also that private bridges creating falsified descriptors will break things, since BridgeDB, [...]
I'm not sure why BridgeDB is relevant here -- the descriptors are not intended to be published at all?
I'm not entirely clear where this discussion is heading, but once there's a spec or proposal I'm happy to comment on anything related to bridge descriptor sanitizing.
The intention here is to allow someone (i.e. me) who might otherwise run a Tor proxy and an "isolating proxy"-style setup to instead run an unpublished Tor bridge and expose its bridge port to the isolated node, which in turn runs a Tor proxy set to use that bridge.
I suspect there's some context that I'm missing (I'm not quite sure what an '"isolating proxy"-style setup' is, how it relates to bridges, and the explanation left me more confused than illuminated). That said, I'm happy to leave this to isis and nickm if they know what's up. Just let me know if there's any questions regarding descriptor parsing in particular.
Batch modify: these tickets seem to be things that wouldn't actually be a big redesign or a big amount of work, so they belong "Unspecified", not "Very Long Term"
Trac: Milestone: Tor: very long term to Tor: unspecified