When you login via SSH with agent forwarding enabled, the SSH server creates a socket in /tmp/ssh-[HASH]/agent.[PID]. This allows SSH sessions on the remote host to access your agent back on your workstation. Commands that use the agent, like ssh, scp, and rsync, find it by reading the SSH_AUTH_SOCK environment variable.
root@server:~# echo $SSH_AUTH_SOCK /tmp/ssh-NshdZD1538/agent.1538
This path is readable only to the current user (and root, which is why agent forwarding is dangerous if you don’t trust the root users of servers you access). GNU Screen inherits SSH_AUTH_SOCK like any other process. However, what happens when you detach your screen session and logout? When you login again and re-attach to screen, SSH_AUTH_SOCK is pointing to the wrong file:
root@server:~# screen -r root@server:~# echo $SSH_AUTH_SOCK /tmp/ssh-NshdZD1538/agent.1538 root@server:~# ls /tmp/ssh-NshdZD1538/agent.1538 ls: cannot access /tmp/ssh-NshdZD1538/agent.1538: No such file or directory root@server:~# ssh localhost root@localhost's password:
I have found a number of solutions of varying complexity. But here is a simple one-liner which finds an agent socket and attaches to it. This works in the current screen session (not just new shells within that session), and you don’t have to modify .bashrc or switch to zsh to use it.
export SSH_AUTH_SOCK=$(find /tmp/ssh-* -user `whoami` -name agent\* | tail -n 1)
This finds the most recent SSH agent owned by the user, and assigns it to SSH_AUTH_SOCK. This doesn’t guarantee that you’ll attach to the socket created for your current SSH session, only the most recent one. For instance, you could login with three SSH sessions and this will find the latest one. But if you’re using screen, you only really need one SSH session anyway.
Edit 2013-01-24: Remi Bergsma has a better solution. The following always takes the most recent SSH agent socket:
export SSH_AUTH_SOCK=$(find /tmp/ssh-* -user `whoami` -name agent\* -printf '%T@ %p\n' 2>/dev/null | sort -k 1nr | sed 's/^[^ ]* //' | head -n 1)