*nix Tip of the Day: SSH Agent Forwarding

Posted Mon 12 May 2008 18:31 under category tips

Today's *nix tip of the day involves SSH and the magic that is Agent Forwarding.

SSH, as some of you know, is a handy way to connect to *nix systems in an untrusted environment. Its primary use is to allow one to remotely access a remote system and get a shell, securely. Basically, encrypted telnet. Of course, SSH has tons of other useful features (like tunneling, proxying, and multiplexing), some of which might come up in future Tips of the Day.

One of SSH's greatest features is its public/private key system. Basically, using private keys, you can allow much more secure access to a remote machine. If you trust your local machine, you can even allow passwordless access to remote machines if you have an unencrypted private key. Of course, this is a bad idea if you think people might be able to compromise your local private key, which is why SSH private keys can also be encrypted with a symmetric cipher (basically, a password). Using this gives you all of the in-transit security and power of private keys, but all of the local security of password authentication (something you have + something you know sort of deal). They're covered a great deal more in a retroactively-posted tip of the day -- read back a bit.

This is all well and good, but there are times when typing your SSH key's passphrase is annoying. For example, the Z Shell allows for tab-completion of remote filenames over ssh (when using scp, for example). It is an awesomely useful feature that makes remote filesystems feel local without any of the muss of sshfs. However, if you have an encrypted private key (or password authentication), typing your password every \<TAB> can be a pain. Hence, ssh-agent.

ssh-agent is a program that you will generally run as a wrapper around your session (this is done automagically on linux if you're running gdm). If you want to test this stuff, you can just run exec ssh-agent \$SHELL from a terminal and then execute all of the commands from this tip in that shell. Now, let's say that you've put your private key in the standard ~/.ssh/id_rsa, and it's encrypted. At your newly-ssh-agent'ed shell, type in ssh-add \~/.ssh/id_rsa and type in your private key's encryption passphrase when prompted. Congrats -- you can now ssh from this shell to any machine containing your public key without any password at all. Isn't that awesome? Try it out. I'll wait.


Now, this is well and good. But let's say that you just ssh'd to example.com using your super-duper ssh-agent, and you want to ssh from there to your other server at example.net. Do you need to copy your private key onto example.net and then type the passphrase there? That might be a bit risky, especially if you don't really trust the admins of example.com. I mean, the key is encrypted, so you're probably okay, but what if they're running a keylogger? Well, as long as you're using OpenSSH (which you most likely are), you're fine, thanks to the magic of agent forwarding. Log out of example.com, and then run ssh -A username@example.com. Note the -A. This turns on agent forwarding, and means that your login at example.com temporarily has the same access permissions as your local machine. So you can happily ssh user@example.net and get the happy password-free access without anything else. You can even agent-forward from example.com to example.net and build up a chain of secure authentication credential forwarding all the way back to your local machine. It's awesome.

Well, that's my tip for the day. Check back again in the future for more exciting things that other people have said and done before.