Student created, untested manual, that should work and is FUN voluntary exercise!
Any fixes comments please send alo.peets@ut.ee
Creating a Tor Hidden Service
The Onion Router, or Tor in short, is a protocol used for anonymity and privacy in the net.
Their infamous hidden services have been used for all manners of crimes but we can put it to legitimate use.
In this lab, you are going to expose your SSH service through your own hidden service.
Using the hidden service will protect our identity and the location of the server, with the added bonus that if the DNS or VPN ever fails, the server will still be reachable through the Tor network as long as the server can connect to it.
These instructions are generic, they would also work to expose any kind of service to the Deep Web.
The first step is to install tor. Use apt install tor
The Tor package contains everything you need to connect to Tor and test it from the command line, note that the configuration files are saved to /etc/tor
Now we will start Tor to check if we can connect to the network. So far you don't need to modify anything.
systemctl start tor
You won't see any information after running that command, to check if Tor is running correctly you can do the following:
systemctl status tor
which would give you some information that looks like this:
● tor.service - Anonymizing overlay network for TCP (multi-instance-master) Loaded: loaded (/lib/systemd/system/tor.service; enabled; vendor preset: enabled) Active: active (exited) since Tue 2018-05-22 17:54:04 EEST; 11min ago Main PID: 6373 (code=exited, status=0/SUCCESS) CGroup: /system.slice/tor.service
To check our connection, lets use a cURL trick. If you have not installed cURL, now is the best time: apt install curl
There are useful online IP APIs that can be freely used to check with an external server which connection information the external server is getting from our request, here are some:
- https://ifconfig.co
- https://ifconfig.me
- http://ip-api.com (watch out, this last one doesn't uses TLS)
curl -s https://ifconfig.co/json
The server should respond with the following information:
{"ip":"193.40.12.10","ip_decimal":3240627210,"country":"Estonia","country_iso":"EE","city":"Tartu","hostname":"sein.ut.ee"}One of the nice utilities that Tor has bundled in their installation is the
torify
app, which when used before a command, will route the connection through a SOCKS5 proxy to our Tor service, thus using Tor to anonymize our connection.Let's see if tor is actually working, we are going to use the same command, but we are going to torify it.
torify curl -s https://ifconfig.co/json
If the command was successful, it means you are using Tor correctly, the output should be a completely random Tor exit node, like so:
{"ip":"91.219.236.171","ip_decimal":1541139627,"country":"Hungary","country_iso":"HU","hostname":"sa1445.azar-a.net"}
So far Tor should be able to connect to the internet and ask a server for information, you could try torifying a ping and fail though, why does this happen?
Warning! While Tor traffic is encrypted by default, your exit node will send your requests in your behalf as your computer would do so if directly connected. If you are sending sensitive information through HTTP, then the information will be visible to your exit node and whoever is spying on the exit node connection. When routing anything through Tor, make sure that it is encrypted (https, ssh, gpg email, tls smtp, etc.)
A Hidden Service, unlike normal internet traffic, is completely encrypted inside the Tor network as no exit node is needed to reach the 'outside', so while torifying a telnet connection to a site on the internet would be a terrible idea, it is not so terrible to run a telnet service on the hidden network. That telnet service would be protected by the layered encryption provided by Tor.
We will now proceed to let Tor create our RSA secret and public keypair. This will determine our hidden address in the onion network.
To do so, edit the /etc/tor/torrc
file.
If you haven't found it already, these are the relevant lines:
## 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/hidden_service/ #HiddenServicePort 80 127.0.0.1:80
While running SSH is perfectly fine, it wouldn't be the best idea to run it in a default port. Hidden services are 'location hidden' not 'service hidden' meaning that any bot roaming the deep web could connect to our service and attempt to brute force it, and we wouldn't have a clue who did. A minimal step against this (essentially to not be the lowest hanging fruit) is to use something other than the default port.
- uncomment the
HiddenServiceDir
line, leave it default to the hidden_service directory. - read the
/etc/tor/torrc
comment where it explains how the redirection works - without modifying your sshd configuration, configure tor to route SSH through port 666
/etc/tor/torrc
you can conveniently create your hidden service by restarting tor, with the following command: systemctl restart tor
This all worked if you can list the files in
/var/lib/tor/hidden_service
. You should see something like this:# ls -l /var/lib/tor/hidden_service/ total 16 drwx--S--- 2 debian-tor debian-tor 4096 May 22 19:07 . drwx--S--- 3 debian-tor debian-tor 4096 May 22 19:08 .. -rw------- 1 debian-tor debian-tor 23 May 22 19:07 hostname -rw------- 1 debian-tor debian-tor 887 May 22 19:07 private_key
Notice that the tor user is debian-tor.
Using cat, you can check your hidden service hostname: cat /var/lib/tor/hidden_service
The hidden service hostname is derivated from the public key of the private key in this directory, meaning that traffic in the tor network is signed with that private key, ensuring that only the owner of the private key can own the hostname. This key is securely and randomly generated, and as you can see by the permissions, should only be readable to its owner.
For example, my hostname is jwvnxsqcguktzhmp.onion
To test that you can reach your hidden service, download and install Tor in your laptop and use torify to connect directly to your .onion address. Check that your SSH fingerprint is the same.
- Linux users, depending on your distribution, installing is as easy as
sudo apt install tor
orsudo pacman -S tor
- Mac OS users, you can use brew to install both tor and torify, check the guide in https://www.torproject.org/docs/tor-doc-osx.html.en
- Windows users, you guys can use the SOCKS5 proxy configuration in PuTTY to connect, follow the guide here: https://trac.torproject.org/projects/tor/wiki/doc/TorifyHOWTO/Putty
Notice how the hidden service is accessible even without adding any iptables rules or opening up a security group in your ETAIS instance. This is because Tor uses the loopback device (lo0 and 127.0.0.1) to route the encrypted packets.
To get a vanity address like https://facebookcorewwwi.onion
you would need to randomly generate millions of RSA private keys until you find one which its public key representation contains whatever string you are looking for.
You can find a program to do so here:
https://github.com/ReclaimYourPrivacy/eschalot
Please do not try to run eschalot in your VM instance, as generating the millions of keys to match the URL is as resource intensive, if not more, as cryptocurrency mining. Doing so can and will make ETAIS break and everyone will get mad.
Run it in your laptop, give it a try, then you can replace the files hostname
and private_key
with the ones you generated. This is entirely optional.
There has been an update to the security of hidden services. The default is v2 which uses RSA for the private keys, the new version is 3, and it uses ed25519 for the private key, making the hostname longer than the default in v2. To generate vanity addresses for them use this:
https://github.com/cathugger/mkp224o
Docker containers
Great! now, having SSH is all good, but there is nothing as cool as really watching your own website running in the .onion address through the Tor Browser Bundle. We don't want to go through the pains and horrors of setting up an apache vhost listening on 127.0.0.1:8080, so why not learn the beauty of Docker containers?
A docker container is like a micro VM, sometimes it even runs its own Linux kernel inside, with an already configured service that you just need to pull and run, is even easier than using apt install
Recently, Docker has been pushing for the Enterprise Edition, making the distribution packages obsolete. (another reason to use snap
packages instead). However, they are still maintaining Docker CE, community edition, as the open source alternative. This is the new procedure to install docker, feel free to copy-paste these commands, you can check their meaning in depth here:
https://docs.docker.com/install/linux/docker-ce/debian/
Installation steps:
apt update
apt install apt-transport-https ca-certificates curl gnupg2 dirmngr software-properties-common
apt-key fingerprint 0EBFCD88
gpg --receive-keys 7EA0A9C3F273FCD8
gpg --export 7EA0A9C3F273FCD8 | apt-key add -
The last '-' matters!add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt update
apt-get install docker-ce
And now, to test docker, lets use the simple hello-world container:docker run hello-world
Now that we have installed Docker, we can pull a container with our favorite service and run it. You can create such containers and replicate them on your servers, it makes deployments very easy. If you want to try that, here is a great guide:
https://access.redhat.com/articles/1328953
However, we will focus on super-fast super-easy not-so-dirty.
These are the steps to run the official apache httpd container for our hidden service:
First, you need to create a new directory, here we will store all the contents of or hidden website:
mkdir /var/lib/tor/hidden_service/www
- change the owner:group of the newly created directory to www-data
Make sure to edit /etc/tor/torrc
we will let docker use port 9001.
HiddenServicePort 80 127.0.0.1:9001
docker run --detach --interactive --tty --name hidden-service -p 127.0.0.1:9001:80 -v /var/lib/tor/hidden_service/www:/usr/local/apache2/htdocs/ httpd
Command breakdown:
- --detach Run container in background and print container ID
- --interactive Keep STDIN open even if not attached
- --tty Allocate a pseudo-TTY
- --name Assign a name to the container
- -p 127.0.0.1:9001:80 Publish a container's port(s) to the host, mapping 127.0.0.1:9001 to the internal docker port 80
- -v /external/path:/internal/path > Bind mount a volume, maps a real directory to an internal directory in the container
- httpd the apache httpd service container
You'll notice that docker downloaded 'something', these were the required containers to make http work: a lightweight Linux OS, httpd, etc.
You can check running containers with:docker ps
If for any reason you need to stop the container just use:docker stop <id>
where id is the docker id given by ps
and to delete the container use:docker remove <id>
Let's check if the service is actually listening, you can do so by using docker ps
and netstat -antup | grep docker
Finally restart tor and give it a few minutes for the circuit to be created and the hidden service published.
You can download the Tor Browser from: https://www.torproject.org/download/download-easy.html.en
Check your fresh hidden service! whenever you stop the container or tor you'll bring it offline.