SELinux and PAM

With all the information about SELinux users and roles, we have not touched upon how exactly applications or services create and assign an SELinux context to a user. As mentioned earlier on, this is coordinated through the use of Linux’s PAM services.

Assigning contexts through PAM

End users log in to a Linux system through either a login process (triggered through a getty process), a networked service (for example, the OpenSSH daemon), or through a graphical login manager (xdm, kdm, gdm, slim, and so on).

These services are responsible for switching our effective user ID (upon successful authentication, of course) so that we are not active on the system as the root user. For SELinux systems, these processes also need to switch the SELinux user (and role) accordingly, as otherwise, the context will be inherited from the service, which is obviously wrong for any interactive session.

In theory, all these applications can be made fully SELinux aware, linking with the SELinux user space libraries to get information about Linux mappings and SELinux users. Instead of converting all these applications, the developers decided to take the authentication route to the next level using the PAM services that Linux systems provide.

PAM offers a very flexible interface for handling different authentication methods on Linux (and Unix) systems. All applications mentioned earlier use PAM for their authentication steps. To enable SELinux support for these applications, we need to update their PAM configuration files to include the library.

The following code listing is an excerpt from CentOS’s /etc/pam.d/remote file, limited to PAM’s session service directives. It triggers the library code as part of the authentication process, as follows:

session	required close
session	required
session	required open
session	required
session	optional force revoke
session	include	password-auth
session	include	postlogin

The arguments supported by the code are described in the pam_selinux manual page. In the preceding example, the close option clears the current context (if any), whereas the open option sets the context of the user. The pam_selinux module takes care of querying the SELinux configuration and finding the right mappings and context based on the service name used by the daemon.

Prohibiting access during permissive mode

Having SELinux active and enforcing on a system improves its resilience against successful exploits and other malicious activities, especially when the system is used as a shell server (or provides other interactive services) and the users are confined – meaning they are mapped to user_u or other confined SELinux users.

Some administrators might want to temporarily switch the system to permissive mode. This could be to troubleshoot issues or to support some changes made on the system. When using permissive mode, it would be a good idea to ensure that the interactive services are not usable for regular users.

With pam_sepermit, this can be enforced on the system. The PAM module will deny a set of defined users access to the system if the system is in permissive mode. By default, these users are mentioned in /etc/security/sepermit.conf, but a different file can be configured through the conf= option inside the PAM configuration itself.

In the sepermit.conf file, there are three approaches to document which users should be denied access when the system is in permissive mode:

  • Regular usernames
  • Group names, prefixed with the @ sign
  • SELinux usernames, prefixed with the % sign

Within this file, we list each user, group, or SELinux user on a single line. After each entry, we can (but don’t have to) add one or two options:

  • exclusive means that the system will allow the user to be active even when the system is in permissive mode, but only a single session can be active. When the user logs out, all active processes will be killed.
  • ignore will return PAM_IGNORE as the return status if SELinux is in enforcing mode, and PAM_AUTH_ERR if SELinux is in permissive mode. This allows special constructs/branches for this user in PAM based on the permissive state of the system.

To enable pam_sepermit, it’s sufficient to enable the module in the auth PAM service as follows:

auth	required

Of course, don’t forget to remove all active user sessions when switching to permissive mode, as any running session is otherwise left untouched.

Polyinstantiating directories

The last PAM module we’ll look at is Before we dive into configuring this module, let’s first look at what polyinstantiation is about.

Polyinstantiation is an approach where, when a user logs in to a system, the user gets a view on filesystem resources specific to its session, while optionally hiding the resources of other users. This differs from regular access controls, where the other resources are still visible, but might just be inaccessible.

This session-specific view, however, does not just use regular mounts. The module uses the Linux kernel namespace technology to force a (potentially more limited) view on the filesystem, isolated and specific to the user session. Other users have a different view on the filesystem.

Let’s use a common example. Assume that all users, except root, should not have access to the temporary files generated by other users. With standard access controls, these resources would still be visible (perhaps not readable, but their existence or the directories they reside in would be visible). Instead, with polyinstantiation, a user will only see their own /tmp and /var/tmp views.

The following setting in /etc/security/namespace.conf will remap these two locations:


/tmp		/tmp/tmp-inst/		level	root
/var/tmp	/var/tmp/tmp-inst/	level	root

On the real filesystem, those locations will be remapped to a subdirectory inside /tmp/tmp-inst and /var/tmp/tmp-inst. The end users do not know or see the remapped locations – for them, /tmp and /var/tmp are as they would expect.

The format (and thus polyinstantiation) of the subdirectories created depends on the third option within the namespace.conf file. The supported options are as follows:

  • user, which will create a subdirectory named after the user (such as lisa)
  • level, which will create a subdirectory named after the user sensitivity level and username (such as system_u:object_r:tmp_t:s0-s0:c0.c1023_lisa)
  • context, which will create a subdirectory named after the process context (including the sensitivity level) and username (such as system_u:object_r:user_tmp_t:s0_lisa)

For SELinux systems, the most common setting is level.


In the default namespace.conf file, you might notice that this also has support for home directories. When enabled with the level or context method, this will ensure that users have a sensitivity-specific home directory set. For instance, if the system configuration forces the user to have a lower sensitivity when logged in through SSH than when the user logs in through the terminal, a different home directory view will be used.

In the previous example, only the root user is exempt from these namespace changes. Additional users can be listed (comma-separated), or an explicit list of users can be given for which polyinstantiation needs to be enabled (if we prefix the user list with the ~ character). To allow the namespace changes to take place, the target locations need to be available on the system with the 000 permission:

# mkdir /tmp-inst && chmod 000 /tmp-inst

Next, enable in the PAM configuration files at the session service:

session	required

Finally, make sure that SELinux allows polyinstantiated directories. On CentOS, this is governed through the polyinstantiation_enabled SELinux boolean:

# setsebool polyinstantiation_enabled on

Other distributions will have it through the allow_polyinstantiation SELinux boolean.

With the polyinstantiation support, we close off this final section of the chapter, where we learned how PAM is used to trigger SELinux context changes on the system.

Related Articles

No Results Found

The page you requested could not be found. Try refining your search, or use the navigation above to locate the post.

Lorem ipsum dolor sit amet consectetur


Submit a Comment

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

3 × 4 =