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
. 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 HiddenService
. 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
VerifyHostKeyDNS no
is there to avoid a DNS leak. This is the default anyway, but DNS leaking is bad and you should make sure.ProxyCommand nc -X 5 -x localhost:9050 %h %p
does the work oftorify
.-X 5
tells netcat to use SOCKS v5,-x
sets the proxy address and port.%h
is replaced by the value ofHostName
and%p
by the value ofPort
(or else is just set to 22). This assumes Tor is using port 9050, but it sometimes uses 9150 (if you’re using the TBB) — try both or check the value ofTorPort
in/etc/tor/torsocks.conf
.- You could also put the Tor-specific options under
Host *.onion
.
Finished
Now you can just run
ssh hostname
to connect to your server over Tor.
Some other things:
- You can have as many hidden services as you like on the same machine.
- Use Shallot, Scallion, etc. to generate vanity
.onion
addresses, if you’re into that kind of thing. - Change the port for a bit of extra security through obscurity. You could also try port knocking.
- If you’re running your hidden service on a relay, this will compromise your anonymity. The same holds if your hidden service is also serving something on the clearnet.