I've read the "Tor Rendezvous Specification - Version 3" and I can't find out how the client knows the "HSDir" nodes that store the onion service descriptor that indicates the introduction points necessary for the connection. Can anyone guide me on the matter?
Client knows the hidden service address which contains a public key. Using the public key and a constant for a time period, it derives the record which is saved in DHT,
Func(hiddenServicePublicKey, timePeriodConstant) -> record saved in DHT.
The same is done by hidden service operator and is uploaded to DHT with introduction points. Client downloads the info, verifies the signature of the record using the public key and uses the introduction points. The timeperiodConstant varies every 24 hours(I think), so new info is uploaded by the hidden service operator
I am not sure if the record is encrypted or hsdir nodes can see the introduction points. However they cannot map the hidden service address to the record (unless they brute force or guess).
The spec for the v3 onion services, starting with section 2.2, explains it rather well:
2.2. Locating, uploading, and downloading hidden service descriptors [HASHRING]
To avoid attacks where a hidden service's descriptor is easily
targeted for censorship, we store them at different directories over
time, and use shared random values to prevent those directories from
being predictable far in advance.
Which Tor servers hosts a hidden service depends on:
- the current time period,
- the daily subcredential,
- the hidden service directories' public keys,
- a shared random value that changes in each time period,
- a set of network-wide networkstatus consensus parameters. (Consensus parameters are integer values voted on by authorities and published in the consensus documents, described in dir-spec.txt, section 3.3.)
Section 2.2.3 has the technical details.
Explaining this in a non-technical manner is a bit harder. I guess you could think for Tor sorting all HSDirs in a particular order (based on their identity, and a public shared random value, …). Then Tor picks 4 HSDirs in that list where the position within that list is determined by the onion address (=public key) and some other factors. Finally, clients just do the same to find to find out which HSDirs have a descriptor. Client and service will agree on which HSDirs to use because all information needed to make that determination is known by both.
The deprecated and soon unsupported v2 onion services used a time-based approach rather than a shared random value.
The Tor Shared Random Subsystem Specification may be of interest as well.