Sometimes, I want to prevent regular users from logging into the system to perform more complex operations.
To achieve that, I am using Pluggable Authentication Modules for Linux to temporarily disable user logins.
Basic usage
Disable user logins without providing a reason.
$ sudo touch /run/nologin
Example of a failed login attempt (as regular user).
$ ssh milosz@remote_server milosz@remote_server's password: Connection closed by remote_server
Disable user logins providing an additional reason.
$ echo "System maintenance in progress" | sudo tee /run/nologin
Example of a failed login attempt (as regular user).
$ ssh milosz@remote_server milosz@remote_server's password: System maintenance in progress Connection closed by remote_server
Notice that /var/run
is a link to /run
directory, so I have used shorter version.
Pluggable Authentication Modules configuration
Set of rules that determines behavior of pam_nologin
module for the Shadow login service is defined in /etc/pam.d/login
Pluggable Authentication Modules configuration file.
By default only root user can login if /run/nologin
file exists.
# Disallows other than root logins when /etc/nologin exists # (Replaces the `NOLOGINS_FILE' option from login.defs) auth requisite pam_nologin.so
Use pam_succeed_if
module once to bypass that restriction for users in the admins group.
# Disallows other than root logins when /etc/nologin exists # (Replaces the `NOLOGINS_FILE' option from login.defs) # ignore rule if user is in admins group auth [default=1 success=ignore] pam_succeed_if.so quiet user notingroup admins auth requisite pam_nologin.so
Set of rules that determines behavior of pam_nologin
module for the Secure Shell service is defined in /etc/pam.d/sshd
Pluggable Authentication Modules configuration file.
By default no one can login over SSH protocol if /run/nologin
file exists [assuming that PermitRootLogin
SSH configuration directive is not enabled].
# Disallow non-root logins when /etc/nologin exists. account required pam_nologin.so
Use pam_succeed_if
module multiple times to bypass that restriction for users in admins group and milosz
username.
# Disallow non-root logins when /etc/nologin exists. account [default=2 success=ignore] pam_succeed_if.so quiet user != milosz account [default=1 success=ignore] pam_succeed_if.so quiet user notingroup admins account required pam_nologin.so
You can use user, uid, gid, shell, home, ruser, rhost, tty, service fields to build a condition which consist of three words: field, test and a value to test for.
In above-mentioned examples pam_succeed_if
module will skip execution of given number of rules on condition failure.
To explain and illustrate this behavior I have prepared the following real world examples based upon previous configuration.
Situation in which user name and group differs. Access will be denied as pam_nologin
module is executed.
Sep 7 05:52:11 debian sshd[6728]: pam_succeed_if(sshd:account): 'user' resolves to 'pawel' Sep 7 05:52:11 debian sshd[6728]: pam_succeed_if(sshd:account): requirement "user != milosz" was met by user "pawel" Sep 7 05:52:11 debian sshd[6728]: pam_succeed_if(sshd:account): 'user' resolves to 'pawel' Sep 7 05:52:11 debian sshd[6728]: pam_succeed_if(sshd:account): requirement "user notingroup admins" was met by user "pawel" Sep 7 05:52:11 debian sshd[6728]: Failed password for pawel from ::1 port 57219 ssh2 Sep 7 05:52:11 debian sshd[6728]: fatal: Access denied for user pawel by PAM account configuration [preauth]
Situation in which user name differs, group matches. Access will be granted as pam_nologin
module is not executed.
Sep 7 05:53:31 debian sshd[6740]: pam_succeed_if(sshd:account): 'user' resolves to 'michael' Sep 7 05:53:31 debian sshd[6740]: pam_succeed_if(sshd:account): requirement "user != milosz" was met by user "michael" Sep 7 05:53:31 debian sshd[6740]: pam_succeed_if(sshd:account): 'user' resolves to 'michael' Sep 7 05:53:31 debian sshd[6740]: pam_succeed_if(sshd:account): requirement "user notingroup admins" not met by user "michael" Sep 7 05:53:31 debian sshd[6740]: Accepted password for michael from ::1 port 57220 ssh2 Sep 7 05:53:31 debian sshd[6740]: pam_unix(sshd:session): session opened for user michael by (uid=0)
Situation in which user name matches. Access will be granted as group condition is not evaluated and pam_nologin
module is not executed.
Sep 7 05:54:11 debian sshd[6755]: pam_succeed_if(sshd:account): 'user' resolves to 'milosz' Sep 7 05:54:11 debian sshd[6755]: pam_succeed_if(sshd:account): requirement "user != milosz" not met by user "milosz" Sep 7 05:54:11 debian sshd[6755]: Accepted password for milosz from ::1 port 57221 ssh2 Sep 7 05:54:11 debian sshd[6755]: pam_unix(sshd:session): session opened for user milosz by (uid=0)
References
Read pam_nologin
and pam_succeed_if
manual pages to get detailed information.