I am a fan of SSH (Secure Shell), which moves bits around safely in a myriad of amazing ways. Tunneling, X11 forwarding, keepalives, passwordless access, ... it just gets better and better.
One part I didn't get my head around until recently is the "passwordless" thing and exactly how far you can go with that.
First there were keys...
In the simplest case, you type
ssh ssh.example.com, give a
password, and you're in.
An alternative -- and potentially passwordless -- way to make an SSH connection is with "keys" (i.e. using public-key cryptography).
For this, you have a pair of keys, the "private" one on the client and the "public" one on the server. (Conceptually) The SSH client encrypts something with the private key and, if it decrypts successfully with the public key, then it must have come from a Good Guy, and you're in.
You can make a passwordless key pair by typing:
ssh-keygen -t rsa -N ''
Copy the public key that's generated over to the server and put it
~/.ssh/authorized_keys and you're off. (Actually, it's very
fussy about permissions and things; never mind, there are hundreds of
how-tos about that all over the 'net.)
The security problem here is that, if someone gets at your client account (as you, as root, by nicking your laptop, ...), they've got your private key and can use it.
The first step back from the brink is to put a "passphrase" (a
password in high heels) on your private key. Leave off the
ssh-keygen. (You can also use
ssh-keygen to add a
passphrase to a previously-passwordless key.)
But, strangely, we're back where we started: Giving a passphrase every time you use a key feels exactly the same as giving a password each time.
... And then there were agents
The tool you want (and the main point of this note) is
It is a program that starts up, you tell it about your keys (i.e. hand over the passphrases), and then the SSH client cooperates with the agent to hand out keys when required -- no passphrases.
So: machine boots up, you login... quick session with
passphrases after that. Perfect.
ssh-agent is started for you as part of the login
env | grep SSH_, and if you see something for the
SSH_AUTH_SOCK, then you are already agent'd up.
How do you tell the agent about your keys (or "identities" as it
likes to call them)? That's what
ssh-add is for. If you have just
one key (not unusual), then just type:
give your private key's passphrase, and declare victory.
You can list keys/identities managed by the agent (
ssh-add -l), or
delete a key (
ssh-add -d), or lock your agent with a password while
you go to lunch (
How does the SSH client know which
ssh-agent to chat with about your
keys? It gets the information from those environment variables
And what about cron jobs? (or other scripted tasks)
A hard passwordy problem is cron jobs, with something like backups being a common and nasty example. You need to move bits from one machine to another (so SSH is just the thing) but you need to do it as root. It must run completely unattended.
Putting the root password in a backup script -- no doubt often done... -- is a complete non-starter.
Passphrase-less keys are much better, and OpenSSH provides many extra ways to mitigate the risk, e.g. only allowing connections from certain IP addresses.
But the fact remains: If someone gets one of root's passphraseless private keys, it's fairly worrying.
So can we play the
ssh-agent game to limit this risk? Yes.
It is possible to start up an agent by hand (or by script), and save
SSH_ environment variables (which it will emit) in a Well Known
Location. Scripts can then source those variables (from the Well
Known Location) and get the benefit of the agent.
Is that the best we can do?
Yes. When a machine (re)boots, an
ssh-agent can be started, the needed
environment-variables recorded, and someone
ssh-adds all of the
keys that will be needed (i.e. gives their passphrases). That is the
least human interaction possible for really quite-secure unattended SSHing.
As long as the machine stays up, scripts should be able to work without any passphrases.
SSH_AUTH_SOCK environment variable points to a socket in the
filesystem (with restricted permissions). Surely, if I can get
read/write permission to that socket (e.g. if I'm root), then I can
ssh-agent to take advantage of post-passphrase SSH keys?
Yes, that's right. Two things: (a) If someone is already on your
system, perhaps as
root, you already have a big problem, never mind
SSHing. (b) The bad guy can use your key through the agent, but
cannot get a copy of the private key itself.
There are almost-as-convenient ways to use passphrase-laden SSH keys as the much-more-vulnerable passphrase-less ones. Use them!
You can get comparable security even for unattended automated tasks (scripting).
[An earlier version of this note appeared in Verilab's internal newsletter.]