On Linux hosts (CentOS6), I’ve taken great care to utilize two-factor remote shell authentication and limit root access with sudo. But while SSH authentication via the Pageant agent works great for Putty on Windows, with no /etc/passwd password required, it always struck me funny that a password was still needed for sudo authentication.

If only there was a way to use the SSH key-pair to authenticate the sudo access and not require the /etc/passwd password prompt at all. There is!

Linux utilizes PAM – Pluggable Authentication Modules – which can query against a variety of authentication mechanisms and be chained to support multiple methods. The /etc/pam.d/sudo file determines how PAM methods are chained for authentication by the sudo program (you might want to also look at sudo-i, which is used for sudo with the -i option).

By default, the CentOS sudo PAM file defers to the regular system-auth methods. It might be tempting to simply edit the system-auth file to add SSH authentication for any program that prompts for a password, but I don’t recommend it. For one thing, SSH Agent Forwarding has limited use and may not be applicable to all scenarios. But more importantly, this file is auto-generated by system-config-authentication when adding LDAP, NIS, WinBind, or Hesiod (but not SSH) authentication and could be overwritten if changes are made via that program.

Note for debugging #1: while trying to make this work, you will likely have to enter your password the normal tedious way at least once. Be sure to always issue the command “sudo -K” to kill any temporary session values, or you may be falsely led to believe that SSH Agent authentication is working when it is really just the memorized regular password.

Note for debugging #2: keep a 2nd root window open while working on this. No point risking that you’ll lock yourself out while mucking with authentication internals.

Other multi-method tutorials I’ve seen made use of the “[default=ignore success=2]” entries to skip entire blocks of fallback directives, but I could never get these to work properly. In the end, I settled for a “sufficient” directive for SSH in /etc/pam.d/sudo, failing over to the regular system methods (eg /etc/passwd) if unsuccessful.

Socket To Me

The pam_ssh_agent_auth.so queries for the SSH private key and matches it to the public key in the authorized file. However, in order for this query to work, sudo must be made to pass the forwarding authenticator’s socket (used for inter-process communication) into the inherited environment.

In the sudoers file (use visudo to edit), look for the env_reset command. This clears the environment variables of the user shell before forking for an elevated root shell. You’ll note that several variables are intentionally passed forward using the env_keep directive. To this list – and before the env_reset – we need to add the SSH socket:

The Forwarding Agent

What’s that you say? You’ve reviewed your environment settings (via env or printenv) and don’t have an SSH_AUTH_SOCKET variable to pass? Totally understandable. The last step is that the SSH Agent must be configured to act as a forwarding authenticator (ie, not solely used for the initial SSH shell login).

In PuTTY’s Pageant, the forwarding is controlled under the Connection –> SSH –> Auth options.

When you check off the Use agent forwarding option, you should discover that a new shell session will have added an SSH_AUTH_SOCKET environment variable.

And if /etc/sudoers was updated correctly, a “sudo printenv” command should reflect this same (inherited) environment variable in the elevated shell.

If SSH_AUTH_SOCKET is not present in the inherited shell, sudo will not be able to query the Forwarding Agent and will fall back to prompting for an /etc/passwd password.

To test, remove your key from Pageant. sudo will prompt for your /etc/passwd password. Now add the key back to Pageant and try sudo again. This time, the Forwarding Agent will confirm the SSH public/private key pairing and not prompt for a password.

Bitvise Tunnelier is another popular SSH client for Windows, arguably better than PuTTY because of extensive port-forwarding capabilities. But I have not found an equivalent SSH Agent to PuTTY’s Pageant. (If anyone knows, please comment!)