Configure an onion service with eotk

This guide will help you set up an onion service for an already public website. Please take a look at this and this before continuing. Please correct or suggest improvements this post at jseckler at riseup.net. Send me a commentary and I will publish it here.

Two things motivate this particular guide: (i) the fact that using v3 onion addresses is not well covered by eotk documentation and (ii) that it seem not to be so easy to have all clearnet redirected to https and all onion tor traffic redirected to http. Why would we want (ii)?


Clearnet over https, tor over http

It should be clear that we want all regular traffic redirected to https. Connecting to a onion service, however, by itself implies end to end encryption. Of course, one extra layer of cryptography wouldn’t hurt. But letsencrypt doesn’t emit certificates for onion addresses. Having a proper ssl certificate would mean spending a few hundred dolars buying a certificate from some authority, which is something most of us (not facebook) aren’t willing to do. The other option, self-signing a certificate (which eotk does by default) is OK but user-unfriendly, since all browsers will show warnings saying your website is insecure, which is not something we want. Besides suggesting the misleading idea, it shows an ugly image and requires two more clicks.


Setup eotk

Follow the instructions of the section "Per platform installation" on the instalation guide . It is normal to get errors with the install-everything-on* scripts, but they do not handle them very well. Thus make sure all the commands in there get executed. I did this by running the script, commenting the lines that caused errors, and running it again. Before continuing to the "Using eotk" section, take a look below.


v3 onion address

We will need a pair of keys to serve our onion. If we follow eotk’s documentation, we will get a v2 onion address, but that has some disadvantages . If you know how to create v3 addresses with eotk, please tell me. Anyway, I would suggest using mkp224o , a tool to bruteforce the generation of addresses and find one that fits you reasonably well. The output of mkp224o is a folder named xxxxxxxxxxxxxxxxxxxxxxxxxx.onion containing three files:

  1. hs_ed25519_public_key
  2. hs_ed25519_secret_key
  3. hostname

Now we should be able to write the config file pname.conf looking like this:

set project pname
hardmap secrets.d/xxxxxxxxxxxxxxxxxxxxxxxxxx domainname.com

set force_https 0

Running ./eotk config pname.conf and ./eotk start pname should throw your onion service up and running!


Redirect tor traffic to http

This section is only valid if the website you are referring to redirects automatically to https and refers to itself as https.

The eotk does not much more than raising a reverse proxy that sits between the client and the server. It does so via nginx. The first thing we need to do is tell our server that requests from this proxy must not be redirected to https. This can be done rather simply because eotk by default adds X-From-Onion to the header of the request to the server (via the command proxy_set_header X-From-Onion). The next section goes through one way to do that in an Apache server with mod_rewrite (if you know how to do that in other setups, please email me).

But that is not enough. Our website most likely has references to itself as https. We need our proxy to convert all https links to our page to http. Well, but it is already converting all our domainname.com links into xxxxxxxxxxxxxxxxxxxxxxxx.onion already, so it shouldn’t be so hard! In fact, the eotk/projects.d/pname/nginx.conf file includes the following lines, more or less like this:

  # map: domainname.com -> xxxxxxxxxxxxxxxxxxxxxxxxxx.onion
  subs_filter
  "(\\b)domainname.com\\.net\\b"
  "$1xxxxxxxxxxxxxxxxxxxxxxxxxx.onion"
  gir
  ;

  # map: domainname\.com -> xxxxxxxxxxxxxxxxxxxxxxxxxx\.onion
  subs_filter
  "(\\b)feverstruggle\\\\.net\\b"
  "$1xxxxxxxxxxxxxxxxxxxxxxxxxx\\.onion"
  gir
  ;

which substitute the original domain name for the onion address. We can simply go to that file and change those lines to

  # map: domainname.com -> xxxxxxxxxxxxxxxxxxxxxxxxxx.onion
  subs_filter
  "https://domainname.com\\.net\\b"
  "http://xxxxxxxxxxxxxxxxxxxxxxxxxx.onion"
  gir
  ;

  # map: domainname\.com -> xxxxxxxxxxxxxxxxxxxxxxxxxx\.onion
  subs_filter
  "https://feverstruggle\\\\.net\\b"
  "http://xxxxxxxxxxxxxxxxxxxxxxxxxx\\.onion"
  gir
  ;

and everything should be OK. Actually, it might be better to add these new lines before the ones that were already there, to ensure no edge case is untreated.

But doing this has a problem. Every time we reconfigure this project, we would need to manually make this change again. The solution for this is to use a custom template. When creating the project, eotk uses the template templates.d/nginx.conf.txt to generate the nginx.conf file we were messing with. We can copy this file and edit the copy

$ cp templates.d/nginx.conf.txt ./force-http-nginx.conf.txt
$ vim force-http-nginx.conf.txt

and precede the following lines

  %%BEGIN
  # map: %DNS_DOMAIN% -> %ONION_ADDRESS%
  subs_filter
  "(%LEFT_TLD_RE%)%DNS_DOMAIN_RE2%\\b"
  "$1%ONION_ADDRESS%"
  gir
  ;
  # map: %DNS_DOMAIN_RE% -> %ONION_ADDRESS_RE%
  subs_filter
  "(%LEFT_TLD_RE%)%DNS_DOMAIN_RE4%\\b"
  "$1%ONION_ADDRESS_RE2%"
  gir
  ;

with these

  %%BEGIN
  # map: %DNS_DOMAIN% -> %ONION_ADDRESS%
  subs_filter
  "https://%DNS_DOMAIN_RE2%\\b"
  "http://%ONION_ADDRESS%"
  gir
  ;
  # map: %DNS_DOMAIN_RE% -> %ONION_ADDRESS_RE%
  subs_filter
  "https://%DNS_DOMAIN_RE4%\\b"
  "http://%ONION_ADDRESS_RE2%"
  gir
  ;

At last, we need to tell our project to use this template file. We do that in it’s config file, pname.conf:

set project pname
hardmap secrets.d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx domainname.com

set force_https 0
set nginx_template force-http-nginx.conf.txt

With $ ./eotk stop pname && ./eotk config pname.conf && ./eotk start pname, your onion service should be running fine! Remember to update this custom template when you update eotk (not all problems are solved...)


Don’t redirect tor traffic to https with Apache2 and mod_rewrite

This solution works for systems running the mod_rewrite module. If you don' know if you are runing this module, you probably are, specially if you used certbot. You should already have something like this in /etc/apache2/sites-enabled/domainname.com.conf, or some equivalent file:

RewriteEngine on
RewriteCond %{SERVER_NAME} =domainname.com [OR]
RewriteCond %{SERVER_NAME} =www.domainname.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

It is enough to add one condition: redirect to https only if the header X-From-Onion is set.

RewriteEngine on
RewriteCond %{HTTP:X-From-Onion} ^$
RewriteCond %{SERVER_NAME} =feverstruggle.net [OR]
RewriteCond %{SERVER_NAME} =www.feverstruggle.net
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

Housekeeping

Don't forget to create the maintenance scripts provided by eotk (with $ ./eotk make-scripts). They will automate start up and housekeeping for you. After generating the scripts, you need to put one of them under init.d and tell some scheduling software (cron, probably) to execute the other. Documentation in the scripts themselves tell you how to do that.

If you, like me, forgot to do that and the server crashed, maybe you will need to erase the files project.d/pname/{xxxxxxxx-v3.d/port-*,nginx.pid}.

Ufa!