ssh-agent(1) is your friend.
Jun 11th, 2007 by dmess0r
Summary: How dmess0r makes ssh-agent do that voodoo that you want to do.
This is my ssh-agent configuration. There are many like it, but this one is mine. My ssh-agent configuration is my best friend. It is my life. I must master it as I master my life. I will learn it as a brother. I will ever guard it against the ravages of weather and damage. I will keep my ssh-agent configuration clean and ready, even as I am clean and ready. My ssh-agent configuration and myself are the defenders of my country … So be it, until victory is dmess0r’s and there is no enemy but peace.
Enough of that silliness. This post is all about how I maintain an ssh-agent configuration.
DISCLAIMER: Do not, under any circumstance run ssh-agent on a multi-user system, or system which you share, or on any system where you do not have 100% confidence. This configuration, along with practically every other ssh-agent configuration is subject to attack if used on a shared system. Don’t even bother posting a comment about the shared attack because I have already warned you. Now lets get to business.
There are a number of ssh-agent configuration applications for a plethora of varying systems, such as sshkeychain for OSX. Sometimes the prebuilt packages/applications/foo work wonderfully, sometimes you need your own home-brew technique. Here is mine:
I use bash, but you could use any shell to do what I am about to show you. First I start with a file called .aliasrc
This file is used to contain any aliases I might be needing, and I break it out of the normal .bashrc/.profile combo simply because I like modularity. I then create an alias called “agent”, and fill it with a string of commands to prepare the agent.
alias agent=’touch ~/.sshrc ; . ~/.sshrc &>/dev/null ; ssh-agent -k &>/dev/null ; killall ssh-agent &>/dev/null ; ssh-agent -t 28800 &> ~/.sshrc ; . ~/.sshrc ; ssh-add’
Now this may look ridiculous, but there is some method behind the madness. Let’s step through it shall we?
touch ~/.sshrc
We do this in case the file doesn’t exist in the first place. I also use semi-colons and not double ampersands because I honestly don’t care about exit codes here.
~/.sshrc &>/dev/null
We source in the contents of ~/.sshrc if any. We use the bash’s recommended redirection method of “&>” into /dev/null so we don’t get any noise with or without ~/.sshrc content
ssh-agent -k &>/dev/null
Now, if there was content inside the .sshrc, we have sourced it, and now we kill off the ssh-agent that may have been running.
ssh-agent -t 28800 &> ~/.sshrc
Now we have a .sshrc loaded with the appropriate environment variables needed to connect to other systems. The .sshrc is important as it is our config which always leads us to the right agent configuration. Notice the “-t 28800″, I use this as my 8 hour window where a loaded key will exist. I only work for 8 hours a day, so as soon as my agent stops working, it is a not-so-subtle reminder that my 8 hours is up. Also, when I leave work, it ensures that some nefarious person can’t just abuse my socket (wow that sounds nasty.)
. ~/.sshrc
We source in the configuration into our current shell, and now we have access to the socket which the agent is so wonderful for handling.
ssh-add
We finally add our private key(s). By default the agent picks up ~/.ssh/id_dsa and ~/.ssh/identity. Enter your password (you’d better have a goddamn password on those private keys) and presto, it works. Interestingly enough, if you use the same password for both your DSA key and your RSA key (if you need one at all) you only need to type your password once. Convenient eh?
[ebrewer@cohesion ~]$ agent
Agent pid 9422
Enter passphrase for /home/ebrewer/.ssh/id_dsa:
Identity added: /home/ebrewer/.ssh/id_dsa (/home/ebrewer/.ssh/id_dsa)
Identity added: /home/ebrewer/.ssh/identity (/home/ebrewer/.ssh/identity)
Now the next part is necessary is you’re you’re using more than a single shell. We need a way for every new shell we use to source in the agent environment.
Now because we may want to use both interactive and non-interactive shells to source in this agent configuration, we’ll need to modify two files, .bashrc and .profile. We append . ~/.sshrc to both .bashrc and .profile:
[ebrewer@cohesion ~]$ tail -n 2 .bashrc .profile
==> .bashrc <==
. ~/.aliasrc
. ~/.sshrc==> .profile <==
. ~/.aliasrc
. ~/.sshrc
So now, if the shell is interactive, or non-interactive, we still get the environment which we need.
Let’s see it all at once:
[ebrewer@cohesion ~]$ agent
Agent pid 9480
Enter passphrase for /home/ebrewer/.ssh/id_dsa:
Identity added: /home/ebrewer/.ssh/id_dsa (/home/ebrewer/.ssh/id_dsa)
Identity added: /home/ebrewer/.ssh/identity (/home/ebrewer/.ssh/identity)
[ebrewer@cohesion ~]$ ssh serv1 id
uid=812(ebrewer) gid=812(ebrewer) groups=0(root),812(ebrewer)