Home / Alt manpages / pam_nologin(8)

  • pam_nologin(8)
  • Admin command
  • linux

Use pam_nologin to Pause Non-Root Logins Safely

Need to lock everyone but root out of a box for maintenance without touching sshd_config or killing sessions, pam_nologin does exactly that. This guide creates a temporary maintenance lock that displays a message and prevents non-root users from logging in through PAM, then removes it and verifies 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.

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 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 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. The module can provide both auth and account types, so inspect the actual stack rather than assume 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 keep secrets, internal hostnames and incident detail out of it.

Before writing anything, check whether a file already exists. This is a 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

Warning

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 writes a short message atomically through a temporary file, sets a readable mode, 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 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 result that matters is that the non-root login is refused and the maintenance text is shown.

Root is deliberately exempt from this module. A successful root login does not show that the lock failed; it is documented behaviour. Also remember the module only affects login methods whose PAM configuration includes it, so check each service you plan to advertise as unavailable.

5. Avoid the successok trap

Warning

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, and the manual warns 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 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 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 every service uses the same PAM stack. Repeat the step 1 checks if the maintenance window covered more than one access method.

Done means

  • Scope confirmed. You checked the installed module version and the PAM services that reference it.
  • Session kept open. You kept a privileged session open before creating the lock.
  • Lock verified live. The maintenance message was visible and the non-root test login was refused.
  • No successok. You did not use successok in a normal nologin stack.
  • Cleanly removed. You removed only the exact lock file you created and verified a fresh non-root login afterwards.