[debian] archive category

Manage multiple SSH private keys with IdentityFile

There are many guides that show you how to set-up your SSH client for password-less login using public-private key certificates. If you have different clients, you may have several different private keys. How can you manage them?

It was pointed out that ssh-agent and PuTTY’s Pagent can also be used to manage multiple private keys.

SSH has a per-user configuration file called ‘~/.ssh/config’ that it can use to select your private keys based on the remote user name and remote host by using wildcards. Let’s check out my ‘config’ file:

IdentityFile ~/.ssh/ids/%h/%r/id_rsa
IdentityFile ~/.ssh/ids/%h/%r/id_dsa
IdentityFile ~/.ssh/ids/%h/id_rsa
IdentityFile ~/.ssh/ids/%h/id_dsa
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_dsa

The percent-h and percent-r take the host and the remote user from your SSH user and hostname arguments. Consider this example command:

$ ssh remote_user@remote_hostname.example.com

From the example command, the SSH client would use the wildcards to seek the correct key to use:


This means that if you had two private keys that you used to access two different servers, you would arrange them as follows. The first one is arranged as follows:

$ ls -l ~/.ssh/ids/remote.example.com/remote_user/
total 16
-rw-------  1 kelvin  staff  668 Mar 24 20:09 id_dsa
-rw-r--r--  1 kelvin  staff  610 Mar 24 20:09 id_dsa.pub
$ ssh remote_user@remote.example.com
[remote_user@remote ~]$

Our second example uses a simple hostname. If a remote user is not required, you can just use the hostname:

$ ls -l ~/.ssh/ids/webby.example.org/
total 16
-rw-------  1 kelvin  staff  668 Mar 24 20:09 id_rsa
-rw-r--r--  1 kelvin  staff  610 Mar 24 20:09 id_rsa.pub
$ ssh webby.example.org
[webby ~]$

For sure, these are totally contrived examples, but you can watch the cascade yourself by adding the verbosity flag(s) to your SSH client session (this one is my client’s WebFaction account):

Trinity:.ssh kelvin$ ssh -v user@user.webfactional.com
OpenSSH_5.2p1, OpenSSL 0.9.7l 28 Sep 2006
debug1: Reading configuration data /Users/kelvin/.ssh/config
debug1: Reading configuration data /etc/ssh_config
debug1: Connecting to user.webfactional.com [] port 22.
debug1: Connection established.
debug1: identity file /Users/kelvin/.ssh/ids/user.webfactional.com/user/id_rsa type -1
debug1: identity file /Users/kelvin/.ssh/ids/user.webfactional.com/user/id_dsa type 2
debug1: identity file /Users/kelvin/.ssh/ids/user.webfactional.com/id_rsa type -1
debug1: identity file /Users/kelvin/.ssh/ids/user.webfactional.com/id_dsa type -1
debug1: identity file /Users/kelvin/.ssh/id_rsa type 1
debug1: identity file /Users/kelvin/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_4.3
debug1: match: OpenSSH_4.3 pat OpenSSH_4*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.2
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'user.webfactional.com' is known and matches the RSA host key.
debug1: Found key in /Users/kelvin/.ssh/known_hosts:41
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /Users/kelvin/.ssh/ids/user.webfactional.com/user/id_rsa
debug1: Offering public key: /Users/kelvin/.ssh/ids/user.webfactional.com/user/id_dsa
debug1: Server accepts key: pkalg ssh-dss blen 433
debug1: read PEM private key done: type DSA
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
Last login: Thu Mar 31 22:31:08 2015 from
[user@web ~]$

Tags: , , , ,

Debian 6 Squeeze and a HP Compaq DL380 G2

I was trying out the new Debian 6 Squeeze release on an old DL380 G2 and it complained about a missing piece of firmware (e100/d101m_ucode.bin). The missing code is a non-free binary-only module that you can install with firmware-linux-nonfree_0.28_all.deb. If you don’t install it then your network card won’t work.

To solve this issue, download the deb file and put it in the root of a thumbdrive. Plug the thumbdrive in the USB port at the back of your DL380 when prompted and Debian should find it if the deb-file is in the root of the drive (not buried in a folder somewhere). With this change I was able to get the network card going and it completed the DHCP set-up without further issues.

One way to avoid all this extra work is to install the OS using the installation disks that include the non-free binary modules. If you just want to get Debian running without the hassles of adding bits of non-free firmware then check out the installation media that includes the non-free firmware.

Python 2.7 on Dreamhost

Python 2.7 was released on 3 July 2010 and I wanted to use it on my Dreamhost account, but the usual installation method yields some warnings:

Python build finished, but the necessary bits to build these modules were not found:
_bsddb             _tkinter           bsddb185
bz2                dl                 imageop         sunaudiodev
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

Three of these modules cannot be installed on Dreamhost’s 64-bit Debian servers anyway and one of them is an older version of a module I am going to install:

Now, if you don’t need any of those remaining modules, then you should be able to just complete the installation and be done with it. If you want all the modules that you can get, you are in for some extra building. This post does a good job of explaining the installation of Python 2.6; mine is based on it. Let’s put the files in the following directories:

Python 2.7
Berkeley DB 4.8
Other executables
Header files
Temporary artifacts

We’ll need to push these values into the UNIX environment by using the export tool under the default bash shell:

$ export LDFLAGS="-L$HOME/local/lib -L$HOME/local/BerkeleyDB.4.8/lib"
$ export CPPFLAGS="-I$HOME/local/include -I$HOME/local/BerkeleyDB.4.8/include"
$ export LD_LIBRARY_PATH=$HOME/local/lib:$HOME/local/BerkeleyDB.4.8/lib

Next make the directories:

$ mkdir ~/temp ~/local

It’s also a good idea to check your machine (note the “x86_64” token). It should look similar to this:

$ uname -a
Linux machine #2 SMP Sat Mar 13 00:42:43 PST 2010 x86_64 GNU/Linux
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1.1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-cld --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1) 

Berkeley DB will be hooked into the installed TCL, so you should install TCL before you install Berkeley DB. Install Python last. Other than that, I don’t believe that order of installation should matter. Let’s do it!


The warning “_tkinter” indicates that the _tkinter module was not built. You will need to build both TCL and TK:

$ cd ~/temp
$ pwd
$ wget http://prdownloads.sourceforge.net/tcl/tcl8.5.8-src.tar.gz
$ tar zxvf tcl8.5.8-src.tar.gz
$ cd tcl8.5.8/unix
$ ./configure --prefix=$HOME/local
$ make
$ make install
$ cd ../..
$ wget http://prdownloads.sourceforge.net/tcl/tk8.5.8-src.tar.gz
$ tar zxvf tk8.5.8-src.tar.gz
$ cd tk8.5.8/unix
$ ./configure --prefix=$HOME/local
$ make
$ make install
$ cd ../..

Berkeley DB 4.8

The warning “_bsddb” will go away when you install version 4.8 of the Oracle Berkeley DB:

$ cd ~/temp
$ wget http://download.oracle.com/berkeley-db/db-4.8.30.tar.gz
$ tar zxvf db-4.8.30.tar.gz
$ cd db-4.8.30/build_unix
$ ../dist/configure --prefix=$HOME/local/BerkeleyDB.4.8 --enable-tcl --with-tcl=$HOME/local/lib
$ make
$ make install
$ cd ../..


Dreamhost has an earlier version of BZip2 (version 1.0.4) and no library (at least I couldn’t find one). To get the latest version:

$ cd ~/temp
$ wget http://www.bzip.org/1.0.5/bzip2-1.0.5.tar.gz
$ tar zxvf bzip2-1.0.5.tar.gz
$ cd bzip2-1.0.5
$ make -f Makefile-libbz2_so
$ make
$ make install PREFIX=$HOME/local
$ cp ./libbz2.so.1.0.4 $HOME/local/lib
$ ln -s $HOME/local/lib/libbz2.so.1.0.4 $HOME/local/lib/libbz2.so.1.0
$ cd ..

Python 2.7

You should be able to build and install Python 2.7 now, less the modules that either cannot be built on a 64-bit platform or cannot coexist with a contemporary version.

$ cd ~/temp
$ wget http://python.org/ftp/python/2.7/Python-2.7.tgz
$ tar zxvf Python-2.7.tgz
$ cd Python-2.7
$ ./configure --prefix=$HOME/local/Python-2.7
$ make
$ make install

At the end of the make process, you will see this:

Python build finished, but the necessary bits to build these modules were not found:
bsddb185           dl                 imageop         
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

As mentioned earlier, these modules are either not buildable on Dreamhost’s 64-bit machines or not compatible with the newer version of Berkeley DB.

Hooking up the new Python

You want to put the new Python 2.7 on your PATH so that bash executes it before the systemwide Python 2.5. If you don’t want to append these export statements, you can also do it via a text editor (vim, emacs, etc).

$ cd ~
$ echo "export PATH=\"$HOME/local/bin:\$PATH\"" >> .bashrc
$ echo "export PATH=\"$HOME/local/Python-2.7/bin:\$PATH\"" >> .bashrc
$ source .bashrc
$ which python
$ python -V
Python 2.7

Try it out!

Try out your new modules…at the shell prompt type “python”!

>>> import bsddb
>>> db = bsddb.btopen('/tmp/spam.db', 'c')
>>> for i in range(10): db['%d'%i] = '%d'% (i*i)
>>> db['3']
>>> db.keys()
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> db.sync()
>>> db.isOpen()
>>> import bz2
>>> print bz2.__author__
The bz2 python module was written by:
    Gustavo Niemeyer <niemeyer@conectiva.com>
>>> import Tkinter
>>> Tkinter.__version__
'$Revision: 81008 $'

Tags: ,