Jesse V:
On 09/27/2016 10:05 AM, Jeremy Rand wrote:
Namecoin also can be used for name-level load balancing, although I haven't really carefully considered the anonymity effects of the load balancing (e.g. does it open the risk of fingerprinting?), so that feature is lower priority until I can think about that more carefully. I'm curious how OnioNS is handling that -- maybe there's some thinking in OnioNS's design that's adaptable to Namecoin?
Really? Now I'm curious how Namecoin does it!
OnioNS currently achieves load balancing by allowing the onion service operator to specify a list of secondary addresses. In this case, the name record contains the following:
- RSA-1024 onion service public key
- RSA-1024 signature
- memorable name
- secondary addresses
- "address1.onion"
- "address2.onion"
- (other data)
The client will then randomly select address1.onion or address2.onion and will round-robin until one of them connects. It's a very simple scheme. Right now it looks like this: https://github.com/Jesse-V/OnioNS-common/blob/8217c47bce76d87d056f1bab671c44...
OnioNS also checks that the main public key is in the root directory of each of the secondary addresses to ensure that they are all maintained by the same entity. I am still mulling over possible attacks, defenses, and implications, but in general it seems to work.
So, I admit that I haven't explicitly specced this out yet (or, rather, I started speccing it out in my head, but never really finished fleshing it out), but here's roughly what I was planning. I was actually meaning to ask you (and the other Tor people) what you think of this rough design, as I'm curious if I've overlooked any attacks.
(I'm typing this from memory, so I might have a few details wrong.)
Namecoin would have 2 namespaces for this purpose: the d/ namespace (which is used for all domain names), and the onion/ namespace (a new namespace whose purpose I will discuss below).
Let's say that "debian.bit" is desired to map to a load balance between "abc.onion" and "xyz.onion".
The name owner would register 3 names: d/debian, onion/abc/nonce1, and onion/xyz/nonce2. d/debian would include the following data (in a JSON-based format that also allows it to include things like IP addresses, other DNS records, etc.):
abc.onion nonce1 xyz.onion nonce2
So in other words, d/debian includes all of the .onion addresses that are pointed to, and the nonces that are needed to find the other names. Just like in a Bitcoin transaction, this JSON data is signed by the ECDSA key that owns d/debian.
onion/abc/nonce1 contains the following data:
Onion pubkey for abc.onion Signature of "d/debian", signed by the onion pubkey for abc.onion
onion/xyz/nonce2 works similarly, just with the onion pubkey for xyz.onion.
This has a few properties that I think are useful:
1. The human-readable name signs each .onion address. 2. Each .onion address signs the human-readable name. 3. Given the human-readable name, all of the .onion addresses can be easily found. 4. Given an .onion address, a prefix-based lookup (i.e. not specifying the nonce) will yield the human-readable name. (So if a user visits a .onion site, hypothetically Tor Browser could detect before you connect that there's a Namecoin name for that .onion, and either automatically redirect to the Namecoin name or give the user the choice of doing so.) 5. Since a nonce is present for the onion/ names, the worst that squatters can accomplish is increasing the amount of data that needs to be downloaded by the prefix search in order to find the human-readable name. (It would be even nicer if we could make the Onion signature part of blockchain validation rules, but that would violate a Namecoin design goal of being agnostic to the format of the data stored in a name.)
Revocation and/or expiration for the signatures by the .onion pubkey could, in principle, be added to this scheme if needed, it just adds complexity. Expiration and revocation could both be done by making the Onion signature also include a min/max block height and a revocation boolean flag in the signed data. I haven't carefully thought about that topic yet.
The main concerns I have with this approach (that I remember offhand) are:
1. Does signing this data with the Onion keys lead to cross-protocol attacks? Is that avoidable by structuring the signed data in some way? I'm not familiar enough with the Tor protocol to know for sure right now.
2. Does the use of a nonce sufficiently prevent spam attacks?
3. Will the Onion pubkeys and signatures eat up too much space in the Namecoin blockchain? It might not be a problem in practice since the number of onion services is so small, but I admit that I haven't crunched the numbers on that.
4. What's the right method of choosing which onion service to use if multiple ones are listed? Choosing randomly on every request might confuse website infratructure that expects a user session to remain on a single service (my understanding is that non-Tor website infrastructure that has multiple servers usually expects users to remain on a single server for a while, and might mess up session cookies and similar things otherwise). However, remembering which onion service is in use could lead to fingerprinting attacks. Using Tor's stream isolation choice as input to whether it should be remembered might make sense, but it seems tricky to do safely.
5. Is it actually desirable to have failover when one of the onion services is down? In standard DNS (which Namecoin usually tries to emulate unless there's a reason not to), when multiple IP's are listed for a name, and the first one that's tried is down, the connection just fails. Failover in DNS is handled by SRV records instead (SRV records also give much better load balancing than just listing multiple addresses). Namecoin supports SRV records just fine, so ideally we would use that approach. Sadly, Firefox doesn't respect SRV records for HTTP. And since Tor handles DNS in a special way, I'm not actually certain that Tor Browser could look up SRV records even if it wanted to. (I'm not familiar enough with how Tor handles DNS to answer that.)
6. Is it actually useful to have the Onion keys sign the Namecoin name? The most damaging attacks that I can think of where this matters, involve an end user who already knows (or can reliably look up) what onion service is the correct one. For such users, I suspect that they can get better security than either Namecoin or OnioNS can provide by simply dropping the human-readable component of Zooko's Triangle, or perhaps using a bookmark-like UI. I'm sure there are probably theoretical attacks that apply to other user classes... the question is whether those attacks are actually going to happen in the real world. (I think I very briefly discussed this topic with you a couple years ago, but I don't believe we ever discussed a solution... I'm curious what your analysis of this is.)
7. If it is useful to have the Onion keys sign the Namecoin name, is there actually a need to have those sigs in the blockchain? It seems like something that arguably would be better done either as part of the Tor protocol, or as an HTTP server that runs on an unused port of the onion service, or on an unused HTTP path of an existing HTTP server on an onion service. In any of these cases, the Namecoin name could reference the method of getting that info, which is much less data to store in the blockchain, and eliminates the squatter spam nuisance attack. If that data isn't retrievable, then probably that implies that the onion service is down, in which case it's not clear that there's any benefit to the user in being able to retrieve that data from the blockchain.
It's definitely good that we're having this discussion -- bouncing ideas off people is a great way to flesh things out and make better systems.
Cheers, -Jeremy