Tuesday, March 2, 2010

Using an SSH agent for sudo authentication

I've discovered a great PAM module for using an SSH agent to authenticate the user for sudo access. I'm planning on installing it on all of my Linux servers.

To build in Ubuntu 8.04.4 LTS, you'll need to install a couple of development packages:
sudo apt-get install libpam0g-dev libssl-dev
Then download the source from

The build process is your typical "./configure; make; sudo make install" but requires a little tweeking before install. So first run
./configure; make
The manpage is NROFF formatted, but installed as a text page. To overcome this, I changed both references in the Makefile from "cat" to "man" with my favorite editor.

Additionally, the PAM modules in Ubuntu are installed in /lib/security, whereas make installs by default to /usr/local/libexec. You can manually modify the libexecdir value in the makefile, or set the variable when calling make install, such as
sudo make libexecdir=/lib/security install
I used sudo checkinstall instead in order to build a simple binary .deb file for distributing among my servers. See here for details.

Once installed, change the line in /etc/pam.d/sudo from
@include common-auth
auth sufficient pam_ssh_agent_auth.so \
auth requisite pam_unix.so nullok_secure
That allows PAM to use the SSH agent. Finally, in order to pass the agent socket to sudo, add the following line before the env_reset line in /etc/sudoers
Defaults env_keep += SSH_AUTH_SOCK
To test, you will have to be running an agent such as Pageant (part of the PuTTY tools) or ssh-agent from OpenSSH, and you will have to connect with the agent forwarding flag (-A). To verify you're reauthenticating instead of using cached sudo credentials, run
sudo -K
to clear the user timestamp. Then, run
sudo id
and check the /var/log/auth.log file for a line like
sudo[5678]: pam_ssh_agent_auth: Authenticated: `and1' as `and1' using /home/and1/.ssh/authorized_keys

Now, why did we do all of this?

Authenticating through an SSH agent means the password is never entered on the remote system. The authentication request is sent back to the originating computer running the agent. The request signed by the user's private key which is held by the agent, and then returned to the remote system to verify using the user's public key.

If the remote system is compromised, using this module will prevent the attacker from ever seeing your password while you access the system and escalate your privileges to admin.

If the PAM module is set to sufficient, it will fall back to prompting for a password. If you set it to required and remove the pam_unix.so line, it should then only allow agent authentication, much like setting "PasswordAuthentication no" in sshd_config. WARNING: I haven't verified this, so make sure you have an alternative means of gaining root access before you fiddle with it...

Once this module is in place, there is no reason to have a password on the remote account. You could set it to '*' or a long, random string and forget it. In fact, it also gives the ability to issue privileged commands remotely, such as
ssh -A myRemoteSystem sudo shutdown -r now
Note that you have to use an agent; specifying the identity on the ssh command line will not work, as the followup request from sudo will not be serviced. The -i command to ssh will only authenticate the original login request.

There is one caveat, true of all agent forwarding. If the remote system is compromised, the attacker will have access to your authentication socket as long as you're logged in. This means he would be able to connect to systems where that key is authorized using your agent forwarding socket.

You can mitigate this using OpenSSH by using the -c option to ssh-add when adding your private key. When used this way, your local system will popup a dialog asking you to authorize each use of the private key. I don't know of a way to do this with PuTTY without patching Pageant.

1 comment:

  1. many thanks Pete :-)
    I was searching for this solution a long time, and you described it wonderful.
    thanks a lot again