Generate A Vanity .onion Address For Your Tor Hidden Service Using Scallion

Ever wonder how Tor sites get those custom vanity .onion addresses such as silkroada7bc3kld.onion? These addresses can be generated by hidden service operators for production use, and are just as secure as the automatically generated (and often more cryptic) addresses.

Hidden service .onion addresses are really just the public part of a key pair. Utilizing asymmetric encryption, a hidden service uses the public key (a 16 character string that functions as the actual address prefix) and a private key (a much longer string that is known only to the hidden service) to verify the identity of the service. Anyone connecting to the public key can only do so if the hidden service has access to the private key. Under normal circumstances, only the service operator has access to that private key, so you could trust that the address has not been hijacked.

Keep in mind, while it takes a long time, it is possible for someone to generate the same keypair as another hidden service. While computationally expensive, entities able to throw enough resources at generating an identical address would be able to do so much more quickly than someone acting alone on a sole machine.

 

Generation with Scallion

Scallion is one tool that can be used for generation. Unlike previous tools for generation addresses, Scallion focuses on GPUs, meaning it works much faster than CPU-targeting utilities in most cases. In my experience, Scallion does not work on ARM devices (Use Shallot or Eschalot instead), but if you have an x86_64 processor and some sort of video graphics (integrated or otherwise), you should be good to go.

Let’s get started generating custom .onion addresses. I will assume that you have access to a Linux machine and are familiar with the terminal. I will be using Debian, but this guide should be easy to modify for most distributions.

First, install some dependencies and then clone Scallion onto your machine:

$ sudo apt install clinfo mono-complete mono-devel nvidia-opencl-common nvidia-opencl-dev nvidia-opencl-icd libssl1.0-dev beignet beignet-dev ocl-icd-opencl-dev ocl-icd-libopencl1
$ git clone https://github.com/lachesis/scallion.git

Now, we will move to the scallion directory, and build the scallion executable:

$ cd scallion
$ xbuild scallion.sln /p:TargetFrameworkVersion="v4.5"

Next, we will get a list of all of the devices that can be used for generating addresses:

$ mono scallion/bin/Debug/scallion.exe -l
Id:0 Name:Intel(R) HD Graphics Skylake Desktop GT2
    PreferredGroupSizeMultiple:16 ComputeUnits:24 ClockFrequency:1000
    MaxConstantBufferSize:134217728 MaxConstantArgs:8 MaxMemAllocSize:3221225472

We can see I have one device with an identifier 0 that I can target. You may have more than one device.

Now we can use Scallion to find an address that starts with a word or phrase of our choice. Let’s start Scallion with 8 threads, and have it use device 0. We will look for addresses that start with “apple”. After a little waiting, you should get some similar output with the .onion address (public key) and the private key:

$ mono scallion/bin/Debug/scallion.exe -t8 -d 0 apple
Cooking up some delicious scallions...
Using kernel optimized from file kernel.cl (Optimized4)
Using work group size 16
Compiling kernel... done.
Testing SHA1 hash...
CPU SHA-1: d3486ae9136e7856bc42212385ea797094475802
GPU SHA-1: d3486ae9136e7856bc42212385ea797094475802
Looks good!
LoopIteration:1  HashCount:16.78MH  Speed:98.7MH/s  Runtime:00:00:00  Predicted:00:00:00  Found new key! Found 1 unique keys.

  2018-01-03T00:24:24.645322Z
  applencoaipu4tqj.onion
  -----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCcDTg3+pON2oUclpStVlFVhtcpleNwtmdO3ZVuN2cPe9tyATjH
fye++edUSTwVm6EZZABrK3iSBdGAITXxRpc5dBM+SHPals6DEECRffa+d2QazJq2
xjhU7sfocXMzly+lALtE3T/I8yhFwcDlv/LGsWn6P9Hh2A2otDz3SCeGCQIEXGYD
DwKBgBkW9kDgDFafPvLhA0YIaDei5tBR5gJXt2vqabJfbi8P7RKF3GJ6vlHXu7xS
XikDmN5lJ+dAeFH5mH4mx0TAyfpjHvwrvCcVFPuXnt8ufDHYnRc5B8hYg/bpe0eS
9iZpSFKvq1Io49Wlt04KKAW86Nk0EJRPlkU6ewfOvs5AHI9vAkEAz+N847csHbcx
79RlBhvoT+GUYoSdKvtB+0pyv4mRYEV3SHFATVwXlTksOcPkI1dFVftkoXaEEld2
RTmsVlaLNQJBAMAqnKx+s4LAj2NxzBTpbcpeVY+DauWBoNMUo5Qdqm3SSV4hPsbd
Bf99XvCWS+7tD+jhks4mffOcKQZNK4JHVgUCQQDH6n4Uf2QWhZHvnY0niHE0ydiu
f2KIBc2spzWzcCWiyBqmtAbjhT3/HajJHB3zYdzHPrI0uVFHVqrjBnhRKSVjAkEA
vWUSQ9u4jPBH/z3ahdD6kbvQA90Jxo/JQgrwaHAUrli/SvmOC3xx/kSWLVPSlSk4
p96zeIgMolOS4Tfiff+newJAUaCQumLZori7RCT+2XOXFCoV03TLlujS8L+2sNH1
LPR8Brc3CBv+ZlleYnJCR4J88py8dFGYSYM95qmpCek1SA==
-----END RSA PRIVATE KEY-----

After generating a private key and address, you will want to use them with your Tor hidden service. The private key and address usually sit in files within the /var/lib/tor/hidden_service/ directory and are named hostname and private_key respectively.

 

For a full list of options and flags, we can run the scallion executable with the --help flag:

$ mono scallion/bin/Debug/scallion.exe --help
Usage: scallion [OPTIONS]+ regex [regex]+
Searches for a tor hidden service address that matches one of the provided regexes.

Options:
  -k, --keysize=VALUE        Specifies keysize for the RSA key
  -n, --nonoptimized         Runs non-optimized kernel
  -l, --listdevices          Lists the devices that can be used.
  -h, -?, --help             Displays command line usage help.
      --gpg                  GPG vanitygen mode.
  -d, --device=VALUE         Specifies the opencl device that should be used.
  -g, --groupsize=VALUE      Specifies the number of threads in a workgroup.
  -w, --worksize=VALUE       Specifies the number of hashes preformed at one
                               time.
  -t, --cputhreads=VALUE     Specifies the number of CPU threads to use when
                               creating work. (EXPERIMENTAL - OpenSSL not
                               thread-safe)
  -p, --save-kernel=VALUE    Saves the generated kernel to this path.
  -o, --output=VALUE         Saves the generated key(s) and address(es) to this
                               path.
      --skip-sha-test        Skip the SHA-1 test at startup.
      --quit-after=VALUE     Quit after this many keys have been found.
      --timestamp=VALUE      Use this value as a timestamp for the RSA key.
  -c, --continue             Continue to search for keys rather than exiting
                               when a key is found.
      --command=VALUE        When a match is found specified external program
                               is called with key passed to stdin.
                               Example: "--command 'tee example.txt'" would
                               save the key to example.txt
                               If the command returns with a non-zero exit code,
                                the program will return the same code.
 

Generate A Vanity .onion Address For Your Tor Hidden Service Using Eschalot

Ever wonder how Tor sites get those custom vanity .onion addresses such as silkroada7bc3kld.onion? These addresses can be generated by hidden service operators for production use, and are just as secure as the automatically generated (and often more cryptic) addresses.

Hidden service .onion addresses are really just the public part of a key pair. Utilizing asymmetric encryption, a hidden service uses the public key (a 16 character string that functions as the actual address prefix) and a private key (a much longer string that is known only to the hidden service) to verify the identity of the service. Anyone connecting to the public key can only do so if the hidden service has access to the private key. Under normal circumstances, only the service operator has access to that private key, so you could trust that the address has not been hijacked.

Keep in mind, while it takes a long time, it is possible for someone to generate the same keypair as another hidden service. While computationally expensive, entities able to throw enough resources at generating an identical address would be able to do so much more quickly than someone acting alone on a sole machine.

 

Generation with Eschalot

Eschalot is one tool that can be used for generation. Eschalot is based off of another tool I previously covered called Shallot. While Shallot only allowed for some basic matching with regular expressions, Eschalot gives the user a bit more control and even supports word lists. Eschalot will not be as fast as a tool like Scallion, but it is (in my opinion) more portable as Scallion seems to have issues running on ARM-based SOCs.

Let’s get started generating custom .onion addresses. I will assume that you have access to a Linux machine and are familiar with the terminal. I will be using Debian, but this guide should be easy to modify for most distributions.

First, install OpenSSL if we don’t have it, then clone Eschalot onto your machine:

$ sudo apt-get install openssl
$ git clone https://github.com/ReclaimYourPrivacy/eschalot.git

Now, we will move to the eschalot directory, and build the eschalot executable:

$ cd eschalot
$ make

We can now make sure everything is working using the builtin testing option:

$ make test
./worgen 8-16 top150adjectives.txt 3-16 top400nouns.txt 3-16 top1000.txt 3-16 > wordlist.txt
Will be producing 8-16 character long word combinations.
Reading 3-16 characters words from top150adjectives.txt.
Reading 3-16 characters words from top400nouns.txt.
Reading 3-16 characters words from top1000.txt.
Loading words from top150adjectives.txt.
Loaded 150 words from top150adjectives.txt.
Loading words from top400nouns.txt.
Loaded 400 words from top400nouns.txt.
Loading words from top1000.txt.
Loaded 974 words from top1000.txt.
Working. 100% complete, 31122412 words (approximately 377Mb) produced.
Final count: 31366539 word combinations.
./eschalot -vct4 -f wordlist.txt >> results.txt
Verbose, continuous, no digits, 4 threads, prefixes 8-16 characters long.
Reading words from wordlist.txt, please wait...
Loaded 31366539 words.
Sorting the word hashes and removing duplicates.
Final word count: 31363570.
Thread #1 started.
Thread #2 started.
Thread #3 started.
Thread #4 started.
Running, collecting performance data...
Found a key for kindland (8) - kindlandudsw7nga.onion
Found a key for loudhour (8) - loudhourvype7cyn.onion
Found a key for cutwaxwin (9) - cutwaxwinstsf6mk.onion
Total hashes: 177519717, running time: 10 seconds, hashes per second: 17751971

When done, simply clean up the test results:

$ make cleantest

 

Now is a good time to use Eschalot to find an address that starts with a word or phrase of our choice. Let’s start Eschalot in verbose mode, with 4 threads, and have it continue to look for addresses even after it has found one. We will look for addresses that start with “apple”. After a little waiting, you should get some similar output with the .onion address (public key) and the private key:

$ ./eschalot -t4 -v -c -p apple
Verbose, continuous, no digits, 4 threads, prefixes 5-5 characters long.
Thread #1 started.
Thread #2 started.
Thread #3 started.
Thread #4 started.
Running, collecting performance data...
Found a key for apple (5) - appleiujtls4awea.onion
----------------------------------------------------------------
appleiujtls3awea.onion
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDQo/ArZ/Em1/1wvTlpVSjV5eTnYelelzJ670kBsO8/Yjvq5GGu
M7LdAUVUBdrF9qO2I24eKNul0sam+jmvov8WvFAk2eSk2p5VefVabxvUvSiOVNwA
cw3XmHlbWPpriOmyFiTOQtzYXHqG4YNPna9VQMR5S+86hy4AEiJoJNEdpQIEAT1u
AwKBgF8uYVx00lZPzAUxAFmrw85H78001d767m+7OLWmj5dDSgC0nbNWHbICwP8y
fczIoQ/DLHGOHK1WtPiUXNw7E/EX3f4DQ3E0zssIRZOBhmy6D3umLUHBILI/6n/F
hzD8U/Zy3W6rgZ35Ib34Mv35Kq/d6DFUD7u6qWv8CrD0gt7zAkEA6ASM6cI/EaT+
iTh+OSt+Pdh6N3Kofe2QGbqb8Y99tsX07nHOzl8EH0kkIxO26RDuWdT5J3wRUCkA
UGyqVrefNwJBAOY0y7qkSTtLE1S/TwhMWc8mEWqewj4FVT+H/sY0hlfZ5VW7xMjf
usKD99eTDLgJ0joqpIOlmmUHAFHKCkdHwAMCQQDVBCQWZJ/qzFqmFvs20erbTzrk
4VNgV6QmOJDidMAxqyjyocUnA1/vASHJcJnunEsdXvpADVKsV3hwO4jSIxqPAkAs
yCr9mXF5c+wWErdlNdYmOTthqIeCxZssr0fRYVadbtfQ9rEHV0UFEdUp50JWAX3s
oy7t+b7kPoTpTteKshyTAkAPzLpDXQPEWKIJL5uqTR1G/iR7FlQ/jaFd44OCNtmz
azXGB3asSbLcmc3z9KnOb5xzeApPW7hIPy/yxYCgEdrE
-----END RSA PRIVATE KEY-----

Additionally, you can use the included worgen utility to generate word lists that can be fed into Eschalot. Below is an example series of commands that will generate 10-character strings by mixing nouns that are 3-10 characters long each, and then run the list through Eschalot. Eschalot comes with several different word lists included what can be used by the worgen utility.

$ ./worgen 10-10 nouns.txt 3-10 nouns.txt 3-10 > wordlist.txt
$ ./eschalot -vct4 -l 10-10 -f wordlist.txt > results.txt

After generating a private key and address, you will want to use them with your Tor hidden service. The private key and address usually sit in files within the /var/lib/tor/hidden_service/ directory and are named hostname and private_key respectively.

 

For a full list of options and flags, we can run the eshalot executable with no arguments:

$ ./eschalot
Version: 1.2.0

usage:
eschalot [-c] [-v] [-t count] ([-n] [-l min-max] -f filename) | (-r regex) | (-p prefix)
-v : verbose mode - print extra information to STDERR
-c : continue searching after the hash is found
-t count : number of threads to spawn default is one)
-l min-max : look for prefixes that are from 'min' to 'max' characters long
-n : Allow digits to be part of the prefix (affects wordlist mode only)
-f filename: name of the text file with a list of prefixes
-p prefix : single prefix to look for (1-16 characters long)
-r regex : search for a POSIX-style regular expression

Examples:
eschalot -cvt4 -l8-12 -f wordlist.txt >> results.txt
eschalot -v -r '^test|^exam'
eschalot -ct5 -p test

base32 alphabet allows letters [a-z] and digits [2-7]
Regex pattern examples:
xxx must contain 'xxx'
^foo must begin with 'foo'
bar$ must end with 'bar'
b[aoeiu]r must have a vowel between 'b' and 'r'
'^ab|^cd' must begin with 'ab' or 'cd'
[a-z]{16} must contain letters only, no digits
^dusk.*dawn$ must begin with 'dusk' and end with 'dawn'
[a-z2-7]{16} any name - will succeed after one iteration

You can also run the worgenexecutable with no arguments for a complete list of options:

$ ./worgen
Version: 1.2.0

usage: worgen min-max filename1 min1-max1 [filename2 min2-max2 [filename3 min3-max3]]
  min-max   : length limits for the output strings
  filename1 : name of the first word list file (required)
  min1-max1 : length limits for the words from the first file
  filename2 : name of the second word list file (optional)
  min2-max2 : length limits for the words from the first file
  filename3 : name of the third word list file (optional)
  min3-max3 : length limits for the words from the first file

  Example: worgen 8-12 wordlist1.txt 5-10 wordlist2.txt 3-5 > results.txt

              Generates word combinations from 8 to 12 characters long
              using 5-10 character long words from 'wordlist1.txt'
              followed by 3-5 character long words from 'wordlist2.txt'.
              Saves the results to 'results.txt'.

 

Generate A Vanity .onion Address For Your Tor Hidden Service Using Shallot

Ever wonder how Tor sites get those custom vanity .onion addresses such as silkroada7bc3kld.onion? These addresses can be generated by hidden service operators for production use, and are just as secure as the automatically generated (and often more cryptic) addresses.

Hidden service .onion addresses are really just the public part of a key pair. Utilizing asymmetric encryption, a hidden service uses the public key (a 16 character string that functions as the actual address prefix) and a private key (a much longer string that is known only to the hidden service) to verify the identity of the service. Anyone connecting to the public key can only do so if the hidden service has access to the private key. Under normal circumstances, only the service operator has access to that private key, so you could trust that the address has not been hijacked.

Keep in mind, while it takes a long time, it is possible for someone to generate the same keypair as another hidden service. While computationally expensive, entities able to throw enough resources at generating an identical address would be able to do so much more quickly than someone acting alone on a sole machine.

 

Generation with Shallot

Shallot is one tool that can be used for generation. Under the name onionhash, Shallot was first created and maintained by an anonymous developer named Bebop. After Bebop disappeared, development continued with the help of a programmer named `Orum who renamed it Shallot before disappearing himself. Eventually, katmagic moved the code to github where it lives today, but without active development. Over the years, other developers have made fixes, but none of them have been moved into the master branch of the application. Shallot will not be as fast as a tool like Scallion, but it is (in my opinion) more portable as Scallion seems to have issues running on ARM-based SOCs.

Let’s get started generating custom .onion addresses. I will assume that you have access to a Linux machine and are familiar with the terminal.

First, clone Shallot onto your machine:

$ git clone https://github.com/katmagic/Shallot.git

Now, we will move to the Shallot directory, and download and apply some patches:

$ cd Shallot
$ wget https://patch-diff.githubusercontent.com/raw/katmagic/Shallot/pull/9.patch
$ git apply 9.patch
$ wget https://patch-diff.githubusercontent.com/raw/katmagic/Shallot/pull/16.patch
$ git apply 16.patch
$ wget https://patch-diff.githubusercontent.com/raw/katmagic/Shallot/pull/25.patch
$ git apply 25.patch

Wait, what are these for?

  • Patch #9 fixes an off-by-one error that caused generation of incorrect keys.
  • Patch #16 adds an optimization for computing powers of 2 using a bitshift.
  • Patch #25 adds use of memcmp to speed up regular expression use.

Next, we will configure and make to build the shallot executable:

$ ./configure && make

We can now test it by generating an address that starts with “apple” utilizing regular expressions:

$ ./shallot ^apple

After a little waiting, you should get some similar output with the .onion address (public key) and the private key:

$ ./shallot ^apple
-----------------------------------------------------------------
Found matching domain after 9231616 tries: applelmehzgcx37v.onion
-----------------------------------------------------------------
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC1szzknIej9Cn32XEarL1TFJXGOWpllK8NDSLKsJfwBIW3kyFb
F996LeIX7wKomRuudZ8TfyCQsdL4XT27MvZTX/HTjYc1TErpw6s+0n1WXm/+sbgD
/8X1vpt/m4OLZS+JOgDSFNM9zi1Qy2GOAMGlyBA5nXKxo5h60vOA87RVowIEARq5
/wKBgBGN/v/RFriNmAd572mI8SiMK5NBO6yu33wz1kf15Xqh/K6QE9Tsr/htYNjr
/RBb7JgIDCXFl0Bsjfnqtsp/WPe5eWUJkzePpzrIyrgAgFneHYYPeKbhUuEwB20i
mFBKXgZmX2yK6BtJDMAjorq/E/hoe9ecKzGaTrv04LTquiIvAkEA43+W3lXBgUIE
EO9ckIHrQ94DvhCtwQGg1vQFLovbvgBL1rqDgmmrWrUrqjqAJXZj8Iou+k+Z9xkK
fn6O4WfMsQJBAMx2ymXmNI8mldwGcl18LvnYGeTCEy0pD6j2yM5LsBNj9G0ZKcFV
n9gAkG5VumCW3yNvGVao7s9B0cjw63n5jJMCQF1ETnd7YOZb20e6GPWxJ1jlXAG7
CapYtn42LBPD9JgNNw8RqKz+zOPu61kWFXMOQnlruLh127218FVsfbvilt8CQFi7
dTZ0DwIPQRwB5QaGe2ymXFSj1yMbDMh9Z/7TXcmdSnigfDfGykQN27qYPwB8CcTM
MfZszZukdmgYFYx+H8cCQDrGHNbtSePX53ATAf2nP6Wqzi438d4Aegev5qOaTLk6
ol+H4euHzOO7R/YmWcXRWSZAwFfmboNb5xMfR54SK+k=
-----END RSA PRIVATE KEY-----

The private key and address usually sit in files within the /var/lib/tor/hidden_service/ directory and are named hostname and private_key respectively.

 

For a full list of options and flags, we can run the shallot executable with no arguments:

$ ./shallot
Usage: shallot [-dmopv] [-f ] [-t count] [-x time] [-e limit] pattern
  -d        : Daemonize (requires -f)
  -m        : Monitor mode (incompatible with -f)
  -o        : Optimize RSA key size to improve SHA-1 hashing speed
  -p        : Print 'pattern' help and exit
  -f  : Write output to 
  -t count  : Forces exactly count threads to be spawned
  -x secs   : Sets a limit on the maximum execution time. Has no effect without -m
  -e limit  : Manually define the limit for e

The repository on Github also has a handy chart to estimate how long it will take to generate an address matching a certain number of characters on a 1.5GHz processor:

characters | time to generate (approx.)
-------------------------------------------------------------------    
1          | less than 1 second    
2          | less than 1 second    
3          | less than 1 second   
4          | 2 seconds    
5          | 1 minute    
6          | 30 minutes    
7          | 1 day    
8          | 25 days  
9          | 2.5 years  
10         | 40 years  
11         | 640 years  
12         | 10 millenia  
13         | 160 millenia  
14         | 2.6 million years
 

Configuring a Tor Hidden Service

Tor hidden services allow various types of services (web server, telnet server, chat server, etc) to be operated within the Tor network. This allows both users and service operators to conceal their identities and locations. Just about anything that can be run on the clearnet can be run within the Tor darknet.

Setting up a hidden service on Tor is a simple process and depending on the level of detail, an operator can keep their service completely anonymous. Depending on your use-case, you may or may not choose to anonymize your service at all. For anonymous operation, it is recommended to bind services being offered to localhost and make sure that they do not leak information such as an IP address or hostname in any situation (such as with error messages).

For this guide, we assume a Debian Stretch (or similar) Linux system with a non-root, sudo user. It is also assumed that the target machine has been set up with some standard security practices such as disallowing root logins over SSH, and basic firewall rules. This Tor hidden service will be masked on the darknet, but if the hosting server is deanonymized, a malicious party could uncover the machine’s actual clearnet IP address and attempt to penetrate it or otherwise disrupt service. Depending on the software running the services you are hiding, you may wish to install into a virtual machine to limit damage to the system by code vulnerabilities.

Installing Tor

Before configuring a relay, the Tor package must be set up on the system. While Debian does have a Tor package in the standard repositories, we will want to add the official Tor repositories and install from there to get the latest software and be able to verify its authenticity.

First, we will edit the sources list so that Debian will know about the official Tor repositories.

$ sudo nano /etc/apt/sources.list

At the bottom of the file, paste the following two lines and save/exit.

deb http://deb.torproject.org/torproject.org stretch main
deb-src http://deb.torproject.org/torproject.org stretch main

Now back in the console, we will add the Tor Project’s GPG key used to sign the Tor packages. This will allow verification that the software we are installing has not been tampered with.

$ gpg --keyserver keys.gnupg.net --recv A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89
$ gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -

Lastly, run an update and install Tor from the repositories we just added.

$ apt-get update
$ apt-get install tor deb.torproject.org-keyring

 

Configuring the Hidden Service

We will be editing the torrc file, so let’s bring it up in our text editor:

$ sudo nano /etc/tor/torrc

Going line by line in this file is tedious, so to minimize confusion, we will ultimately rewrite the whole file. We will implement logging into a file located at /var/log/tor/notices.log and assume the local machine has a web server running on port 80. Paste the following over the existing contents in your torrc file:

Log notice file /var/log/tor/notices.log

############### This section is just for location-hidden services ###

## Once you have configured a hidden service, you can look at the
## contents of the file ".../hidden_service/hostname" for the address
## to tell people.
##
## HiddenServicePort x y:z says to redirect requests on port x to the
## address y:z.

HiddenServiceDir /var/lib/tor/hs_name_of_my_service/
HiddenServicePort 80 127.0.0.1:80

#HiddenServiceDir /var/lib/tor/other_hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServicePort 22 127.0.0.1:22

After saving the file, make and permission a log file, then we are ready to restart Tor:

$ sudo touch /var/log/tor/notices.log
$ chown debian-tor:debian-tor /var/log/tor/notices.log
$ sudo service tor restart

If the restart was successful, the Tor hidden service is active. If not, be sure to check the log file for hints as to the failure:

$ sudo nano /var/log/tor/notices.log

Now that the hidden service is working, Tor has created the hidden service directory we defined in the torrc, /var/lib/tor/hs_name_of_my_service/. There are two files of importance within this directory.

There is a hostname file at /var/lib/tor/hs_name_of_my_service/hostname that contains the hidden service’s public key. This public key acts as a .onion address which users on the Tor network can use to access your service. Make a note of this address after reading it from the file with cat:

$ sudo cat /var/lib/tor/hs_name_of_my_service/hostname
nb2tidpl4j4jnoxr.onion

There is also a private_key file that contains the hidden service’s private key. This private key pairs with the service’s public key. It should not be known or read by anyone or anything except Tor, otherwise someone else will be able to impersonate the hidden service. If you need to move your Tor hidden service for any reason, make sure to backup the hostname and private_key files before restoring them on a new machine.

After restarting the hidden service, it may not be available right away. It can take a few minutes before the .onion address resolves on a client machine.

 

Example – Configure A Web Server with Nginx

Let’s use this hidden service to host a website with Nginx.

First, we will install Nginx and create a directory for our HTML files

$ sudo apt-get install nginx
$ sudo mkdir -p /var/www/hidden_service/

Now, we will create an HTML file to serve, so we need to bring one up in our editor:

$ sudo nano /var/www/hidden_service/index.html

Paste the following basic HTML and save it:

<html><head><title>Hidden Service</title></head><body><h1>It works!</h1></body></html>

Next, we will set the owner of the files we created to www-data for the web server and change the permissions on the /var/www directory.

$ sudo chown -R www-data:www-data /var/www/hidden_service/
$ sudo chmod -R 755 /var/www

We want to make some configuration changes for anonymity. First, let’s edit the default server block:

$ sudo nano /etc/nginx/sites-available/default

Find the block that starts with server { and you should see a line below that reads #listen 80;. Replace this line with to explicitly listen on localhost:

listen localhost:80 default_server;

Now find the line in the block for server_name  set the server name explicitly:

server_name _;

Next we need to edit the Nginx configuration file:

$ sudo nano /etc/nginx/nginx.conf

Find the block that starts with http { and set the following options:

server_name_in_redirect off;
server_tokens off;
port_in_redirect off;

The first option will make sure the server name isn’t used in any redirects. The second option removes server information in error pages and headers. The third option will make sure the port number Nginx listens on will not be included when generating a redirect.

Now we need to create a server block so Nginx knows which directory to serve content from when our hidden service is accessed. Using our text editor, we will create a new server block file:

$ sudo nano /etc/nginx/sites-available/hidden_service

In the empty file, paste the following configuration block. Make sure that the server_name field contains your onion address which you read from the hostname file earlier and not my address, nb2ticpl4j4hnoxq.onion.

server {
listen   127.0.0.1:80;
server_name nb2tidpl4j4jnoxr.onion;

error_log   /var/log/nginx/hidden_service.error.log;
access_log  off;

location / {
        root /var/www/hidden_service/;
        index index.html;
    }
}

After saving the file, we need to symlink it to the sites-enabled directory and then restart Nginx:

$ sudo ln -s /etc/nginx/sites-available/hidden_service /etc/nginx/sites-enabled/hidden_service
$ sudo service nginx restart

To test the hidden service, download and install the Tor Browser on any machine and load up your .onion address.

 

Example – Configure A Web Server with Apache

Let’s use this hidden service to host a website with Apache. Note: Many criticize Apache for leaking server information by default. Apache takes more effort to secure.

First, we will install Apache and create a directory for our HTML files

$ sudo apt-get install apache2
$ sudo mkdir -p /var/www/hidden_service/

Now, we will create an HTML file to serve, so we need to bring one up in our editor:

$ sudo nano /var/www/hidden_service/index.html

Paste the following basic HTML and save it:

<html><head><title>Hidden Service</title></head><body><h1>It works!</h1></body></html>

Next, we will set the owner of the files we created to www-data for the web server and change the permissions on the /var/www directory.

$ sudo chown -R www-data:www-data /var/www/hidden_service/
$ sudo chmod -R 755 /var/www

Now, we need to make a few changes to the Apache configuration. Let’s start by setting Apache up to only listen to port 80 on 127.0.1.1:

$ sudo nano /etc/apache2/ports.conf

Change the line Listen 80 to Listen 127.0.0.1:80 and save the file.

Now we will access the security configuration file:

$ sudo nano /etc/apache2/conf-enabled/security.conf

Change the line for ServerSignature to ServerSignature Off and the line for ServerTokens to ServerTokens Prod to restrict information the httpd reports about the server.

Then, we will make an edit to the main Apache configuration file to override the server name Apache uses:

$ sudo nano /etc/apache2/apache2.conf

At the very bottom of the file, paste the following. Make sure that the ServerName field contains your onion address which you read from the hostname file earlier and not my address, nb2tidpl4j4jnoxr.onion.

ServerName nb2tidpl4j4jnoxr.onion

Next, we will disable Apache’s mod_status module to turn off status information:

$ sudo a2dismod status

Now we need to create a virtual host so Nginx knows which directory to serve content from when our hidden service is accessed. Using our text editor, we will create a new server block file:

$ sudo nano /etc/apache2/sites-available/hidden_service

In the empty file, paste the following configuration block. Make sure that the server_name field contains your onion address which you read from the hostname file earlier and not my address, nb2tidpl4j4jnoxr.onion.

<VirtualHost *:80>

 ServerName  nb2ticpl4j4hnoxq.onion

 DirectoryIndex index.html
 DocumentRoot /var/www/hidden_service/

  CustomLog /dev/null common

</VirtualHost>

After saving the file, we need to symlink it to the sites-enabled directory and then restart Nginx:

$ sudo ln -s /etc/apache2/sites-available/hidden_service /etc/apache2/sites-enabled/hidden_service
$ sudo service apache2 restart

To test the hidden service, download and install the Tor Browser on any machine and load up your .onion address.

 

Conclusion

Your hidden service should be up and running, ready to server Tor users. Now that your relay is functioning, it may be a good idea to back up your hostname and private_key files mentioned earlier in the /var/lib/tor/hs_name_of_my_service/ directory.

I would strongly recommend taking a look at riseup.net’s Tor Hidden Services Best Practices guide to learn more about proper setup of your hidden service.

Additionally, subscribe to the tor-onions mailing list for operator news and support!

Sources