Archive
Integrating keychain with KDE
In the last post I introduced keychain
and compare it with pam_ssh
. I described some nice features of keychain
, in particular how it can use long term running SSH/GPG agents. However the explained setup is not well integrated with KDE because of the environment problem described in that post. Although KMail can be configurated to sign sent messages with GPG keys, this feature doesn’t work with keychain
out of the box. Let’s suppose that we want to sign our messages with the key 5E653DA8
-without entering the passphrase- and we want to use keychain
for managing our GPG keys. In order to get our goal we configure properly the gpg.conf
(ensuring that GPG will use the gpg-agent) file and add to our .bashrc
file a block like
eval `keychain --nogui --noinherit --stop others id 5E653DA8`
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh-gpg" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh-gpg"
fi
We restart the X session just to be sure that keychain
will add the key to the gpg-agent. Now we start KMail from the KMenu and try to send a signed message using the GPG support. The result is a dialog displaying the message “Signing failed: Bad passphrase”. The reason, as you can guess, is that the environment variables that keychain
uses to expose the GPG agent are not known by KMail (in fact they are not available to KDE). This can be fixed in several ways. We can launch KMail via command line from a shell running keychain
. But we prefer to launch it from the KMenu so we discard this workaround. Other possibility is to use the KmenuEdit tool and change the launch command from KMail to something like:
GPG_AGENT_INFO=/tmp/gpg-xJRtSl/S.gpg-agent:2249:1; kmail
(of course we get the GPG_AGENT_INFO value from ~./keychain/${HOSTNAME}-sh-gpg
). But this doesn’t work if we use KMail as a component of Kontact. We can try to do the KMenuEdit trick with Kontact but then KMail will show us again the error message if we try to sign a message (it seems that Kontact doesn’t pass the environment to the KMail plugin).
The proper way to deal with this problem is to use the ~/.kde/env
folder, of course. After all is a environment problem. So we put the following script in this folder:
#!/bin/sh
eval `keychain --nogui --noinherit --stop others`
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh-gpg" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh-gpg"
fi
This way the environment variables setup by keychain
will be available to the KDE. Now we can start KMail in every possible way and we will be able to send signed messages without entering the passphrase (we may need to adjust the ttl of the passphrase to a value suitable for our needs. This change can be done in the gpg-agent.conf
file).
Single sign-on: keychain vs pam_ssh
As an unexpected consequence of the previous post about single sign-on in kdm
via pam_ssh
I met keychain
. It is a nice tool for dealing with both SSH keys and GPG keys. Its main goal is to share a unique ssh-agent between logins. In this post I’ll describe briefly some nice features of keychain
and will explain how it can be used for getting single sign-on. As usual, everything shown here has been done on a (testing) Debian box with KDE SC4.
Before starting I assume that your /etc/pam.d/kdm
is not using pam_ssh
, that OpenSSH is properly installed in your system and you have created a RSA key. In your ~/.bashrc
file you have added the line
eval `keychain --nogui id_rsa`
If you restart your X session -so that current ssh-agent and gpg-agent will be killed and new agents will be created during the X session startup sequence- and open a konsole
you’ll see something like:
The already running agents are, by default, inherited by keychain
. Then it uses ssh-add
to add the SSH keys specified in the command line to the ssh-agent, and set up the shell environment so that ssh
can find the running agent. Because this is the first time we login in this system, the ssh-agent doesn’t know the required SSH keys and we’ll be prompted for a passphrase. If the supplied passphrase is correct then the SSH key will be added to the ssh-agent. If we want to add more identities we can do it via ssh-add
command.
Your ~./keychain
directory is now populated with the files initialised during the keychain
startup (see the above screenshot).
Let’s suppose you start a new konsole
(or whatever terminal emulator you like). It doesn’t matter if it is a subshell of the current konsole
or not. The .bashrc
file will be sourced and keychain
executed allowing you to reuse the running ssh-agent so the SSH key added in the first opened shell is available to this new shell too:
Things get interesting when you want to use ssh
in situations in which the environement needed by the ssh-agent (SSH_AUTH_SOCK and SSH_AGENT_PID variables) is not known by the shell. Normally you would need to start new agents. But keychain
solves this problem in a clever way: the required environment is described in the files under .keychain
and those files can be sourced, exposing the environment to the shell. Let’s see some examples.
You will face the environment problem if you want to run ssh
commands in a non interactive shell, for instance in cron jobs. A simple working example of a cron job (assuming that your job is a bash-like script and the the job will be run by the user running the agent) follows:
#!/bin/sh
source /home/vmas/.keychain/rachael-sh
ssh vmas@a_remote_server "ls -l" >> ~/output.txt
As an alternative you can do:
#!/bin/sh
eval `keychain --noask --eval id_rsa` || exit 1
ssh vmas@a_remote_server "ls -l" >> ~/output.txt
Other example. If you connect remotely (for instance via ssh
) to your X session you will see something like:
As you can see, the problem is fixed by sourcing the appropriate file.
As a last example, you can login in a virtual console (for instance tty3 via Alt+Ctrl+F3). You will be presented with the usual keychain
stuff. However, no identities will be added to the ssh-agent due, one more time, to the environment problem. So the ssh-agent -l
command will display the message:
Could not open a connection to your authentication agent.
This problem is fixed again by sourcing the .keychain/${HOSTNAME}-sh
.
You can make things easier adding the next lines to your .bashrc
, after the line calling keychain
. They remove the need of explicitly sourcing files in interactive sessions:
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh"
fi
Last but not least, keychain
can provide you with long term running agents (one of my favorites features). Until now we’ve launched keychain
in a way that inherits the agents provided by the X session. It means that if we restart that session the agents will be killed and created again so keychain
will use a new pair of agents every time an X session starts. We can force keychain
to keep running the agents used the first time it was invoked. In order to do that we change our .bashrc
replacing the old keychain
invocation with this one:
eval `keychain --nogui --noinherit --stop others id_rsa`
meaning that keychain
will not inherit the agents started by the X session (in fact they will be killed). Instead keychain
will use its own agents.
In summary, we can say that using keychain
we’ll have a unique, long term running, ssh-agent shared between user logins instead of a ssh-agent per login and we’ll be able to use SSH keys in non-interactive sessions too. All the examples above use SSH keys but keychain
also supports GPG keys.
Even more, we can use keychain
to get single sign-on and a unique ssh-agent shared between logins all at once. Simply add the following lines to your .bashrc
:
eval `keychain --nogui --noinherit --stop others id_rsa`
if [ -f "${HOME}/.keychain/${HOSTNAME}-sh" ]; then
. "${HOME}/.keychain/${HOSTNAME}-sh"
fi
This is an interesting combination. Now the very first time that you login in a X session, you will have to authenticate twice: first with your regular password in order to start the session, and then with your passphrase (required by keychain
). But from now on every time you restart your X session you will enjoy a nice single sign-on using just your regular password (something I’ve not been able to do with pam_ssh) plus the flexible management of SSH/GPG keys provided by keychain
.
Single sign-on with kdm for Debian via pam_ssh (III)
In my previous post I thought I got pam_ssh and gpg-agent working together in a seamless way. As Sheldon Cooper would say, “In the world of emoticons, I was colon capital D”. But although all configurations included there worked for me like a charm, they didn’t work for Ivan. Indeed things worked for me better than I expected: when looking for the reasons of Ivan’s problems I realized that I could remove any reference to pam_ssh from my /etc/pam.d/kdm
file, start a new X session using my regular password for login and still have my SSH keys added to the agent! Obviously it was all a mirage. I wasn’t aware that a ~/.gnupg/sshcontrol
file containing references to all my SSH keys was living in my system. It seems that due to this file the SSH keys were automatically added to the agent every time I started a X session, because ssh-add -L
always returned a list of keys, even when I removed every pam_ssh reference from /etc/pam.d/kdm
.
When I removed the sshcontrol
file the inconditional addition of SSH keys went away. So let me start again from the beginning. At the moment we forget about the gpg-agent. The following configurations work for me using the ssh-agent:
auth required pam_ssh.so
#@include common-auth
…
@include common-session
session optional pam_ssh.so
This config forces me to authenticate with my passphrase. The SSH keys are then added to the ssh-agent and I can use them during my X session without entering the passphrase. So far so good.
@include common-auth
auth optional pam_ssh.so use_first_pass
…
@include common-session
session optional pam_ssh.so
With this config I can login using my password. But my SSH keys are not added to the ssh-agent. However the README.Debian, in the paragraph talking about this configuration says:
“By thus adding ssh-auth after common-auth, ssh-auth can use the user’s
password to decrypt the user’s traditional SSH keys (identity, id_rsa,
or id_dsa)…”
So, if I understand it properly, pam_ssh should be able to add my SSH keys to the agent when I authenticate using my password. But it doesn’t (unless that the password equals to the passphrase, which doesn’t make sense for me) and I feel a little bit disappointed. The same happens with the next configuration:
auth sufficient pam_ssh.so try_first_pass
@include common-auth
…
@include common-session
session optional pam_ssh.so
With this config I can login using my passphrase or my password. If I use my passphrase then my SSH keys are added to the ssh-agent but again if I use my password they are not.
And now let’s consider the replacement of ssh-agent with gpg-agent. I’ve setup my system as follows in order to use only the gpg-agent (detailed information can be found, for instance, here) :
– in /etc/X11/Xsession.options
I’ve commented out the line use-ssh-agent
– in /etc/X11/Xsession.d/90gpg-agent
I’ve added the --enable-ssh-support
option to the
STARTUP line
– I’ve disabled ssh at the gnome-keyring:
$ gconftool-2 --set -t bool /apps/gnome-keyring/daemon-components/ssh false
However, all the above /etc/pam.d/kdm
configurations fail with this setup. The “session optional pam_ssh.so” line always start a ssh-agent and SSH keys are never added to it. If I remove that line the ssh-agent is not run but SSH keys are not loaded into the gpg-agent so pam_ssh doesn’t appear to be compatible with gpg-agent. If any of you know how to make them work together, please, let me know. In the meantime I’ll have a look to alternatives to pam_ssh: keychain, libpam-gnome-keyring… As usual, suggestions are welcome 🙂
Single sign-on with kdm for Debian via pam_ssh (II)
In my previous post I gave a first example of single sign-on using kdm and pam_ssh on a Debian box. Now I’ll provide a more flexible way for achieving the same goal: you will be able to use your passphrase or your password in order to authenticate and pass your OpenSSH keys to an agent. In the meantime I’ll also replace the ssh-agent (that pam_ssh uses by default) with the gpg-agent because it is more flexible and provides additional functionality (it can manage both OpenSSH keys and GPG keys). I assume the gnupg-agent package is installed in your system.
In the example given in my previous post we can see the line:
session optional pam_ssh.so
This line forces to use a ssh-agent during the X session.
On the other hand we know that during the start sequence of kdm, the system Xsession
files (i.e. /etc/X11/Xsession*
files and files under /etc/X11/Xsession.d
directory) are called. In particular the 90gpg-agent
file is sourced. As a result, a gpg-agent will be launched and it will be alive until the X session ends. So eventually we’ll have both a ssh-agent and a gpg-agent running during the X session. However the gpg-agent can be used as a drop-in replacement for the ssh-agent if we pass the --enable-ssh-support
to it. So we do the following:
* comment out the session optional pam_ssh.so
line in the /etc/pam.d/kdm
configuration file
* edit the /etc/X11/Xsession.d/90gpg-agent
file and add the --enable-ssh-support
option to the line where the agent is launched. We’ll have something like
STARTUP="$GPGAGENT --enable-ssh-support --daemon --sh --write-env-file=$PID_FILE $STARTUP"
And now for the authentication part. It will be short. I’ll simply give a couple of useful configurations of the /etc/pam.d/kdm
file. First, if we want to authenticate only with our password and load our SSH keys into the gpg-agent we can do:
auth @include common-auth
auth sufficient pam_ssh.so
We can use the optional
control instead of the sufficient
one. The order of the lines is not important (it can be reversed). This same result can be reached if we pass the use_first_pass
argument to the pam_ssh module:
auth @include common-auth
auth sufficient pam_ssh.so use_first_pass
And second, if we want to authenticate with our passphrase or our password and load our SSH keys into the gpg-agent we can do:
auth @include common-auth
auth sufficient pam_ssh.so try_first_pass
Again we can use the optional
control too. And again the order of lines doesn’t matter.
As a final remark I’d like to say that a configuration like:
auth @include common-auth
auth required | requisite pam_ssh.so use_first_pass | try_first_pass
will always fail and will lock the access to our system via kdm.