pam_ssh

Ages ago, I read or saw something about using your SSH passphrase to log in to your system. Seemed like a good idea, but I never got around to implementing it. One of the methods available is a PAM module called pam_ssh. I just gave it a test on a Ubuntu Gutsy system, and it works surprisingly well (Edit: except for GNOME integration…).

On my Gutsy system it was a simple apt-get install libpam-ssh to install (it’s in Universe). Once installed, you need to enable it by changing your PAM configuration. The package provided a couple of sample files in the PAM configuration directory, pam-ssh-auth and pam-ssh-session. You can take these files and copy them into the relevant part of your config.

For the “auth” section I elected just to add the right line to config-auth. What is the right line for you depends on whether you want to still prompt for the Unix password or not (some folks seem to want to use pam_ssh as a supplementary login, a bit like two-factor authentication). For me I wanted to be able to log on with either SSH passphrase or Unix password, so I added a new line like this:

auth sufficient pam_ssh.so

and changed the “pam_unix” line to look like this:

auth sufficient pam_unix.so try_first_pass nullok_secure

The important change is to make sure that “required” on the pam_unix line is change to “sufficient” — this ensures that login can proceed with either the correct passphrase or the correct password.

For the “session” section I simply added the line as suggested by the package maintainers:

session optional pam_ssh.so

With PAM modified I jumped to a virtual console to try a TTY login:

Ubuntu 7.10 columbia tty1

columbia login: vicc
SSH Passphrase:

I entered my passphrase, and was warmly greeted with a command prompt. Hooray! The further test was yet to come…but it passed with flying colours. The ssh-agent that PAM started for me seemed to work a treat, as I was able to login to my servers without password or passphrase prompts.

Now to try a GDM login. I was expecting that there would be a problem with the ssh-agent automatically started by the GNOME login process. However, I was pleasantly surprised to find that GNOME didn’t start another ssh-agent, and my SSH logins from gnome-terminal were again password-prompt-free!

I tested to make sure that logins worked with either passphrase or password, and they do — the only difference is that (obviously) the SSH key is not added to the running ssh-agent when the password is used to log on instead of the passphrase.

I made one minor change from my first trials. I found that the “SSH Passphrase” prompt I saw on the console login also appeared on the GDM login panel. I looked cool to me, but since the machine I was using to test is my wife’s laptop I figured that I had better make the change as transparent as possible. So, I reversed the order of the “auth” lines to make pam_unix.so appear first. I had placed pam_ssh.so first originally in order to make sure that SSH was tried first, but it doesn’t make any difference to the results… and since PAM displays the prompt text from the first module in the order[1], putting pam_unix.so back to the top of the list gives a “normal” login box.

Once you’re logged on, if you made the PAM change as shown to the common config files (on Ubuntu, the common-* files, on others it may be system-auth for example) you can continue to use either password or passphrase for things like sudo prompts and screen saver unlocks. If you included the change in only a specific PAM config, your ability to use the SSH passphrase applies only to that application[2].

I’m keen to try this out on other systems, if only to eliminate the additional “ssh-add” run I currently have to do to get my key into an agent. I’m also keen to try it with KDE to see if it also doesn’t start its own ssh-agent.

While this module seems to work really well, you may have to check a couple of things for yourself before using it. One is that the project pages on Sourceforge appear to be dead: the last released version was in 2004 and there has been no developer response on the open bugs in the tracker. Secondly, while I had no trouble finding Ubuntu packages, a Gentoo ebuild, and documents about its inclusion in OpenSUSE/SLES, if you use RHEL I don’t believe it’s in a standard repository (in Fedora it’s in Fedora Extras which I think doesn’t bode well for RHEL).

Lastly, and probably the most serious point, is that if you decide to use pam_ssh and your current SSH key has a blank passphrase you should think VERY seriously about setting one. If you use your blank-passphrase key to log on to your computer, you are giving free access to anyone who walks up to your computer and enters your username — not only to that computer, but to every other computer that your SSH key provides access to. Admins of multi-user systems that use pam_ssh should make sure that “nullok” or “nullok_secure” doesn’t appear on the module line that prompts for the password, to ensure their system doesn’t create the opening for an exploit. Also, organisations that use SSH keys for authentication need to give some thought to either centralised generation of SSH keys for staff, or testing/verification of passphrase strength.

Despite the negatives, I’m impressed by pam_ssh. It’s easy to set up — it’s taken me longer to write this blog post than get the module working! — and it works well.

[1] When use_first_pass is coded on second and subsequent “auth” lines, those modules will never prompt for a password themselves. With try_first_pass, a subsequent module might generate a prompt if the password that filters down is not correct and the module wants to get a new password to try.

[2] This page has an example of using pam_ssh for XDM only, by editing the PAM config for XDM only.

Edit: Turns out that by using “sufficient” in the PAM “auth” config things break. I was using sufficient as a short-circuit to avoid having to enter both SSH passphrase and normal password (for the case where the passphrase is different from the password). I ASSuMEd that all the PAM applications had no additional auth settings after the inclusion of config-auth, but I was wrong: the PAM setup for GDM has the config that brings in pam_gnome_keyring (the module that automatically unlocks the GNOME login keyring). By using “sufficient” in config-auth for the pam_ssh and pam_unix modules, the pam_gnome_keyring module doesn’t get invoked.

I could change “sufficient” to “required” again, but this will break (preventing an otherwise valid login) in the case where the user has no SSH key. Forcing all users to create an SSH key would get around this; possibly not hard to automate at userid creation time, but tedious for those with existing IDs.

What I think I need is something like the difference between “required” and “requisite”. Both “required” and “requisite” modules have to return ok in order for the entire stack to return ok, but if the module returns not-ok “required” allows subsequent modules to be executed whereas “requisite” exists immediately. “sufficient” seems to be like a kind-of affirmative “requisite”; I need an equivalent to “sufficient” that will pass control to later modules but not consider the failure of a later module as failure of the stack. I’m pretty sure I can do this with the extended control syntax but it might take some mucking about.

I also feel the need to restate something I mentioned in the original post about centralised generation of SSH keys. Much of the advice about using SSH keys for logging on to systems is written from the user perspective, and goes along the lines of “generate your own key, so that only you have the private key and no-one else has a copy”. I agree with this (and would fight for it) as a user of SSH, but as a system admin for systems that allow login via SSH key I tremble at the thought that my users might have SSH keys with no passphrase.

This is one of those areas where trust and responsibility are required on either side: sysadmins must trust their users not to do stupid things, and users must not abuse that trust by acting irresponsibly when creating keys. In my opinion as a sysadmin (and part-time commentator on things security), the convenience of interactive login using SSH keys is a privilege rather than a right, to be withdrawn if necessary to maintain the integrity of the system and the network.

I accept that SSH keys with no passphrase are a necessity for some system automation tasks. That’s why I said “interactive” in my previous statement. Enforcement of a good passphrase for a key used for interactive logins though is tricky. A modification to pam_ssh, to reject the use of an SSH key with a weak or empty passphrase — kind of a built-in pam_cracklib — might be one way. Regular sweeps of user home directories to look for keysets with no passphrase might be another (be careful to update any Acceptable Usage statement or equivalent, to ensure your users know upfront that they’d be subject to this however). It might just be as simple as making sure “nullok” is not coded for the pam_ssh module, as I mentioned originally.

Leave a comment