Securely Connecting to Your Home Server

I’ve recently found the need to connect to my home network remotely quite a bit lately. There’s a number of solutions out there to do this, including setting up your own VPN tunnel using some open source tools. While I am a fan of VPN, I’ve opted for a simpler solution using OpenSSH and port forwarding on your router.

The horror of port forwarding isn’t necessarily the act of the forwarding itself, but the service in the background your forwarding to. I didn’t feel comfortable having Transmission or Couchpotato publicly accessible from the web. It was less about someone submitting crazy torrent downloads and more about those services having potential vulnerabilities in their prepacked web servers.

Generating the SSH Keypair

The first thing you’ll want to do is make sure you can login to the machine via a public/private key pair. In order to do that, you’ll need to first generate a keypair.

ssh-keygen -t rsa -b 4096 -o <key_file_name.key>

You’ll want a nice big fat key size (hence the 4096) just to future proof it. And considering this is for your home machine, the overhead you’ll pay for it is largely irrelevant. This command will generate two files, the file name you specified as -o and a file of the same name with the .pub extension.

It is very important to understand the difference between these two keys. One is the public key (.pub) which you are allowed to share with other systems for authentication. The other (without the .pub) is the private key, which you should never, never, never share. Your private key also requires specific file permissions, so you’ll want to execute the following.

chmod 700 <key_file_name.key>

Now you need to get that public key on to the server. The easiest way to do that is using the command ssh-copy-id. Once again, stress the importance of knowing the difference between the two keys, you should only copy your public key to the server. (The file ending in .pub)

ssh-copy-id -i <> <user>@<ipaddress>

It will ask you for your password and then copy the file to the correct location. Now to test that it works

ssh -i <key_file_name.key> <user>@<ipaddress>

If you set everything up right, you should be logged in without being prompted for a password.

Securing OpenSSH

The first thing you should do prior to forwarding OpenSSH

Instead of just copy/pasting the OpenSSH config, I figured it made more sense to put it on Github so that we can continue to evolve and refine it over time. Check back periodically to see if there’s any updates to the config.

Enable Port Forwarding on your Router

Enabling port forwarding is specific to your router. If you already know how to do it, then just make sure you forward port 22 to port 22 on your target server. If your home internet service provider is giving you a static IP address, then connecting is easy. If not you may want to look at a dynamic DNS service so that as your IP address changes, your DNS record is updated.

If you need to check what your public IP address is, you can execute the follwoing


That should return your public IP address.

SSH Tunneling

Now you can setup your SSH tunnel to send traffic over port 22 to any of the ports on the local machine. From your client, open a terminal and execute

ssh -i <private key> -L <port-to-forward-to>:<server ip>:<local port> <username>@<server ip>

So that’s a handful.

ssh -i server.key -L

If you need to forward multiple ports, you can repeat the -L flag for as many ports as you need.

The last step is to open your browser and go to “http://localhost:port” where port is the local port you specified in the above command. Your port should be forwarded and connected to the remote server.

Voila, you’re now communicating with your remote server securely.

UPDATE: Some folks have said that they have problems connecting remotely, with a “connection refused” or “server unexpectedly closed the connection”.

I’ve seen this happen on some setups and adding a localhost entry usually resolves the issue. In your /etc/hosts file just add an entry for that matches your server’s fully qualified domain name. (ex:

comments powered by Disqus