Multi-factor authentication (MFA) solutions are becoming the standard for many user facing IT services. Most visibly with web applications, corporate VPNs, self-service portals and online banking platforms to name but a few. Extending MFA to the realm of system administration to harden access to the Linux operating system itself is becoming an established best practice with more organisations as well.

It will be likely that MFA utilities and applications on Linux used for operating system access will differ from those used for web”ish” applications. It is also likely these solutions will be implemented using purpose developed Pluggable Authentication Modules (PAM) such as those from Google or Duo Security to leverage the standard Linux PAM framework.

Before delving into implementation specifics, an overview on what is being attempted in this example.

  1. Only SSH access will be subject to MFA.
  2. All local accounts will be denied access over SSH.
  3. Active Directory authentication must be successful before challenging for MFA.
  4. Subsequent MFA authentication must be successful.

(Console access is not subject to MFA using this configuration)

The authentication logic:

PAM MFA flow chart

Turning to the PAM configuration

The configuration presented uses the Duo Security “” module available in the duo_unix-latest.tar.gz build archive to provide MFA services. The archive itself, SLES prerequisites, SSH requirements and best practices, configuration info for the /etc/duo/pam_duo.conf, and the shared API keys required are documented at

Once the software build, installation, and configuration of the module is complete, the system PAM configuration can be modified to use it.

Some PAM basics

The files used by the PAM framework in most Linux distributions are located in the /etc/pam.d directory. The service they provide authentication and authorisation configurations for can usually be gleaned from their meaningful names (like /etc/pam.d/sshd). PAM module directives are processed serially within like module “interface” groups. Module interface types include auth, account, password, and session. So, for example, all auth module interface lines are processed in order before moving on to the next interface group in a given service file. The focus in this example is limited to the “auth” interface.

Control flag key-words

Module interfaces use control flag key-words that determine how module failures, successes, or responses to other PAM module return code values are handled (more on return code values later). These responses can result in a successful authentication, prompting for additional authentication criteria, or terminating PAM processing ending the authentication session if unexpected results are encountered.

The relevant interface control flag key-words are:

  • requisite: Failure terminates PAM processing ending the authentication session.
  • required: Failure does not terminate PAM processing but does impact the final success/failure result of the interface group.
  • sufficient: Success terminates PAM processing ending the authentication session. However, if a previous “required” control flag has failed the final success/failure result of the interface group will be impacted.
  • optional: Failure or success does not impact the final success/failure result of the interface group.
  • include: Calls an additional service file to include in the PAM processing. Failure within the included file does impact the final success/failure result of the PAM processing.


Control flag square bracket notation

Technically, PAM modules return responses to authentication and authorisation events in the form of PAM return code values. These return code values, and their defined actions (called value=action pairs), are used by the PAM framework to make decisions. There are currently thirty standard return code values used by PAM module developers (a PAM module will only use the return code values specified by the module developer).

In addition to using the key-word form for interface control flags, the explicit “square bracket notation” can be used equally as well. Below is the equivalent of the previous control flag key-words in square bracket notation using return code value=action pairs:

requisite              [success=ok new_authtok_reqd=ok ignore=ignore default=die]
required              [success=ok new_authtok_reqd=ok ignore=ignore default=bad]
sufficient             [success=done new_authtok_reqd=done default=ignore]
optional               [success=ok new_authtok_reqd=ok default=ignore]

Note that the “value” component of the value=action pairs used in square bracket notation are the actual PAM return code values without the “pam_” prefix. So, the “pam_success” return code value becomes “success” when used in square bracket notation.

Square bracket notation can be used for more granular control over how PAM events are handled, enhancing the implementable logic in PAM processing.

More info concerning control flag key-words, square bracket notation, return code actions, and PAM in general can be gleaned from the pam.d man file.

Similarly, more info concerning PAM module arguments and return code values can be gleaned from module man files (the pam_localuser man file for example).

Implementing the MFA configuration

MFA text based login

Important: Minimally two active sessions are recommended when initially modifying the system PAM configuration files in the /etc/pam.d directory.  One as root used for making changes to the files, and one for testing those changes.

The PAM SSH service configuration file will be modified to reference a new custom configuration file, instead of the /etc/pam.d/common-auth-pc file, to implement the MFA configuration. The use of a custom file helps retain as much content in the original PAM service files as possible in the event the system needs to be rolled back to restore the default authentication services.

Original /etc/pam.d/sshd file:


auth        requisite
auth        include     common-auth

account     requisite
account     include     common-account

password    include     common-password

session     required
session     include      common-session
session     optional   silent noupdate showfailed

Create the new file in the /etc/pam.d directory with the “-pc” suffix as user root. Then create a symbolic link to the file to reference it from the /etc/pam.d/sshd file (conforming to the standards in the /etc/pam.d directory).

~# cd /etc/pam.d/
~# touch mfa-common-auth-pc
~# ln -s mfa-common-auth-pc mfa-common-auth

Updated /etc/pam.d/sshd file:


auth           requisite
auth           include      mfa-common-auth

account     requisite
account     include      common-account

password  include      common-password

session     required
session     include        common-session
session     optional   silent noupdate showfailed

Modify the contents of the new file



auth    [success=4 user_unknown=ok default=ignore]
auth    required
auth    optional file=/usr/mfa/etc/mfa-msg.txt
auth    [success=ok new_authtok_reqd=ok ignore=ignore default=bad cred_err=die]
auth    sufficient
auth    sufficient

What is happening with this configuration

  1. auth [success=4 user_unknown=ok default=ignore]
  2. auth required
  3. auth optional file=/usr/mfa/etc/mfa-msg.txt
  4. auth [success=ok new_authtok_reqd=ok ignore=ignore default=bad cred_err=die]
  5. auth sufficient
  6. auth sufficient


  1. If the pam_localuser module detects the user exists in the /etc/passwd file it skips the next four lines of the file by virtue of the values and actions specified in the control flag square bracket notation. The pam_deny module then denies the user access and because the “sufficient “control flag key-word is used PAM processing then terminates.
  2. The pam_env module can be used to set and unset additional environment variables and is included because it is utilised in the default /etc/pam.d/common-auth-pc file. Because the “required” control flag key-word is used, PAM processing continues even if the module registers a failure. If a failure is registered, when the final line with a key-word of “required”, or the next line with a “sufficient” key-word is processed, the overall result will be a failure when PAM processing terminates.
  3. The pam_echo module is used to display a banner in the session to provide information to the user concerning the MFA login process. If a banner is used it can be customised to suit your organisation, obviously. Because the “optional” control flag key-word is used, the success or failure of this line does not impact the final success/failure of the interface group and PAM processing continues.
  4. The pam_sss module uses the SSSD to attempt authentication of the user against Active Directory according to its configuration. The values and actions specified in the control flag square bracket notation is the same as used for the “required” key-word, but adds the “cred_err=die” value=action pair making this particular error behave in a similar way to the “sufficient” control flag. Meaning if this value is returned by the module, PAM processing terminates.
  5. The pam_duo module attempts authentication of the user against the organisation’s Duo Security UNIX application configuration and its local system configuration. Because the “sufficient” control flag key-word is used, whether a success or failure event, or the failure event of a previous line that used the “required” key-word occurs PAM processing will terminate.
  6. The purpose of the pam_deny module is to deny access. When this module is processed the user will always be denied access. Because the “sufficient” control flag key-word is used PAM processing will then terminate.

The MFA application, utilities, or model used for your deployment may of course vary. If a PAM based methodology has already been chosen, or may now be a considered an option after reviewing this article I hope it has been of help. Once developed and tested, these types of solutions lend themselves to being distributed to systems managed by most configuration management frameworks such as SUSE Manager, Salt, or Puppet.

One of my next blog entries will cover using PAM based MFA to supplement the authorisation of privilege elevation, such as becoming user root.

(Visited 21 times, 1 visits today)

Leave a Reply

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

No comments yet

Avatar photo
Lawrence Kearney Lawrence has over 20 years of experience with SUSE and Red Hat Enterprise Linux solutions, and supporting and designing enterprise academic and corporate computing environments. As a member of the Technology Transfer Partners (TTP) Advisory board Lawrence actively contributes and promotes the efforts of international academic computing support missions. Currently working for the Georgia High Performance Computing Center (GACRC) at the University of Georgia supporting high performance and research computing infrastructures Lawrence publishes articles on many of his solutions as time permits.