Solution 1:

With the following setup, you won't need any wrapper for invoking screen. Moreover, it avoids using /tmp (with the consequent security risks).

  1. Ensure you have an ~/tmp directory:

    mkdir ~/tmp
    
  2. Add to .screenrc the following line:

    setenv SSH_AUTH_SOCK "$HOME/tmp/ssh-agent-screen"
    
    • This ensures that inside screen, ssh looks for the socket always in the same location, rather than a changing path.
    • You must use setenv whichever shell you use, since it's a screen and not a shell command.
  3. Add to .bash_profile the following line:

    [ -n "$SSH_AUTH_SOCK" ] && [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ] && ln -sf "$SSH_AUTH_SOCK" "$HOME/tmp/ssh-agent-screen"
    
    • This will link from the fixed location (where ssh looks) to the real one, and must appear after starting ssh-agent.
    • Using [ -n "$SSH_AUTH_SOCK" ] will properly prevent errors when SSH_AUTH_SOCK is not set.
    • [ "$SSH_AUTH_SOCK"!="$HOME/tmp/ssh-agent-screen" ] will prevent screen sessions linking $HOME/tmp/ssh-agent-screen to itself, if screen sources .bash_profile.
  4. Instead of starting ssh-agent in .bash_profile, you can consider connecting with ssh -A (to use agent forwarding and make the remote machine use your agent).

After this setup, you can just use standard screen command. You'll only need to recreate existing sessions or manually set SSH_AUTH_SOCK inside them to the fixed location of step 2.

Credits to this website for the idea; I avoided using /tmp. This answer is similar but uses extra aliases.

Solution 2:

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.

Solution 3:

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