nginx & Tor

What follows is a blow-by-blow guide for configuring a UNIX home computer (as a webserver) to host a site on a hidden slice of the internet, frequently referred to as: "the darknet".

  1. Background
  2. nginx
  3. Tor
  4. Custom hostnames

Background

In the headlines (Oct 2013), the owners of the "The Silk Road" (a site which facilitated drug transactions) and "Freedom Hosting" (a webhoster) were arrested and their servers seized. The Feds boast to have knocked 1/2 of all darknet sites out of commission by taking-down "Freedom Hosting".

Tor assigns sites on the darknet the .onion pseudo TLD (Top Level Domain), and they are accessed with the Tor Browser Bundle (or a non-Tor browser configured for a Tor proxy). In a regular browser - when an .onion link is clicked, a "Server not found" error is displayed. Many of these onionland sites remind me of the old (early 1990s) "underground" internet, but some are extremely disturbing: "Buy counterfeit currency", "Hire a hit man", kiddie porn, etc.

Perhaps, this is the time to colonize the darknet for good rather than silly or just plain evil?

Tor was designed to provide anonymity, i.e. to conceal a user's public IP address. Like any technology, a hidden internet can be used for beneficial or destructive ends. Dissidents from China and Iran employ it to evade censorship - or jail. Now, a number of US journalists avail themselves of it to avoid being surveilled or slapped with FISA warrants by Uncle Sam. On my onion site, I host a political blog, computer writings and onion links to freedom of (political) speech sites. Arguably - with nginx (pronounced Engine X) and Tor around, no one with a fat, broadband pipe to the internet (and a modicum of patience) needs to shell-out cash for an account at a webhosting service.

One question frequently asked is: "If IPs, assigned by a user's ISP, regularly change, how can an onion domain, hosted on the computer, continue to resolve to THAT computer?". For access to the darknet, clients and servers enter the Tor proxy, and the IP of 127.0.0.1 is attached to both devices. Tor performs addressing for onion domains, based on the exchange of public keys - not public nameservers. Unlike DNS, an IP and a hostname are not bound-together. A server, assigned an onion domain by Tor, remains permanently associated with it, provided that the same secret key is present. Onion domains resolve to the computers hosting them for clients on the Tor network - but only after a series of complicated, network negotiations is performed.

nginx

Find the sources for nginx. The latest stable release is recommended: http://nginx.org/download. Download the sources with wget (or use a browser), then extract them.

$ cd ~/

$ wget http://nginx.org/download/nginx-1.X.X.tar.gz

$ tar xzvf nginx-1.X.X.tar.gz

Move to the nginx source directory.

$ cd ~/nginx-1.X.X

Create a minimal "config.sh" script. The use of this script will facilitate upgrades (and/or the addition of compile options) at a later date. In a text editor, add the following:

./configure \
"--prefix=$HOME/nginx" \
"--user=$USER" \
"--without-http_rewrite_module"

note
The "--prefix=$HOME/nginx" option installs nginx under your UNIX account - rather than system-wide. "--without-http_rewrite_module" prevents the rewrite engine from being built. To build a functional rewrite, install libpcre from the package manager (or the ports collection) of your operating system and remove "--without-http_rewrite_module" from the config.sh.

Run the config script.

$ sh ./config.sh

Build and install nginx.

$ make

$ make install

note
To accelerate building nginx - on a machine with multiple processors or cores, "make -j9" will compile 9 threads simultaneously.


Configure nginx for run-time

In a text-editor, open up ~/nginx/conf/nginx.conf. To execute nginx - as a non-root user, the webserver should run on 127.0.0.1 (localhost), bound to the http-alt port - 8080. Search for and edit the "listen" entry.

worker_processes 1;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
charset utf-8;
index index.html;

log_format main '$remote_addr $host $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log logs/access.log main;
error_log logs/error.log;
error_page 500 502 503 504;
sendfile on;
keepalive_timeout 60s;
server_tokens off;
etag off;

server {
listen 127.0.0.1:8080;
server_name localhost;
root html/;
}
}


Execute nginx

$ ~/nginx/sbin/nginx

To pull-up the verification message: "Welcome to nginx!", click http://127.0.0.1:8080. Place the webcontent (html, images, audio and video files, etc.) that you wish to serve into ~/nginx/html.

Tor

Since onion domains are not resolvable by internet nameservers, installing Tor is required to generate a secret and public key, write an onion hostname to a file and help kick-off the process of Tor (client/server) network negotiations.

Grab and unpack the sources for the standalone version of Tor. The latest stable release is advised. https://www.torproject.org/download/download.html

$ wget https://www.torproject.org/dist/tor-0.2.X.X-rc.tar.gz

$ tar xzvf tor-0.2.X.X-rc.tar.gz

$ cd tor-0.2.X.X


Configure, compile and install Tor

note
Verify that $HOME/bin exists and that it's in your $PATH statement.

$ ./configure --prefix="$HOME/tor" --exec-prefix="$HOME"

$ make

$ make install

note
To build Tor without the man pages, add "--disable-asciidoc" to the configure options above.

Create a directory to hold the new, onion hostname and keys, and copy the torrc.sample to ~/.torrc.

$ mkdir -p ~/tor/var/lib/tor/host

$ cp ~/tor/etc/tor/torrc.sample ~/.torrc

Open up ~/.torrc in a text editor and copy the following to it, but substitute your own UNIX username for "username", below.

HiddenServiceDir /home/username/tor/var/lib/tor/host
HiddenServicePort 80 127.0.0.1:8080


Execute tor

$ ~/bin/tor

The new onion directory is located in ~/tor/var/lib/tor/ as "host" - with a public and a secret key. Open the file named "hostname":

$ cat ~/tor/var/lib/tor/host/hostname

To bring-up the new site, copy and paste the onion hostname into the address bar of the Tor browser. The site is now available to clients of the Tor network. It would be best to backup the keys and store them elsewhere. In case of a disk crash - without any backup, a new key will be generated when Tor is re-started and a different hostname assigned.

notes
Copy and paste the new, onion hostname as the value of the "server_name" entry into ~/nginx/conf/nginx.conf. Replace "localhost" with the new, onion hostname. To initialize both nginx and Tor at boot, add the following cronjob with "crontab -e".

@reboot $HOME/nginx/sbin/nginx
@reboot $HOME/bin/tor

Finally - a strong piece of advice: A computer that remains connected to the internet 24/7 is encouraged. Should the computer hosting the onion domain go offline for an extended period of time - list sites and search engines will remove their links to it, and the site will receive few hits.

Custom hostnames

The onion hostnames, generated by Tor, are a random-slaw of letters and numbers. However - with mkp224o, it's simple to create a semi-customized hostname, but only a part of the address (the first part) is practical to customize.

Below, clone the repo with git, compile mkp224o then run it to create hostnames with "kheper" - as the first part. (If necessary, install these dependencies: gcc, libc6-dev, libsodium-dev, make and autoconf.)

$ git clone https://github.com/cathugger/mkp224o

$ cd mkp224o

$ ./autogen.sh

$ ./configure

$ make

$ ./mkp224o -d onions kheper

When a number of new hostnames has been created, stop mkp224o with Ctrl-c. Look into the ./onions directory for the newly created hostnames. Copy any one of the directories to $HOME/tor/var/lib/tor/host and restart tor. Copy and paste the new hostname as the value of the "server_name" entry into ~/nginx/conf/nginx.conf.