A while back on StackOverflow, I asked this question about ssh-agent and crontab. I have a similar question now about ssh-agent and screen on linux systems.

So, on my Mac, ssh-agent launches at system startup, so it's always available to me. I think it would be true under my linux (redhat el5/fedora) if I were using X-Windows. However, this is a remote server machine and I'm always logging in via ssh.

I would love to have ssh-keys set up properly so I didn't have to enter my password multiple times during an svn update or commit. I'm happy to type in my passphrase once per session, and I discourage our team from having password-less ssh-keys.

For a brief shining moment, it seemed like doing "eval `ssh-agent -s`" in my .bash_profile, paired with a command to kill the ssh-agent when I logged out, would work. However, we make heavy use of screen in order to manage long-running interactive programs and development environments. If you start & stop ssh-agent as I just described, then it gets killed when you exit out of the terminal, and the screen's sub-sessions which used to be referring to that ssh-agent instance are abandoned.

So ... how can I be a console user, who uses screen, who uses a password with his ssh-keys, who doesn't have to type in the passphrase constantly?

link|improve this question
feedback

4 Answers

Can you launch ssh-agent from an initscript instead of .bash_profile? For instance, I might put

su -c 'ssh-agent -s > ~/.ssh_agent_env' myusername

in the appropriate part of /etc/conf.d/local, although RHEL/Fedora probably uses a different system. As you pointed in your comment, terminal sessions will need to be able to connect to the agent, which is why that command creates the file .ssh_agent_env in the user's home directory. Then you can add

[ -f ~/.ssh_agent_env ] && source ~/.ssh_agent_env >/dev/null

in .bash_profile.

Another thing you could do is put the following in .bash_profile

ps -U myusername | grep -q ssh-agent || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

which will start ssh-agent only if it's not already running. Then you don't have to kill it.

As a slightly different alternative to the second suggestion, instead of checking for the existence of an ssh-agent process, you could check for the existence of the file ~/.ssh_agent_env,

[ -f ~/.ssh_agent_env ] || ssh-agent -s > ~/.ssh_agent_env
source ~/.ssh_agent_env >/dev/null

If everything works properly, there shouldn't be any significant difference between the two ways.

link|improve this answer
The initscript idea is interesting -- basically, just start it at system startup for all users who want it? That could work. We don't have a lot of users who would care. Whether or not that's significantly better than not having a passphrase at all is an interesting question, since I suspect that means you'd only have to enter it once per machine restart. Hmm. Both that and the second suggestion rely on new terminal sessions being able to connect to the ssh-agent if it's already running. I'm not completely sure it's that easy, but I haven't tried yet. Thanks for the ideas! – khedron Jul 1 '10 at 2:44
@khedron: Yep, but you'd have to put one line in /etc/conf.d/local (or your equivalent) for each user who uses the agent, to launch a separate ssh-agent process per user. If, as you say, you don't have a huge number of users, that wouldn't be too bad. You raise a good point (which I forgot to consider) about terminal sessions attaching to the agent; see my edit to the answer. – David Zaslavsky Jul 1 '10 at 5:57
feedback

A better approach is to use ssh agent forwarding (-A option). This allows the person using ssh to use keys from the ssh-agent running on the machine they are coming from, presumably the workstation they are actually sitting at.

link|improve this answer
feedback

to follow up on ssh agent forwarding, you'll find that by default the forwarded ssh credentials won't be available to your screen session once you log out, log back in, and re-attach to your sesssion.

You can get around this, though, by having screen set the SSH_AUTH_SOCK environment variable to something well-known, and having that well-known location be updated to your current auth socket.

I use this shell function to re-enter screen and fix the ssh auth sock:

function sr () { 
    if [ ${+STY} = 1 ] ;then 
            echo already in screen\!
    else
            if [ "${SSH_AUTH_SOCK}x" != "x" ]; then
                    if [ ! -d /tmp/screenssh ]; then
                            mkdir /tmp/screenssh 
                    fi
                    rm -f /tmp/screenssh/socket
                    ln -s $SSH_AUTH_SOCK /tmp/screenssh/socket
                    echo $REMIP > /tmp/screenssh/remip
            fi                
            screen -DR
    fi
}

and I have this in my .screenrc:

setenv SSH_AUTH_SOCK /tmp/screenssh/socket

Hope this helps.

link|improve this answer
feedback

Check out keychain. It does all of the above. Look especially at the --clear and --timeout options.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.