Previously posted on blog.labrat.info on February 25, 2010

Screen has become a great tool in my arsenal. I use it every day. It’s a great way to maintain state. Log into a server, start up screen and do some work. Detach from the screen and leave. When you have time to come back reattach to the screen and all your work is there waiting. There’s tons of tutorials out there to teach you how to use it. Basic screen is out of the scope of this.

As a sysadmin it’s nice to be able to quickly log into the machine and do what you need to do and then log out. Since I’ve been using screen what I’ve done is start up a new screen window, log into the machine and then rename the screen so I know which windows is attached to which machine. This is fine until the machine with the screen reboots. Then I have to remember which machines I had logged into and log in to all machines again. It would be great to create a script that could take care of starting screen, creating windows for each server and starting an SSH session automatically.

Part of the trick to this is being able to create an ssh-agent session that can be shared between all the windows. To do this they all have to share the same authorization socket. The authorization socket location can be set by the SSH_AUTH_SOCK environmental variable. The first step is to set this variable inside screen. To do this add the following three lines near the top of the ~/.screenrc file.

# ssh-agent
unsetenv SSH_AUTH_SOCK
setenv SSH_AUTH_SOCK "$HOME/.ssh-auth-sock"

The next step us to create a small script that will be called by screen and will start the ssh-agent along with all the SSH sessions to all machines. It has a small trick to make sure all the SSH sessions connect after the ssh-agent has been started. I put the following script in ~/bin/screen-init.sh.

#!/bin/bash

function ssh_shell {
    sleep 10
    ssh "$1"
}

screen -t ssh-agent 0 ssh-agent -a $SSH_AUTH_SOCK $SHELL
screen -t Server1 ssh_shell server1.host.stuff
screen -t Server2 ssh_shell server2.host.stuff
screen -t Server3 ssh_shell server3.host.stuff

The small ssh_shell function has a sleep before trying to connect to the server. This is to give you enough time to start and tell the ssh-agent to accept all your SSH keys. The first screen line will start a window by calling ssh-agent with the SSH_AUTH_SOCK we set before in .screenrc and then dropping down to a shell. The windows will be called “ssh-agent”. After that, every line will start a new window, sleep for 10 seconds and then try to ssh into the server specified. For this to work screen has to be called with the script as a parameter. Once screen starts you have 10 seconds to get all your keys in ssh-agent before the sessions start trying to connect.

#> screen -A ~/bin/screen-init.sh
#screen> ssh-add
Password:
#screen> 

If you ctrl-a “ and move to another server you should see you are not logged in to that server automagicaly!