Skip to content

SSH power unleashed – Part 2: use SSH agent as an authentication provider

In the first part of this serial posts I’ve introduced SSH key and agent and their applications. In this one I’m going to take it further, let’s see how we can make use of SSH agent authentication to make things easier in other situations while still keep it secure.

A pain point of sudo

Sudo, the so commonly used tool that probably don’t need any introduction here. I find myself in dilemma while tryhing to keep secure AND convenient at the same time. By default, when you setup sudo to allow some user to own the root power, you ask him to authenticate himself by enter this password when he fires up sudo. It is usually set up by putting a line as below in /etc/sudoers file.

username        ALL=(ALL)       ALL

People like me may set up password very long so every time I ran sudo I have to type in that in a finger dance. Yes I’ve mentioned that in the last post already and I solved that by using SSH agent. Hint: it is going to help us again this time.

Some people trying to solve this problem by setting up sudo like below instead.

username        ALL=(ALL)       NOPASSWD: ALL

The NOPASSWD part makes sudo skip asking password for username when he issues sudo command, and grant him the root power silently. So as you already find out, although it is convenient, it is a huge risk – if the user accidently got hacked, the hacker is able to get root power like a piece of cake.

Let’s take the SSH agent authentication method further beyond just SSH connection

So you may wonder as I had before – we already have a way to authenticate ourselves to SSH command via the SSH agent, and skip password input in a secure way. Can we make use of that same facility on sudo? The answer is yes!

First we need to install the great pam_ssh_agent_auth package. This package provides the capability to authenticate via SSH agent in the PAM framework(I will cover that detail later in this post). This package is included in the repository of many Linux distros so just install it with your favorate package manager. As what I did on a CentOS server:

yum install pam_ssh_agent_auth

Then put a line in the file /etc/pam.d/sudo

#%PAM-1.0
auth sufficient pam_ssh_agent_auth.so file=~/.ssh/authorized_keys          <--- This is the line to put in
auth       include      system-auth
account    include      system-auth
password   include      system-auth
session    optional     pam_keyinit.so revoke
session    required     pam_limits.so

Make sure the line is located above other “auth” lines, like what I did in above example. This line tells PAM that when sudo is trying to authenticate a user, first try to use the pam_ssh_agent_auth module. If it succeeded, the user is authenticated and get sudo power. If it failed, try the next authentication method, the global system-auth method, which in most case would be asking for password.

The file=~/.ssh/authorized_keys parameter in that line tells the pam_ssh_agent_auth module to verify the user SSH agent against the public keys stored in his own home directory. You can also change that to some other file path, say, if you would like sudoers to authentication against an admin managed dedicated SSH key for sudo.

Once it is done, follow the same instructions in the last post regarding SSH agent and agent forwarding. Then you can sudo on a remote server without needing to input the password, while if you accidentally get hacked, the hacker won’t be able to sudo as he don’t have your SSH key.

The magic behind

So what happens behind all this? The major parts in this magic are: SSH agent, PAM, and the pam_ssh_agent_auth module.

I have already talked about SSH agent so I won’t repeat it. The pam_ssh_agent_auth module connects PAM and SSH agent. The key here is PAM.

What is PAM? PAM means Pluggable Authentication Modules. Here is what PAM says about itself in it’s man page.

Linux-PAM is a system of libraries that handle the authentication tasks of applications (services) on the system. The library provides a stable general interface (Application Programming Interface - API) that privilege granting programs (such as login(1) and su(1)) defer to to perform standard authentication tasks.

The principal feature of the PAM approach is that the nature of the authentication is dynamically configurable. In other words, the system administrator is free to choose how individual service-providing applications will authenticate users. This dynamic configuration is set by the contents of the single Linux-PAM configuration file /etc/pam.conf. Alternatively, the configuration can be set by individual configuration files located in the /etc/pam.d/ directory. The presence of this directory will cause Linux-PAM to ignore/etc/pam.conf.

My own sumary for PAM:

  • PAM provides a system with plugin capability, which is easy to extend for both developers and system admins. A plugin is called a module.
  • PAM provides a universal way for applications to use different methods for authentication provided by different modules. The application don’t need to change if the system provides password authentication in the beginning while later adds fingerprint authentication.
  • Each authentication method provided by PAM can be enabled / disabled / configured individually without interfering each other.
  • Different modules could be linked to gether to provide parallel or serial path of authentication flow.

PAM is a fundamental part of Linux system for many years. And many modules have been developed in this framework. The pam_ssh_agent_auth module I mentioned here, is one of them.

Sudo command, like many other applications in Linux, make use of PAM for user authentication. The file /etc/pam.d/sudo controls how sudo will make use of PAM for user authentication. Before we put the line in, it defaults to system-auth, which on most system usually is password authentication(check /etc/pam.d/system-auth if you are interested in what it does on your system). After we put the line in, sudo will first try to execute what that specific line instructs.

What the configuration line I put in /etc/pam.d/sudo does are explained below:

auth - Tells PAM this line is about a method of how to authenticate a user.
sufficient - Tells PAM that the user will be considered successfully authenticated if he passed this one, no need to try othe "auth" line after this one.
pam_ssh_agent_auth.so - Tells PAM to load and excute this module.
file=~/.ssh/authorized_keys - The parameter to the module, the meanning is already explained above.

So when a user fires up sudo, it calls PAM for authentication, PAM then look into the file /etc/pam.d/sudo and decide to try pam_ssh_agent_auth module first. This module then interacts with the SSH agent and verifys the priviate key information provided by SSH agent against the public keys in ~/.ssh/authorized_keys. If the verification susccess, the module turns back to PAM system and tells it the authentication is successful. As PAM sees the sufficient options here, it considers the whole authentication process is successful and sudo can move on. If the user has no SSH agent running, or the agent is not able to provide the correct key, the authentication attempt of this module failed, and PAM moves on to the next line, which allows the user to still authenticate with his password.

More than that

This approach is not specific to sudo. It can be enabled for any program that makes use of PAM for user authentication. So just open your mind and find out what makes you keep typing passwords. If it uses PAM, congratulations, you may save your fingers!

Published inTips