---
title: SSH access through Tor Hidden Service
date: 2019-03-11 18:30:00
---

I have a number of computers that are connected to different networks, sometimes
accessible from the Internet, sometimes behind a NAT that I can configure,
sometimes behind NAT that I cannot modify and sometimes behind multiple
obstacles.

Recently, I discovered that there is a very easy way of dealing with this:
Tor Hidden Services. Usually when we think about Tor, we think about the
anonymity part of the network, but it also provides a connection that is
unfiltered and thus allow access to our services even if they are behind
NAT, have a dynamic IP address or are protected by firewalls.

## Configuration of a Hidden Service
We will install and configure Tor to expose our SSH daemon to the Tor
network through a hidden service.

```
$ sudo apt update && sudo apt install tor

$ sudo tee -a /etc/tor/torrc <<EOF
HiddenServiceDir /var/lib/tor/onion-ssh/
HiddenServicePort 22 127.0.0.1:22
EOF
```

Restart the service so that the configuration directory for your new service
is created with the correct permissions and content.

`systemctl restart tor@default`

Once the service is restarted, you can get the generated address from the
service configuration directory.

`sudo cat /var/lib/tor/onion-ssh/hostname`

Wait a few seconds so that it connects to the network and your service
should be available.

## Vanity addresses

This part is optional but allows you to create so called Vanity addresses
for your hidden service. A vanity address is an address starting with a
human readable prefix or suffix. I like to start my services with a
given prefix depending on where I'm using it, just because it's possible.

There are a number of programs available to generate a number of hashes
and generate *collisions* with your prefix. I use Eschalot for this.

```
sudo apt install build-essential libssl-dev
git clone https://github.com/ReclaimYourPrivacy/eschalot.git
cd eschalot && make
```

As the process is essentially brute-force, don't try generating something
with too long a prefix.
On my computer, a collision with a prefix of length 4 will take less than
a tenth of a second, a prefix of length 5 will take twice as long and a prefix
of length 6 will take around 20 seconds.

```
./eschalot -vnp inf3 -t 4
Verbose, single result, digits ok, 4 threads, prefixes 4-4 characters long.
Thread #1 started.
Thread #2 started.
Thread #3 started.
Thread #4 started.
Running, collecting performance data...
Found a key for inf3 (4) - inf3melq3f3fpokb.onion
----------------------------------------------------------------
inf3melq3f3fpokb.onion
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDa929qGBCBC6ls5HAWjZOdfwct3D3DU7JAnMSvXKHGKBXV2qy8
2cPwvnqriyT6PkUw7tFQG4cdnwbzkJRQ6hzBW8OcFANytQzRUEibPS8MfbVIKdvp
a1tAqgF+f7vFL0TzjoNlf81oJHW6phBjYWKQ5GTd3WywLAc3E2wGj5SUCwIEAQFR
gQKBgC9Je1KfMtXutICuo6+8N3ODapnj3VAJ7uhyvDbEazzZuNo+/oqrKIUD1cGA
YZIotRdhv+GQPYDW62GRqwd/BlA72dGKWBVbdMOst/dE7qDAnjcTpgdLJOa0Yek1
65979lQ0ZK1yIXCvsSEK98fNzCSiaMC6oXrPBgweLQReSw/ZAkEA/8EG0gH+Zwie
oYAYLRnMPF/cwozKxHCsE/Pp9E+XHgmokvnfuZrBWRH8tc+6SyNrkMazq7zpGgzK
vFbbL18gUwJBANstWbxQZUcMbT81q1xSsoHD/zdKXyLRY2w5F5AAGPPFFbR7pvRA
qvHuxbfLUYSNS0OO13hli5v5w5fE2ymsJmkCQAztiLQWRRyTKBCgXsdhDkwwXXTc
lc/YAsnAPJ5B+0ruztIImG+J2gcZWTIC6451rFErlik+92asIEUVibWk4z8CQQCl
9iushVkFIvlyUv0XBCKqk6rCAt4kT+U2vvKlgmfMZRxSZ+1stm6rNH5O+dpDLExY
yRZ+a0xvbzmuc6TwvLKxAkB9UciXBhpJdcw9Jtq2gjAVFeq/pyMrsCf1DxQDGMxp
Nnryo/WI0VoJz9cco6xf/su1F05xdcMrD+dOO2RAv/OB
-----END RSA PRIVATE KEY-----
```

Once Eschalot finds a result, copy the RSA private key from the output and
replace the content of the private key file used for your service,
located in the service folder at `/var/lib/tor/onion-ssh/private_key`.

Then, restart Tor so that the new key is taken into account.

`systemctl restart tor@default`

You can check that the address of your service changed to the one found
by Eschalot in the `/var/lib/tor/onion-ssh/hostname` file. This file
is rewritten by Tor on every execution to reflect the Tor address of the service
and this changes when the private key is changed.

`sudo cat /var/lib/tor/onion-ssh/hostname`


## SSH Client configuration
By default, SSH won't know how to connect to the Tor network or an `.onion`
address. We will need to also install Tor on the client service and tell
our SSH client that `.onion` hosts are somewhat special and need to be accessed
through a socks proxy.

`sudo apt update && sudo apt install tor ncat`

We will alter our SSH configuration so that, when encountering an `.onion`
address, SSH will use a proxy instead of trying to connect directly. We
also add an easier way to remember the address of our server now available
through a hidden service.

```
cat - >> .ssh/config <<EOF
Host *.onion
    proxyCommand ncat --proxy 127.0.0.1:9050 --proxy-type socks5 %h %p

Host tor-myserver
    hostname inf3melq3f3fpokb.onion
    proxyCommand ncat --proxy 127.0.0.1:9050 --proxy-type socks5 %h %p
EOF
```

Once the SSH client is configured and some minutes passed to allow both
the client and the server to be connected to the Tor network, we can try
to connect to our server, through the Tor network, bypassing every NAT or
other block that would impede our direct connection:

`ssh tor-myserver`
