Home / Alt manpages / pam_securetty(8)

  • pam_securetty(8)
  • Admin command
  • linux

Lock Root Logins to Trusted Terminals with pam_securetty

pam_securetty stops root logging in from anywhere that isn't on an explicit allow-list, so a stolen password alone can't get root in over SSH. Non-root authentication is untouched. You'll also check the module's console exception and keep a rollback copy of the PAM configuration. Allow about 20 minutes, plus time to arrange an already-open root-capable session for recovery.

This guide describes the installed Linux-PAM pam_securetty module from package version 1.5.3-5ubuntu5.7. The local manual page is dated 7 May 2023. PAM stacks vary by distribution and service, so treat the example as a controlled pattern to adapt after inspecting your own files.

Security warning

A bad PAM edit can lock root out of a service or console. Do not test this over your only SSH session, and do not close an existing administrative session until a separate login has been verified. Reading files below needs no special privileges; editing PAM configuration, creating the securetty file and changing its ownership or mode all require them.

1. Check the module and the target PAM service

Confirm the module exists and identify the service whose root logins you intend to restrict. This module only provides the auth type, and the application has to supply the PAM_TTY value correctly for it to work at all:

$ dpkg-query -W -f='${Package} ${Version}\n' libpam-modules:amd64
libpam-modules 1.5.3-5ubuntu5.7
$ ls -l /lib/x86_64-linux-gnu/security/pam_securetty.so
-rw-r--r-- 1 root root ... /lib/x86_64-linux-gnu/security/pam_securetty.so
$ sed -n '1,120p' /etc/pam.d/login

The file path can differ on another architecture. If the module is missing, stop and install or repair the package through your normal system-management process; do not write a guessed module path into a PAM file.

Checkpoint

Decide whether the rule belongs in /etc/pam.d/login, a display-manager file, or another service file. Do not add it to every PAM service by copying a line blindly, and remember that a service which doesn't set PAM_TTY correctly can't be evaluated reliably by this module.

2. Inspect the secure terminal list

pam_securetty first checks /etc/securetty. If that file is absent and the module was built with vendor-directory support, it falls back to /securetty. Each entry names a terminal device without the /dev/ prefix. On this machine both paths are absent, so root logins have no file-based terminal allow-list at all:

$ for file in /etc/securetty /securetty; do
    if test -e "$file"; then
        ls -l "$file"
        sed -n '1,120p' "$file"
    else
        printf '%s: absent\n' "$file"
    fi
done
/etc/securetty: absent
/securetty: absent
  • /dev/tty1 becomes the entry tty1.
  • /dev/ttyS0 (a serial device) becomes ttyS0.
  • An SSH session normally gets a pseudo-terminal name such as pts/0, but allowing pseudo-terminals defeats the point of limiting root to physical or otherwise approved devices. Decide that policy on purpose, not by accident.

Common entries are host-specific: use the names reported by your own console and login setup rather than copying a list from somewhere else.

3. Create a minimal allow-list

Preserve any existing file first, then create the list with root privileges. Replace the sample terminal with a device you have deliberately approved. This command changes persistent authentication policy, so read the here-document before pressing Enter:

$ sudo install -o root -g root -m 0600 /etc/securetty /etc/securetty.bak 2>/dev/null || true
$ sudo sh -c 'printf "%s\n" tty1 > /etc/securetty'
$ sudo chown root:root /etc/securetty
$ sudo chmod 0600 /etc/securetty
$ sudo sed -n '1,40p' /etc/securetty
tty1

pam_securetty rejects the file outright if it isn't a plain file or is world-writable, so the restrictive mode above isn't paranoia, it's a requirement. The backup command may print nothing when no file existed to back up; in that case there's simply nothing to restore.

Checkpoint

Verify the metadata before connecting the PAM rule:

$ stat -c '%A %U:%G %n' /etc/securetty
-rw------- root:root /etc/securetty

4. Add the rule before sufficient authentication

Make a dated backup of the target PAM service, then edit it as root. The canonical order is a required pam_securetty line before any sufficient authentication method. Keep the existing stack and insert only the line that matches your service:

$ sudo cp -a /etc/pam.d/login /etc/pam.d/login.before-pam-securetty
$ sudoedit /etc/pam.d/login

Place this line before the first sufficient authentication line, and before the normal password module if that's how the service is structured:

auth required pam_securetty.so

To request diagnostics while testing, add the documented option:

auth required pam_securetty.so debug
  • debug is for temporary use while consulting the service's logging destination. It does not make an unauthorised terminal acceptable.
  • noconsole is a separate, stricter choice: it stops automatic acceptance of the kernel console unless that device is also listed in the securetty file. By default the module allows root on the console named by the kernel console= setting and on terminals listed by /sys/class/tty/console/active; add noconsole if your policy needs the file to be the complete allow-list.
auth required pam_securetty.so noconsole

Warning

Do not select noconsole without first confirming that your approved physical console is present in /etc/securetty. Get this wrong and your recovery path disappears the next time someone tries to log in.

5. Test from a second session

Keep the first administrative session open. From the approved terminal, test a root login using the exact service you changed. From a deliberately unapproved terminal, confirm root gets rejected. Do not paste a production password into a command, and do not run a password-testing loop.

A successful module decision lets PAM continue authenticating root on an accepted device; a rejected decision returns an authentication error. Later PAM modules, account policy or the service itself can still affect what you see, so keep the full service log handy when diagnosing a failure:

$ sudo sshd -t
... no output on success ...
$ sudo journalctl -b --no-pager | grep -i securetty

sshd -t only validates SSH daemon syntax, it does not test a PAM login. Use whatever non-destructive validation your service provides. The journal command is a read-only diagnostic and may show nothing if the module isn't logging at the current level.

6. Recover without guessing

Recovery

If an approved login fails, use the still-open administrative session or the provider's console. Restore the PAM file first, then the terminal list if needed:

$ sudo cp -a /etc/pam.d/login.before-pam-securetty /etc/pam.d/login
$ sudo cp -a /etc/securetty.bak /etc/securetty
$ sudo chmod 0600 /etc/securetty
$ sudo chown root:root /etc/securetty

If /etc/securetty.bak never existed because the original file was absent, don't copy it. Remove the new list only after double-checking the path is exactly the file you mean to remove:

$ sudo test -f /etc/securetty.bak || sudo rm -- /etc/securetty

That removal is irreversible unless another backup exists. If the module reports a service error, check the securetty path is readable, a normal file, and not world-writable. If root is rejected when it shouldn't be, check the PAM_TTY value and the exact terminal name before you touch the policy again.

Done means

  • Service identified. You confirmed the exact PAM service and the installed Linux-PAM package version.
  • Terminal list secured. Terminal names were chosen deliberately and the securetty file verified as root-owned and not world-writable.
  • Rule placed correctly. pam_securetty.so is an auth required rule before any sufficient authentication method.
  • Console exception understood. You know the default kernel-console exception and chose noconsole only when the file needs to be authoritative.
  • Second session verified first. A second session confirmed the intended result before the original administrative session was closed.
  • Rollback kept. A tested rollback copy of both the PAM service file and the terminal list still exists.