This post goes into what tor’s onion service authentication features do, how they work, and when they should be used based on your threat model because I couldn’t find any other documentation about it besides reading the spec. “Stealth” only provides “stealthy” properties against malicious HSDirs and basic has some additional obfuscation measures that might make your service better protected.
An onion/hidden service supports two types of built in authentication:
There are a variety of posts from people writing about these functions but I didn’t find much detail about how they work and how they should be used.
A quick summary of how the hidden services protocol works:
There are two types of attacks that default onion services are susceptible to in the case of malicious HSDIRs:
As shown in the past, if someone is able to read the service descriptors (ie running a lot of HSDir hosts), they can find your onion addresses and connect to the servers. This is useful for attackers that want to profile how many people are visiting a service and to uncover services that incorrectly rely on the obscurity of the onion address for security.
So if you are concerned about other services finding and accessing your onion service or about someone monitoring when and how often your service is used, you can setup either Basic or Stealth authentication controls.
In “basic” mode, you’re doing one thing differently from the standard onion service flow: Symmetrically encrypting the Introduction Points published in the service descriptor.
This defends against the service descriptor being intercepted and granting access to your onion service.
Even in the case of a malicious HSDir, where the service descriptor is intercepted the adversary will only be able to see the onion address but won’t be able to establish a connection to it because they won’t have the IPs.
This mode is ideal if your service has no built-in authentication and you are concerned about someone else discovering your service. The use case for this would be a service you want to share with a group of people and you’re not concerned about those people sharing the key.
The poorly named “stealth” authentication mode, operates similarly to above where a key is generated and IPs are encrypted but instead of having a single onion address that can be visited by anyone with the key, it is creating separate keys and addresses for each individual visiting the service. This means that for each client you create, you’re functionally running a dedicated onion service for them.
The differences are:
The benefit is “stealth” mode authentication is service operators can revoke access to clients instead of having to shutdown entire services. So in the case of a compromise, you remove that client, and continue with the service.
You might say to yourself, “OOh Stealth, that sounds more private, I should use that” but let me point something out: When you run separate onion Services dedicated to each individual, the service operator will be able to know exactly which client is connecting and when. If you’re setting up an SSH service that only you plan on connecting to, maybe that’s not a big deal. If you’re setting up an anonymous drop and you want some plausible deniability between you and your 16 friends, then this isn’t ideal.
This mode is ideal for small services with a limited amount of users. In fact, the spec only allows for 16 clients max. If you think of stealth authentication like running multiple instances of basic authentication, you can also imagine giving groups of people access to your service so that in the case of a compromise, you can revoke access to one portion of the server without disrupting others.
If you’re into the nitty gritty details, from what I understand reading the spec the symmetric keys are using 128 bit AES-CTR and one interesting feature of basic mode is that when a service descriptor is uploaded, it is padded with a bunch of fake descriptors. I’m not sure if this is trying to increase the amount of effort to brute force the key or to minimize the risk of an attacker passively discovering a valid authenticated service.
I also didn’t trace down exactly how
descriptor cookies are generated. We know
that symmetric 128bit AES will depend on the key size but AFAIK, these cookies
are just random.
To configure a server to require authentication, add lines like this to your TORRC:
## Stealth HiddenServiceDir /var/lib/tor/stealth_service/ HiddenServicePort 22 127.0.0.1:22 HiddenServiceAuthorizeClient stealth alice,bob,charlie ## Basic: HiddenServiceDir /var/lib/tor/basic_service/ HiddenServicePort 80 127.0.0.1:80 HiddenServiceAuthorizeClient basic mybasicclient
If you take a look those folders you created, you’ll see
For your basic
client_keys, because you don’t need to generate much key
material, it will look like this:
client-name mybasicclient descriptor-cookie /tuvPBTFHoWzwQCSXTgXxg==
And for stealth
client_keys it’ll look like this:
client-name alice descriptor-cookie h2JCZAzzEBxobjPLOOFTkg== client-key -----BEGIN RSA PRIVATE KEY----- xxx -----END RSA PRIVATE KEY----- client-name bob descriptor-cookie LPTX88EEGDvpcedXiYEmqw== client-key -----BEGIN RSA PRIVATE KEY----- xxx -----END RSA PRIVATE KEY-----
To configure your TORRC to connect to your services:
HidServAuth lxqluyty24ijfg4p.onion rJcrR/ZbCMDdJqTImOBvxB stealth1 HidServAuth tkwk5o5n4eud3vwd.onion /tuvPBTFHoWzwQCSXTgXxg basic1
There’s one line that bugged me in the documentation. When talking about how to revoke someone’s access to a stealth auth protected service:
As long as a removed client cannot link descriptors issued for other clients to the service, it cannot derive service activity any more (spec)
It’s saying that in basic mode, there is no defense from someone monitoring your onion address and watching its activity. While in stealth, there is. This is phrased very odd but the point is that because stealth mode will generate separate service descriptors, there’s no way that a malicious HSDir could watch the traffic related to your service, because they won’t know the other clients' dedicated onion address.
Why not replace stealth authentication by running multiple instances of your own onion address with basic authentication? The answer is that there’s a lot more overhead to do this and that’s the point of this service. I don’t know how much this improves performance but that’s one of the purposes of stealth mode so I can only assume it’s substantial enough to warrant it.
Why don’t you just have your service provide authentication? This is a valid response but with all of the discussion about putting your IoT on the Tor Network, maybe you want an extra layer of defense especially if you’re going to be the only one that uses them. This is protocol agnostic so even if your IoT crapware has an unauthenticated exploit, this would seemingly protect you.