Friday, June 15, 2012

Using SSH public keys to authenticate SUDO

Q) Can sudo use the ssh agent for authentication instead of asking for the user's Unix

A) Yes. This entry talks about how to make sudo to use SSH public key infrastructure.

The reader of this entry is assumed to have knowledge of SSH and sudo. There could be
various motivations to use SSH public key infrastructure for sudo authentication. These
motivations are explained below in usecases section.


One of the great strengths of SSH with public-key authentication is that a user can log in
to an untrusted host without providing any sensitive data. The user provides only his
public key and a signature. Even if the remote host is compromised, the user's
authentication material is safe. Compare this to password authentication; if the remote
SSH daemon has been compromised, an adversary can obtain the plaintext password.
Any tool on the remote host which uses password authentication is susceptible to such an
attack. By default, sudo is one of those tools. Same analogy applies to a multi user

Automation at times may need sudo privileges and to run the scripts in headless mode (non
interactive mode) requires a way for sudo to work. Setting password less sudo or using
SUDO_ASKPASS are ways to use sudo to use in automation, but both the options are not
preferred solutions as they are risky.


Solution is to make use of pam_ssh_agent_auth. Which is a PAM module which permits
authentication for arbitrary services via ssh-agent. Written with sudo in mind, but like
any auth PAM module, can be used for for many purposes.

Steps to Build pam_ssh_agent_auth in Ubuntu (but can be built on many Unix systems) :
$ sudo aptitude install libssl-dev libpam0g-dev build-essential checkinstall
$ wget ""
$tar -xjvf pam_ssh_agent_auth-0.9.3.tar.bz2
$ ./configure --libexecdir=/lib/security --with-mantype=man
$ make
$ sudo checkinstall

Note : If you can get hold of suitable for you OS and ARCH, you don't
need to build one.

sudo checkinstall is an optional step. After the above steps,
should be created in the current directory as should have been copied to /lib/security.

Do the following configuration changes to make sudo to use pam_ssh_agent_auth:

Edit the sudoers (/etc/sudoers) file
$ sudo visudo

Add the line "Defaults env_keep += SSH_AUTH_SOCK" if it doesn't already exist and
delete the line "Defaults reset_env", if it exists.

Edit /etc/pam.d/sudo
$sudo vi /etc/pam.d/sudo

and add the line with the quotes
"auth sufficient /lib/security/ file=~/.ssh/authorized_keys"
directly above
@include common-auth
@include common-account

Make sure you have generated your SSH keys, if you haven't ,generate them using ssh-keygen
command with empty paraphrase. Create authorized_keys file in ~/.ssh directory.
$cd ~
$mkdir .ssh (if required)
$ssh-keygen (if required)
$cd .ssh
$cat >> authorized_keys
$chmod 600 authorized_keys

Hang on, you are almost there. Now you have all the pieces to make sudo work with SSH keys.
Follow the below steps to see that sudo works with SSH keys (will not for password).

1) Make sure there is only ssh-agent running for that user. You can run multiple of them
but then you have to know which one to use. I used  keychain
( to simplify interacting
with ssh-agent. Run either ssh-agent or key-chain and export SSH_AUTH_SOCK and SSH_AGENT_PID
environment variables.
    1.1 With keychain
        $eval `keychain --eval` (this runs ssh-agent as well as exporting variables)
    1.2 with ssh-agent
        $eval `ssh-agent`
2) Register your SSH keys with the ssh-agent

Now try "sudo whoami" and it should say root with out asking the password.
$sduo -K (to force reauthentication)
$sudo whoami

If you are not prompted for password and you got "root" as output, you are all set!!!