How to Set Up an SSH Server as a Hidden Service

This article assumes you’ve got an SSH dæmon on your host machine running on the clearnet and you use Ed25519 keys. If you haven’t already, make your server secure: use iptables (or something equivalent) and choose good algorithms.

For the Host

Add the following to /etc/tor/torrc.

HiddenServiceDir /var/lib/tor/ssh/
HiddenServicePort 22 127.0.0.1:22
HiddenServiceAuthorizeClient stealth clientname

The first two lines are obvious. The last line isn’t strictly necessary, but adds a fair bit of security by only allowing specified clients to connect. Read the man page entry.

Reload Tor and open /var/lib/tor/ssh/hostname. It should look like this.

hostaddress.onion authcookie # client: clientname

That’s it.

For the Client

Now add

HidServAuth hostaddress.onion authcookie

to your local /etc/tor/torrc file (i.e. the contents of the hostname file becomes the value of HidServAuth). This is only relevant if you used HiddenServiceAuthorizeClient. Again, read the man page entry.

We can now check if this all worked. But wait! SSH mitigates man-in-the-middle attacks by displaying a fingerprint of its host key for you to verify. Before you connect over Tor, you should get a copy of this fingerprint to compare.

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

It’s important to do this before you log in over Tor, but you can check after the fact by looking for the public key in ~/.ssh/known_hosts (if you don’t obfuscate that file). It should obviously be the same over Tor and the clearnet.

OK, let’s connect. Run

torify ssh -i ~/.ssh/id_ed25519 username@hostaddress.onion

and make sure the fingerprint matches what you expect.

If this worked, we just need to streamline the process. Let’s edit ~/.ssh/config. First, we need to get netcat to proxy SSH traffic. I’m using openbsd-netcat, the syntax is slightly different for gnu-netcat.

Host hostname
    HostName hostaddress.onion
    Port 22
    User username
    PubkeyAuthentication yes
    IdentityFile ~/.ssh/id_ed25519
    VerifyHostKeyDNS no
    ProxyCommand nc -X 5 -x localhost:9050 %h %p

Finished

Now you can just run

ssh hostname

to connect to your server over Tor.

Some other things: