• Linux
  • Microsoft

Managing system access with Linux-PAM

Recently I had the necessity to restrict who can SSH and access the console of a variety of Linux systems joined to Active Directory. With SSSD it’s fairly trivial as it’s sssd-ad provider has built in support for this scenario by using Active Directory Group Policy Objects and Windows User Rights Assignments.

Winbind does not have this capability so something more low-level was needed for systems joined to Active Directory with Winbind.

What are PAMs?

The Plugable Authentication Module is a series of library that implements various methods to perform authentication. They can (and usually are) be called by any application that does not want to reinvent the wheel and write it’s own authentication interface.

It exposes two channels to the application: an interface to handle authentication requests and decisions (the application itself does not handle the authentication, it knows nothing of the authentication methods you can potentially use via PAM) and the other is a messaging interface to the user (so you can be prompted for username/password/whatever via the application user interface)

The following is a schematics representation of the PAM architecture, courtesy of the “Linux-PAM System Administrators Guide“:

We are going to use a specific PAM library to restrict access to our system: pam_access.so.

Enter authselect

In modern RHEL systems, authselect is used to manage most aspects of the PAM configuration. What it does is that it manages some predefined PAM stacks (these are configuration files in /etc/pam.d that represent complete units) that are applied to most of the PAM service names defined on a system.

As an example, this is the /etc/pam.d/password-auth file created and managed by authselect:

This file is included in many other PAM configuration files called by different service names:

We need to tell authselect that we want to use the pam_access library so it can modify the default files to enable it.

The verify we have correctly enabled the feature:

Now we need to configure the library:

What I did here is I told the library to permit any PAM service for my Domain Admins, the members of the group wheel and prevent any other local access to the system.
For more information and an explanation of the syntax man access.conf is your friend.

Now we need to take care of the SSH connections. Unfortunately, the pam-access library allows to specify PAM service names only for non-networked logins.


This last sentence bears some explaining to do: pam_access.so uses the calling service name when the value of the passed RHOST variable is undefined by the calling application (read: local daemons usually do that).
When RHOST is defined (read: the login process, sshd, et cetera…), it uses that. When you login via SSH RHOST is populated with your source IP so we can’t match against the service name.


What can be done is to modify the ssh PAM service file to specify a custom configuration file for the pam-access library:

The line with the arrow is the one I’ve added, and following is the library custom configuration file:

It’s very similar to the global one we defined earlier on, but for SSH we use the “ALL” PAM service name.

Does it works?

Yes it does.

From the /var/log/secure we can see that the PAM module we introduced is preventing the login attempt to conclude successfully even if some other modules permitted it.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.