Use pam_nologin to pause non-root logins safely
You will create a temporary maintenance lock that displays a message and prevents non-root users from logging in through PAM, then remove it and verify that the lock is gone. On this machine, pam_nologin comes from libpam-modules version 1.5.3-5ubuntu5.7. Allow about ten minutes, plus the time needed to check every login service you intend to restrict.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need an existing maintenance window, a root shell or sudo, and an open root session that you will keep until the rollback is complete. This guide changes a security-sensitive login control. It does not stop already logged-in users, terminate sessions, or suspend services.
1. Check how PAM is already using the module
Start with read-only checks. The module is installed as a shared PAM object, not as a command you run directly:
$ dpkg-query -W -f='${Package} ${Version}\n' libpam-modules:amd64
libpam-modules 1.5.3-5ubuntu5.7
$ ls -l /usr/lib/x86_64-linux-gnu/security/pam_nologin.so
$ rg -n 'pam_nologin' /etc/pam.d
On this host, the module is present in /etc/pam.d/login, /etc/pam.d/sshd and /etc/pam.d/ppp. Your host may use a different set of services. The PAM module can provide both auth and account types, so inspect the actual stack rather than assuming that one entry covers every login method.
Checkpoint
Keep one privileged session open and write down the services that contain pam_nologin.so. If the service you need is absent, creating the file alone will not make that service consult this module.
2. Choose the lock file and message
With no module option, pam_nologin checks /var/run/nologin or /etc/nologin. The conventional system-wide file is /etc/nologin, and the installed configuration on this machine comments that path. The contents are shown to a refused user, so make the message useful but do not put secrets, internal hostnames or sensitive incident details in it.
Before writing anything, check whether a file already exists. This is an ordinary read-only command, but treat an existing file as owned by another maintenance procedure until you have identified it:
# ls -l /etc/nologin /var/run/nologin 2>/dev/null || true
# for path in /etc/nologin /var/run/nologin; do
if [ -e "$path" ]; then
printf 'existing lock: %s\n' "$path"
fi
done
Do not overwrite an existing lock without an explicit handover. You could hide another operator's recovery instructions and remove the wrong file later.
3. Create the maintenance lock
This is the state-changing step. The command below writes a short message atomically through a temporary file, sets a readable mode, and then renames it into place. Run it as root:
# tmp=$(mktemp /etc/nologin.tmp.XXXXXX)
# printf '%s\n' 'System maintenance is in progress. Please try again later.' > "$tmp"
# chmod 0644 "$tmp"
# mv -f -- "$tmp" /etc/nologin
The final rename is the point at which the lock becomes visible. If a command before mv fails, inspect and remove only the named temporary file. Do not use a broad cleanup pattern in /etc.
Checkpoint
Confirm the file and its message:
# stat -c '%A %U:%G %n' /etc/nologin
-rw-r--r-- root:root /etc/nologin
# cat /etc/nologin
System maintenance is in progress. Please try again later.
The module checks for the file when the relevant PAM service processes a login. It does not kick out users who are already logged in. Keep the privileged session open so that a PAM configuration mistake cannot strand your administration access.
4. Test a real login path
Test one of the services that actually contains pam_nologin.so, using a disposable non-root account or a controlled second session. Do not test by closing your only root connection. For SSH, from a separate terminal use a command such as:
$ ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no USERNAME@HOSTNAME
System maintenance is in progress. Please try again later.
Permission denied
Replace USERNAME and HOSTNAME with safe test values. The exact SSH wording and whether the message appears before or after authentication depend on the service's PAM ordering. The useful result is that the non-root login is refused and the maintenance text is displayed.
Root is deliberately exempt from this module. A successful root login does not show that the lock failed; it is the documented behaviour. Also remember that the module only affects login methods whose PAM configuration includes it. Check each service you plan to advertise as unavailable.
5. Avoid the successok trap
Do not add successok to a normal nologin entry. Without that option, the module returns PAM_IGNORE when no lock file exists. With successok, it returns PAM_SUCCESS instead. The manual warns that this can break standard Unix nologin semantics when the entry is before a sufficient method: a later failure could still lead to a successful login because this module reported success.
A conventional entry is therefore small and required, for example:
auth required pam_nologin.so
Do not copy that line into every PAM file blindly. PAM stack order is part of the service's authentication policy. Preserve the distribution's existing structure, and make a backup before editing a PAM configuration. A syntax or ordering error can prevent logins, including administrative ones.
6. Remove the lock and recover normal access
When maintenance is finished, remove the exact file you created. This is another state-changing action. First confirm that it is still your file and that no handover has occurred:
# stat -c '%A %U:%G %n' /etc/nologin
# rm -- /etc/nologin
# test ! -e /etc/nologin && echo 'nologin lock removed'
If you used a different path through file=/path/nologin, remove that exact path instead. Do not remove both default paths as a generic cleanup step. One may belong to another procedure, and the module's effective path depends on the options in the PAM stack.
Now open a fresh test login as the non-root account. A successful login confirms the file is no longer blocking that service, but it does not prove that every service uses the same PAM stack. Repeat the service checks from step 1 if the maintenance window covered more than one access method.
Done means
- You checked the installed module version and the PAM services that reference it.
- You kept a privileged session open before creating the lock.
- The maintenance message was visible and the non-root test login was refused.
- You did not use
successokin a normal nologin stack. - You removed only the exact lock file you created and verified a fresh non-root login afterwards.