12-B.6: Pluggable Authentication Modules
- Page ID
- 42879
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)PAM
Linux Pluggable Authentication Modules (PAM) provide dynamic authentication support for applications and services in a Linux system. Linux PAM is evolved from the Unix Pluggable Authentication Modules architecture.
Linux-PAM separates the tasks of authentication into four independent management groups:
- Account modules check that the specified account is a valid authentication target under current conditions. This may include conditions like account expiration, time of day, and that the user has access to the requested service.
- Authentication modules verify the user's identity, for example by requesting and checking a password or other secret. They may also pass authentication information on to other systems like a keyring.
- Password modules are responsible for updating passwords, and are generally coupled to modules employed in the authentication step. They may also be used to enforce strong passwords.
- Session modules define actions that are performed at the beginning and end of sessions. A session starts after the user has successfully authenticated.
PAM offers the following advantages:
- Provides a common authentication scheme that can be used with a wide variety of applications.
- Allows a large amount of flexibility and control over authentication for both system administrators and application developers.
- Allows for the development of programs without creating their own authentication scheme.
PAM Configuration
The PAM configuration files are in the /etc/pam.d/ directory which contains the configuration files for each of the system's PAM-aware application/services.
The syntax of each file in /etc/pam.d/ is similar to that of the main file and is made up of lines of the following form:
module-interface control-flag module-name module-arguments
This is a example of a rule definition (without module-arguments) found in the /etc/pam.d/sshd file, which disallows non-root logins when /etc/nologin exists:
account required pam_nologin.so
Understanding PAM Management Groups and Control-flags
PAM authentication tasks are separated into four independent management groups. These groups manage different aspects of a typical user’s request for a restricted service.
A module is associated to each one of these management group types:
- Account: provide services for account verification: has the user’s password expired? Is this user permitted access to the requested service?
- Authentication: authenticate a user and set up user credentials.
- Password: responsible for updating user passwords and works together with authentication modules.
- Session: manage actions performed at the beginning of a session and end of a session.
PAM loadable object files (the modules) are to be located in the following directory: /lib/security/ or /lib64/security depending on the architecture.
The supported control-flags are:
- Requisite: failure instantly returns control to the application indicating the nature of the first module failure.
- Required: all these modules are required to succeed for libpam to return success to the application.
- Sufficient: given that all preceding modules have succeeded, the success of this module leads to an immediate and successful return to the application (failure of this module is ignored).
- Optional: the success or failure of this module is generally not recorded.
Lockout Users
Linux Server hardening is one of the important tasks for system administrators. It is recommended that one should enable login or SSH attempts policy, meaning a user’s account should be locked automatically after some predetermined numbers of failed login or SSH attempts.
In Linux distributions like CentOS, RHEL and Fedora this is achieved by using PAM module “pam_faillock” and for Debian-like distributions, this can be achieved using “pam_tally2” PAM module.
For CentOS/RHEL/Fedora
Add the following lines in two files /etc/pam.d/password-auth & /etc/pam.d/system-auth,
auth required pam_faillock.so preauth silent audit deny=3 unlock_time=600
auth [default=die] pam_faillock.so authfail audit deny=3 unlock_time=600
account required pam_faillock.so
Where,
- Audit will enable audit logs for user login attempt in secure log file.
- Deny=3 will lock the user after three unsuccessful login attempts. You can change this number as per your requirement.
- unlock_time=600 means user’s account will remain locked for 10 minutes (600 seconds); if you want a user account to be locked forever then set this parameter as “unlock_time=never.“
Note: To lock root account as well after n incorrect logins, add “even_deny_root” parameter in auth section lines; example is shown below:
auth required pam_faillock.so preauth silent audit even_deny_root deny=3 unlock_time=600
auth [default=die] pam_faillock.so authfail audit even_deny_root deny=3 unlock_time=600
For Debian, Ubuntu and Linux Mint
Add the following line in the file “/etc/pam.d/common-auth”
auth required pam_tally2.so onerr=fail deny=3 unlock_time=600 audit
If you wish to lock root account as well after three incorrect logins then add the following line:
auth required pam_tally2.so onerr=fail deny=3 unlock_time=600 audit even_deny_root root_unlock_time=600
Where:
- Onerr=fail - In case of error issue a fail.
- deny=3 - After three unsuccessful login attempts account will be locked.
- unlock_time=600 - Means account will remain locked for 10 minutes or 600 seconds.
- audit - Means audit the logs in audit.log file.
- even_deny_root - Lock the root account after three incorrect logins.
- root_unlock_time=600 - Root account will remain locked for 10 minutes or 600 seconds after three unsuccessful login attempts.
Adapted from:
"Lock User Account After n Failed Login attempts in Linux" by Pradeep Kumar is licensed under CC BY-NC 4.0