X11 forwarding

The ssh tool has a lot of cool stuff that a lot of people don't know about it when they use it for the first time. For example, did you know that it can do automatic X11 forwarding? What that means is that you can log into another computer, and run an X11 program on that other computer, and have it appear locally. This is in part due to X11's network transparency, and in part due to 'ssh' doing some magic.

This might already be enabled for you; try it. If it isn't working, then you need to edit /etc/ssh/ssh_config and change the line

#  !ForwardX11 no


   !ForwardX11 yes

on your machine. And on the remote machine, you need to edit /etc/sshd/sshd_config and change the line

#X11Forwarding no


X11Forwarding yes

Then restart the ssh daemon on the remote machine. On most distributions, you can do this by running

/etc/init.d/ssh restart

or maybe

/etc/init.d/sshd restart

Then you should be good to go. This is really nice if you have a couple computers around your house; you can just log in and run programs from one computer as if you were actually sitting at the other.


Another really useful feature that ssh has is the ability to password-less authentication. This may sound insecure, and of course it is less secure than requiring a password every time, but the way it's done with ssh doesn't make it too bad, and it is very convenient.

Setting up password-less logins with ssh is explained in many places on the 'net. However, the first time I did it, I found that many of these explanations were lacking, so I'll try to do better. To set up a password-less login with ssh you're going to need to do the following:

  1. Generate a private/public key pair.
  2. Copy the public key to the remote machine.
  3. Add the public key to a list of "authorised" keys.

So, 3 simple steps. Shouldn't be too bad.

1. Generate the keys

To generate the keys, run

ssh-keygen -t rsa

as your normal user. This should ask for a passphrase. You don't need to enter one, but it's a good idea. If you set things up properly, you will have to type your passphrase very rarely, so it's a good idea to make it quite long.

2. Copy the public key

The previous step should have generated a file called id_rsa.pub in your ~/.ssh directory (assuming you accepted the default choice). We now copy this file (and not id_rsa -- that one's private) to the remote host:

scp ~/.ssh/id_rsa.pub user@remote.machine.com:~/

3. Add key to authorised list

Now, you need to login to the remote host, and add that public key to a list of authorised keys:

ssh user@remote.machine.com
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
rm ~/id_rsa.pub

This is the crucial step, so make sure to get it right. In particular, I know I've screwed up by trying to use authorized_hosts instead of authorized_keys at least once :)

Hopefully finished

Now, log out of your remote connection, and try it again:

ssh user@remote.machine.com

You should a message like:

Enter passphrase for key '/home/username/.ssh/id_rsa':

Or maybe it just logged in without asking you anything, if you didn't enter a passphrase. If you did enter a passphrase, however, enter it now, and you should be logged in.

Using the agent

But wait, you say! What good is this? I had to enter a password before, and now I have enter a different one, and you even told me to make it longer! This is stupid!

And you're right, it would be stupid, if it weren't for ssh-agent. Using ssh-agent properly used to be kind of complicated, and involved hacking around with xinitrc files and so on. Now, however, most distributions have ssh-agent set up out of the box, so that it's automatically used when running X11. So, on your local machine, try this (from a terminal within your X11 session):


It should ask for your passphrase. Enter it. Now try to ssh to your remote host again. You should be logged straight in. What this means is that you only have to enter your passphrase once, when you first log in to your local machine. Then you can ssh to the remote host all you want and never enter a password.

Side note: if you use Mac OS X, everything I've talked about applies up until now. The ssh-agent stuff is somewhat different, however: by default there is no agent in OS X. However, you should really check out http://www.phil.uu.nl/~xges/ssh -- it's a graphical ssh-agent front-end and is dead easy to use. If you've done as I said above, then all you need to do is run it when you log in, enter your passphrase, and close the window (but don't "Quit" the application).

If it goes wrong...

Now, if you're like me, you get to this point in the procedure, and you've done everything precisely as I've said above, and it still doesn't work. This happens to me almost every time I setup ssh keys, and it's almost always due to permissions of the public/private keys or perhaps the authorized_keys file. So check these permissions (with ls -l):

On the local machine:

On the remote machiine:

Unfortunately, if you've checked all that, and done everything precisely as I said above, and it still doesn't work, I don't have too many suggestions, other than to check the /etc/ssh/ssh_config file locally and /etc/ssh/sshd_config file on the remote host and look for anything disabling key-based authentication.

Fun with authentication

Having password-less logins lets you do some fun things. For example, if you want to run a command on the remote machine, you can just type

ssh remote.host.com command

and it'll just run right away.

Another neat trick is to set up shortcuts that open terminal windows already logged in on another machine. To do this in GNOME, right-click on your desktop (or panel, if that's where you want it) and choose "Create Launcher". Type in a name like "Terminal on hostname" and for the command, type ssh remote.host.com. Then check the box that says "Run in terminal." You should be good to go; click on the link and see if it works.

Stored hostnames/usernames

One thing that can be a pain is if you use a different username on your home box than your username on the remote box. For example, let's say you're the ever-popular Jane Doe, so your username at work is jdoe, but (despite your name) you've got quite a stinging personality, so your username at home is medusa. This means that every time you ssh to work, you have either type ssh -l jdoe work.com or ssh jdoe@work.com. Wouldn't it be nice to have ssh remember the username associated with work.com? Or what if your company lost out on the whole cybersquatting thing, so your work has a really annoying domain, like thisistheincrediblylongannoyingdomainfromhell.com? Wouldn't it be nice to alias that to something nice, without resorting to annoying /etc/hosts hacks?

Well don't fear, you can!

This can be done using either /etc/ssh/ssh_config or ~/.ssh/config. It's better to use ~/.ssh/config for this kind of thing (the kinds of situations I described above) because they are likely to be highly user-specific.

If you don't have a ~/.ssh/config, never fear. Just create one. The syntax for doing host aliasing is like this:

Host work
HostName thisistheincrediblylongannoyingdomainfromhell.com
User jdoe

Now Jane can just do ssh work and have all the right information automagically filled in by ssh. And of course this also works with scp, so Jane could also do scp work:~/boring_file . and get the same automagic goodness. Now if that doesn't give you a warm fuzzy feeling inside I don't know what will!

Happy ssh-ing!