Kate's Comment

Thoughts on British ICT, energy & environment, cloud computing and security from Memset's MD

How to secure Mac OSX Screen Sharing with SSH tunnelling

I want to be able to access my home machines over the Internet when I’m at work, preferably via a GUI/WIMP. It is relatively straight-forwards to expose a machine on your home network using port-forwarding on your router, but is it secure just to send Screen Sharing over the Internet? For that matter, if you’re on a semi-untrusted local network (maybe your housemates have debatable personal laptop security standards) is it secure?

A bit of Googling suggests that it is not. While Mac Screen Sharing will encrypt authentication and keystrokes/mouse moves it does not by default encrypt the streamed screen contents. There used to be an option under the Screen Sharing app’s preferences where you could enable “fully encryption” but this was removed in OSX 10.8 for some bizarre reason. If you’re using a VNC client to connect with a password then there is no encryption at all by default.

There are third party apps which will allow fully encryption such as Remotix, but you don’t need to spend the money. Instead you can create a SSH tunnel to securely carry the Screen Sharing connection between your devices.

Creating your SSH tunnel

Since we’re likely to be doing this often it is worth making a quick command to create the tunnel. Open up Terminal and edit ~/.ssh/config. I normally use nano for command-line editing, like so:

nano ~/.ssh/config

If ~/.ssh doesn’t exist just create it first with “mkdir ~/.ssh”. Once you’re in nano copy and paste the following:

Host ext
Port 22
User <your-username>
LocalForward 5999

Replace the IP address after “HostName” with the IP address of the machine you want to connect to. Also replace <your-username> with your username on the remote machine. Save the file with <ctrl>-x and follow the prompts (“y” then <enter>). Now you simply need to type the following to open the tunnel:

ssh -f ext -N

If this is the first time you’re connecting to the server via SSH you’ll get a warning about “The authenticity of host can’t be established”. That’s expected – just say yes. You should then be prompted for your password and  be connected to the remote machine. Nothing will actually appear to happen because of the -f and -N. They tell SSH to open the tunnel in the background. If you want to be certain it is connecting you can remove both of those (you will be logged in like normal), but you’ll then need to leave the SSH connection and Terminal window while you’re using Screen Sharing.

If you don’t want to have to type in your password every time you can use ssh-keygen to create a public/private SSH key pair (you put the public bit in ~/.ssh/authorized_keys on the remote host), but that’s probably another article. 😉

If you don’t want to have to type “ssh -f ext -N” each time you can make an alias for that in your ~/.bash_profile. You could put the whole command into an alias if you wished rather than editing ~/.ssh/config. It would like like this:
alias <your-command>='ssh -f -L 5999 <your-username>@<remote-host-IP-address> -N'

Connecting to using Screen Sharing over the tunnel

5999 is the local port which is being forwarded via SSH to the Screen Sharing port (5900) on the remote host. To connect you now need to go to Finder and hit <ctrl>-k to open the “Connect to Server” dialogue. Enter the following into the address bar:


Click the “+” to save it in your “Favorite Servers” list for future convenience. Now click “Connect”. If all goes well you should now be prompted for your username and password on the remote host. You can save this in your KeyChain so you don’t have to type it every time. Then, you’re in, and viewing your remote machine over a SSH-encrypted connection. 🙂

Note that if you are using this to connect into a home network then you’ll need to port-forward SSH (port 22) rather than Screen Sharing’s port (5900) on your router to the host you want to connect to. This is a good thing since SSH is a well-hardened protocol and probably the only one you should ever consider exposing to the Internet. If you are doing that also ensure you take appropriate security precautions: A good firewall is absolutely necessary – get LitteSnitch (you’d be nuts not to IMHO) and ideally lock down incoming connections on port 22 to known ones like your office, use cryptographically-strong passwords – or better yet SSH keys, and consider installing Fail2Ban (non-trivial on Mac unfortunately).

Tidying up your tunnels

The above will work fine, but it does have the potential to leave unused SSH tunnels (well, usually only the one) lying around after you’re done. This is sub-optimal. It is easy enough to find and kill them like so:

ps aux | grep ssh

This will list processes matching “*ssh*”. Your tunnel will likely be last on the list and you should be able to recognise them. Something like these, depending on your approach:

kcw             26398   0.0  0.0  2499156   1064   ??  Ss    1:38pm   0:00.09 ssh -f -L 5999: kate@ -N
kcw             34527   0.0  0.0  2508300   804   ??  Ss    1:23pm   0:00.29 ssh -f home -N

The first number is the process ID (pid). You can safely kill just those processes with “kill <pid>” like so in this example:

kill 26398
kill 34527

That’s a right faff though. An alternative is to get SSH to run the sleep command on our remote host. This uses no resources and at the end of the specified time, if nothing else happens, the sleep process will quit and SSH will in turn disconnect from the host. If, however, we start using Screen Sharing in the mean time then SSH will detect that and keep the tunnel open for us until we stop using it. SSH is extremely cunning! If you want to do this it is best to take the one-liner / .bash_profile alias approach (see above) rather than putting commands into your SSH config:

alias <your-command>='ssh -f -L 5999 <your-username>@<remote-host-IP-address> sleep 60'

“60” is the number of seconds to sleep for. It can be as little time as it takes you to open up Screen Sharing. Remember that the tunnel will close once you stop using Screen Sharing so you’ll have to re-open the tunnel each time you want to use it with this method.

On Linux it is possible to open the tunnel and launch the screen sharing app of choice, but I can’t work out how to do that on Mac. If anyone knows please let me know and I’ll update the blog post.