Archives For 30 November 1999

I’m using SSH’s key-based authentication to login to my servers using a SSH key pair. Of course my private key is protected with a password of its own. This has the consequence that even with key-based authentication, you still need to type a password: your private key passphrase. And you need to type it on every single connect. Although this is far more secure that having no passphrase on your private key, typing it so many times is a bit over done.

In this blog I’ll show you how to setup a system where you enter the passphrase only once per day when you start a new terminal session. For me this works great, as I now only type my passphrase in the morning when I login to my workstation and am able to connect password-less the rest of the day. Whenever I leave my desk, my screen is locked so no one can access my key.

Setting up key-based authentication

The first step is to generate a key pair to use.

ssh-keygen -t rsa -b 2048

The output is something like below. Enter your passphrase twice, when prompted.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/remi/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/remi/.ssh/id_rsa.
Your public key has been saved in /home/remi/.ssh/id_rsa.pub.
The key fingerprint is:
41:22:af:8b:4b:aa:94:34:a4:fa:5a:eb:91:4c:5b:5e remi@wks

The key's randomart image is:

+--[ RSA 2048]----+
|    . . .        |
|     o o         |
| .    . .        |
|o    .   .       |
|.o. o E S        |
|ooo* o           |
|.oO o            |
|.= +             |
|=o=              |
+-----------------+

To setup key-based authentication, copy your public key to the ‘.ssh/authorized_keys’ file on the server you want to connect to. You can do this by using ‘ssh-copy-id‘. You need to have access to the user account you want to connect to because you need to type its password to authenticate the copying.

ssh-copy-id -i ~/.ssh/id_rsa.pub user@server

You can now login to this server by typing only the passphrase of your private key, instead of typing the user account’s password.

Using ssh-agent to manage private keys
When you want to take this to the next level, you can use ‘ssh-agent‘ to manage your SSH keys. This program is started at login and remembers the keys you add each session. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using SSH.

The idea is that the agent is run in the user’s local PC, laptop, or terminal.  Authentication data need not be stored on any other machine, and authentication passphrases never go over the network. However, the connection to the agent is forwarded over SSH remote logins, and the user can thus use the privileges given by the identities anywhere in the network in a secure way.

To add a key, run ‘ssh-add‘ and type the passphrase of your private key. This is needed only once per session. After you’ve added your key to ‘ssh-agent‘, you should be able to SSH to the local machine without entering a password. This is more secure than a key pair without a passphrase because whenever your key gets lost, one still needs to type your passphrase to get access.

Use case
At work, I SSH to a central server from which I can access all the other servers. My public key is distributed to all servers, my private key is on my workstation. Now, for secure password-less logins to work, I need to be able to access my local ssh-agent from this central server. When you SSH to your server as I describe above, you don’t have to type the passphrase. When you have a look at the environment variables, you’ll notice SSH_AUTH_SOCK is set. This variable holds the path to the socket connecting to your ‘ssh-agent‘ running on your local machine. Authentication is now done this way!

Getting this to work with GNU screen
There’s a little problem when using this technique with GNU screen. When you reconnect to a running screen session from another location, the environment variable inside screen is not updated and so you need to type the password for your private key on each connect again. I found this post that describes a solution, which I further enhanced to make it work correctly for me:

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)

This one-liner looks for the most recent ssh-agent socket, owned by the current user and sets the SSH_AUTH_SOCK environment variable to this socket. You can now use this socket again to authenticate to your locally running ‘ssh-agent‘.

To make this a little easier, I added this scrip ‘update-ssh-agent-socket.sh‘ on my home directory on the central server (also available on github):

#!/bin/bash

echo "Updating ssh-agent socket environment.."
echo "Current value:  $SSH_AUTH_SOCK"

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)

if [ $? -gt 0 ]; then
 echo "ERROR!"
 exit $?
fi

echo "New value:  $SSH_AUTH_SOCK"
echo "All done!"

Run it like this to use the most recent ssh-agent socket (note the dot at the start):

. ~/update-ssh-agent-socket.sh

Usually I type ‘<CTR>+r update <enter>’ to quickly run this command from history. This is the quickest way I could think of to get everything working and make it easy to quickly login to our servers.

Whether you’re using Mac OSX, Windows or Linux, we’re all using a so-called “window manager”. Most are graphical user interfaces; and that’s a good thing 🙂 But as a sysadmin I need to manage many servers. Servers without a graphical user interface. So, how to handle that?

One could just ssh into a server when you need to do work on a given server. Depending on the terminal program you use, you might be able to have multiple sessions at the same time, preferably in tabs. It looks like this when 3 tabs are open:

Although this works well, it has one drawback for me: it only works on one computer. And when you turn off your computer everything is gone and disconnected. Since I’m working on multiple computers (desktop/laptop), multiple OS’es (OSX, Ubuntu) and multiple places (Work, Home), this no longer worked for me and I started looking for a better solution.

GNU Screen to the rescue! GNU Screen is a full-screen window manager, but terminal based. That is, it works in interactive shells such as a ssh session and is able to keep running while disconnected.

Starting a screen is easy:

screen -S screenname

You can attach and detach a session when needed. To detach, press Ctrl+a+d. To reattach enter:

screen -r screenname

This means that no matter on what computer I login, on any place, I always am able to attach a running screen. It looks like this:

Note the bar at the bottom where the tabs are. You can even give them a name!

GNU Screen can be a bit obscure to configure. After googling a lot and some help from co-workers, I have now configured GNU Screen as you can see on the above image. Configuration is read from the .screenrc file in your homedir. In the image above you can see my .screenrc file.

Commands in GNU Screen are all prefixed by a control command, the default is Ctrl+a. This means that all commands you type will be entered in the terminal you’re connected to, except commands followed directly after you press Ctrl+a. In the manual page you’ll find C-a, which is short for Ctrl+a.

When you want to create a new tab, enter Ctrl+a+c. To change from one tab to the other, you press Ctrl+a+2 to go to tab #2. Ctrl+a+spacebar brings you to the next tab. To name that tab, enter Ctrl+a+A, etc. It takes a bit of time to get used to it, but for me it works very well.

GNU Screen is a window manager, so apart from multiple tabs, you can even split the window to host multiple screens next to each other. To split vertically you enter Ctrl+a+|. Ctrl+a+tab brings you to the newly created space. You then create a new tab there, like Ctrl+a+c. It looks like this:

Like I said, Ctrl+a+tab switches between the left and right screen. In each you can call any tab that is below with Ctrl+a+tabnumner, or toggle between them using the spacebar.

Need to go away and want to protect your screens? Enter Ctrl+a+x and you’re screens will be locked. You need to enter the password of the connected user to unlock.

This is just a quick introduction of what is possible with screen. Have a look at the man page:

man screen

or use Google to get some more configuration examples. Have fun!