sandstorm-io / sandstorm

Sandstorm is a self-hostable web productivity suite. It's implemented as a security-hardened web app package manager.
https://sandstorm.io
Other
6.74k stars 707 forks source link

Sandstorm tries to resolve DNS for Tor .onion domains #434

Open isislovecruft opened 9 years ago

isislovecruft commented 9 years ago

If I configure Tor to run a Hidden Service like so:

In /etc/tor/torrc:

HiddenServiceDir /var/lib/tor/hidden_service_sandstorm
HiddenServicePort 80 127.0.0.1:6080

where 6080 is the configured port in /opt/sandstorm/sandstorm.conf, and then I navigate a Tor Browser to the .onion hostname for the configured Tor Hidden Service above, I get the following error page from Sandstorm:

ticket-sandstorm-hs The immediate issues with this behaviour are:

  1. Sandstorm is attempting to resolve .onion domains, which means that it is leaking (to several layers of DNS servers, as well as anyone eavesdropping in between any of them) that this server is running a Tor Hidden Service.
  2. Sandstorm is revealing the public-internet location of the server (including the port number!) to any clients who attempt to reach the Hidden Service.

These two problems combined mean that it is trivial (given the public, non-Tor location of the server, either by IP address or public domain name) to know that this server is running a Tor Hidden Service, and it is beyond trivial (given the server's .onion address) to find the actual server on the public internet.

My suggestions for better behaviour would be to instead:

  1. Never attempt to resolve DNS for something which ends in .onion — nor .i2p, nor .gnu .

    If you're absolutely certain that the resolution request will properly go to the server's listening Tor/I2P/GNUnet instance to be dealt with there, you could forward the resolution request to Tor/I2P/GNUnet (you probably don't want to do this, as I'm not sure what purpose it would serve, and it definitely would make Sandstorm configuration more difficult because there'd probably be the need to specify Tor/I2P/GNUnet's listening port in the sandstorm.conf file).

  2. If a Sandstorm instance is contacted by a client via some domain name which the Sandstorm instance does not recognise, Sandstorm should probably allow access to the normal Sandstorm user interface.

    I assume this behaviour was originally implemented to redirect users who attempt to go to the IP address of the Sandstorm server to the public interface… Was this design chosen in order to seem friendlier? Are there any other problems/concerns with allowing access to the normal Sandstorm user interface via an unrecognised domain name?

kentonv commented 9 years ago

Hi Isis,

Sorry, there are a few things going wrong at once here.

First, if you want to expose the Sandstorm main interface at a .onion address, you will need to modify BASE_URL and WILDCARD_HOST in /opt/sandstorm/sandstorm.conf to specify that address. This will also then be the address that the error page shows. Unfortunately my understanding is that Tor does not support wildcard subdomains, which means you won't be able to use Sandstorm as a Tor hidden service for now, since our security model needs a wildcard.

Now, when the user comes in on a host that doesn't match BASE_URL, Sandstorm assumes that it is receiving a request for a web site hosted by one of the running apps, per the web publishing feature. Currently, such sites are expected to add a TXT record to their DNS entries to indicate which Sandstorm grain (app instance) hosts the site. This is essentially our hacky way of making sure that only the real owner of the domain is allowed to specify which grain to use (especially if the Sandstorm server is multi-user). Eventually we hope to replace this approach with something more rigorous in which the user proves to Sandstorm that they own the domain and then can map it to things through a UI in Sandstorm.

I'm happy to accept a patch that skips the TXT lookup for pseudo-TLDs, but I suspect you'll find several other problems along these lines. We like Tor but we just haven't been designing for this use case so far. I think the safe thing to do here is run Sandstorm in a container where its network access is tunneled through Tor, so that it actually can't accidentally reveal itself.

Someday we'd like to support having individual apps on Sandstorm host hidden services through a Tor "driver" -- perhaps as an alternative to the usual web hosting "driver". Our plans for drivers are still a ways away, though.

isislovecruft commented 9 years ago

Hey Kenton,

Tor onion services do support wildcard DNS, so that problem's out of the way at least.

And I'm sorry! I think I didn't do such a good job explaining why I expected different behaviour from Sandstorm. I knew, before trying to use two "domain" names simultaneously, from reading your code, that Sandstorm would only allow me to run its instance under one BASE_URL name at a time (side note that someday you might want to document the various options somewhere that doesn't require reading C++ :) ). However, I was curious how many things might break if a new user were to think "Wow, this Sandstorm thing is awesome, I'm going to add a Tor Hidden Service for it too!" so that I'd better know what I'd need to fix (that is, if allowing more than one BASE_URL simultaneously is something you might be willing to support).

This behaviour of displaying the friendlier error page pointing users back to the main Sandstorm interface makes considerably more sense now that you mention the web publishing features. But still I see no real technical limitations, nor constraints within Sandstorm's security model — unless I've missed something again, sorry! — which should disallow Sandstorm from offering its services via more than one BASE_URL name simultaneously; e.g. given a sandstorm.conf like so:

BASE_URL=https://stormzrp2ttca5th.onion/
WILDCARD_HOST=*stormzrp2ttca5th.onion
BASE_URL=https://para.noid.cat/
WILDCARD_HOST=*.para.noid.cat

I don't see why Sandstorm shouldn't be able to handle a user using either one at any given time — other than the (slightly) annoying overhead of needing to pass around a pointer to whichever name is in use by a grain at a given time, and some additional complication in config parsing. Would there be any other possible issues with this? Is it something you might consider supporting (or taking patches for)?

isislovecruft commented 9 years ago

@kentonv said:

Someday we'd like to support having individual apps on Sandstorm host hidden services through a Tor "driver" -- perhaps as an alternative to the usual web hosting "driver". Our plans for drivers are still a ways away, though.

This would be neat… you'd be adding support for creating free, easy-to-use, anonymous blogging platforms. This could be really, really neat combined with something like a P2P chat application. Depending on how/where support for using "driver"s was implemented, something like @meejah's txtorcon might be useful. I'd be willing to help hack on that, if/when you get around to it!

isislovecruft commented 9 years ago

@kentonv said:

I'm happy to accept a patch that skips the TXT lookup for pseudo-TLDs, but I suspect you'll find several other problems along these lines.

PR #447 contains a patch for avoiding the DNS TXT lookup. Though, yes, you're correct that there are still likely other issues with leaking information.

We like Tor but we just haven't been designing for this use case so far. I think the safe thing to do here is run Sandstorm in a container where its network access is tunneled through Tor, so that it actually can't accidentally reveal itself.

Yes, that's definitely the safest thing to do, currently. (I still want support for using both my cute hostnames simultaneously, though. :D )

kentonv commented 9 years ago

Hey, sorry for the delayed response, this slipped through my email filters.

Glad to hear Tor supports wildcards! Not sure why I thought it didn't.

I think the main challenge in supporting multiple BASE_URLs is making sure the login providers work correctly. Configuring OAuth login providers is kind of a huge pain in that, ironically, none of them allow the configuration to be automated, so we have to give the user step-by-step instructions on how to use the provider's UI. It's important that the provider be configured to recognize all BASE_URLs. Annoyingly, if the user adds a new BASE_URL, we need to direct them through the process of updating their OAuth config.

(Of course, I imagine Tor users probably aren't going to use OAuth login, but I think supporting multiple BASE_URLs would be a nice thing to have in general...)

We'll also need to review what other things Meteor might be triggering off BASE_URL. Most of the time it doesn't care about this setting but there are random usages here and there...