Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example code for running a (HTTP/HTTPS) Tor hidden service supporting subdomains.

The following files show an example of how to create subdomains for onion site hidden services. (This hasn't been tested for hidden services for anything other than HTTP/HTTPS.)

(You might also want to read our blog post about ProPublica’s Tor hidden service, including a tutorial and notes on running a hidden service: https://www.propublica.org/nerds/item/a-more-secure-and-anonymous-propublica-using-tor-hidden-services )

In general, this works (maybe just in recent Tor clients) because Tor will handle the connection to www.xxxxxxxxxxxxxxxx.onion as a connection to xxxxxxxxxxxxxxxx.onion. The encapsulated HTTP/HTTPS connection contains the subdomain in the Host: header (and in the case of HTTPS, the SNI part of the TLS handshake), so the underlying web server knows what domain the client actually wants.

Be aware that there might be some issues with older tor clients and tools (possibly things like torsocks) that have issues addressing subdomains like this (since they don't resolve the subdomain as a connection to the root onion domain).

# /etc/tor/torrc
# This file isn't exactly important, it just sets up the basic hidden service.
# ... maybe other config lines ...
HiddenServiceDir /var/run/tor/my-onionsite-with-subdomains
HiddenServicePort 80 127.0.0.1:44480
# /etc/nginx/sites-enabled/onionsite.conf
# Given a hidden service running at xxxxxxxxxxxxxxxx.onion,
# configured to connect to 127.0.0.1:44480 (i.e. above),
# an nginx site config for subdomains might look like the below.
# A nice side effect is that any subdomain changes (new subdomains,
# removing old ones) doesn't require you to edit your torrc at all.
#
# This example listens for the bare xxxxxxxxxxxxxxxx.onion domain,
# and www- and projects- subdomains.
#
# bare domain: redirect to www
server {
listen 127.0.0.1:44480;
server_name xxxxxxxxxxxxxxxx.onion;
allow 127.0.0.1;
deny all;
server_tokens off;
rewrite ^/(.*) http://www.xxxxxxxxxxxxxxxx.onion/$1 permanent;
}
# www.xxxxxxxxxxxxxxxx.onion
server {
listen 127.0.0.1:44480;
server_name www.xxxxxxxxxxxxxxxx.onion;
allow 127.0.0.1;
deny all;
server_tokens off;
location / {
...
}
...
}
# projects.xxxxxxxxxxxxxxxx.onion
server {
listen 127.0.0.1:44480;
server_name projects.xxxxxxxxxxxxxxxx.onion;
allow 127.0.0.1;
deny all;
server_tokens off;
location / {
...
}
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment