SSH Hidden Service

Posted on May 11, 2020

This is a short guide on using SSH over the Tor network. It can be used to hide the location of your server, and hide that you are connecting to your server. Note that your ISP will be able to see that you are using Tor, just not what exactly you are doing over Tor.

Running a hidden service doesn’t require you to open up any ports, so you can keep port 22 closed to the world and away from any automated scanners.

Install Tor

Your distribution might already have Tor in its package repositories, but it is best to use the repositories maintained by the Tor project1.

For Debian-based systems, this is only a few commands away:

# Add package signing key
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | apt-key add -

# Add Tor package repositories
cat << EOF > /etc/apt/sources.list.d/tor.list
deb https://deb.torproject.org/torproject.org $(lsb_release -cs) main
deb-src https://deb.torproject.org/torproject.org $(lsb_release -cs) main
EOF

# Update package listings
apt update

# Install Tor and package signing keyring
apt install tor deb.torproject.org-keyring

You will also need to repeat this step on any clients that you want to connect to the hidden service.

Configure a Hidden Service

Open up /etc/tor/torrc in your favourite text editor.

Firstly I like to disable the SOCKS proxy since we won’t be using it here, we can do this by adding the line SocksPort 0.

Next we need to add a block that describes our hidden service:

HiddenServiceDir /var/lib/tor/ssh/
HiddenServiceVersion 3
HiddenServicePort 22 127.0.0.1:22

We use version 3 of the hidden service protocol (identifiable by the longer addresses), which uses more modern crypto and has an improved directory protocol making it harder for people to discover your onion address.

If you would like to create a single hop onion2 (provide no anonymity to the server, but clients still get full anonymity), you can add the following lines to your hidden service block:

HiddenServiceNonAnonymousMode 1
HiddenServiceSingleHopMode 1

Restart Tor so that it can reload the configuration:

systemctl restart tor

Now a file should have been created that contains your onion address!:

cat /var/lib/tor/ssh/hostname

Save this somewhere, because we’ll need it shortly to connect.

Connecting via Tor

On your client computer, install Tor as before. You don’t need to alter any configuration values this time.

Using the torify wrapper program is very easy, and it works with any program (ssh, curl, …):

torify ssh user@blahblahblah.onion`

However, we can make things easier by using the ProxyCommand directive in ~/.ssh/config (create this file if it does not exist).

Host foo
  HostName blahblahblah.onion
  User user
  ProxyCommand /usr/bin/nc -x 127.0.0.1:9050 %h %p

To verify that your connection is indeed going over Tor, you can run echo $SSH_CLIENT. The address should be 127.0.0.1.

Going Further

  • Use the mkp224o tool to bruteforce a vanity onion address. e.g. mysshXXXXXXXXXXXXX.onion.
  • Read the manual on the HiddenServiceAuthorizeClient config directive to configure authentication for your onion.
  • Use the SSH ProxyJump option to connect to all of your machines through a single onion service.
  • Use Mosh3 instead of SSH, as it feels much better with high latency connections. Mosh requires UDP, Tor is not able to route UDP packets, and so unfortunately you cannot use Mosh.
  • Run a bridge to donate some bandwidth to the Tor network!
  • Deploy this using your favourite configuration management tool (like Ansible).

  1. Why and how I can enable Tor Package Repository in Debian?↩︎

  2. What’s new in Tor 0.2.9.8?↩︎

  3. Mosh: the mobile shell↩︎