Debian PAM Limits: Control User Process Resources

The Debian operating system uses the Pluggable Authentication Modules (PAM) framework to enforce process resource constraints on users and groups upon login. By leveraging the pam_limits.so module alongside configuration files located in /etc/security/, Debian allows system administrators to place soft and hard ceilings on system resources such as open file descriptors, maximum processes, and memory consumption. This article explains the underlying mechanisms Debian uses to load PAM limits, the syntax for defining resource thresholds, and the operational differences between interactive sessions and system services.

The Role of pam_limits.so in Debian

In Debian, PAM manages authentication, account verification, password changes, and session setup. Resource boundaries are handled specifically during the session management phase by the pam_limits.so module.

When a user initiates an interactive session (such as through SSH, local virtual consoles, or the graphical display manager), PAM reads service-specific configurations in the /etc/pam.d/ directory. For example, /etc/pam.d/login, /etc/pam.d/sshd, and /etc/pam.d/su include session definitions that invoke:

session required pam_limits.so

When this module executes, it reads kernel system parameters and updates the calling process’s resource limits using the standard setrlimit() Linux system call before spawning the user's login shell. Child processes spawned by the shell subsequently inherit these restricted resource limits.

Configuration Files and Syntax

Debian organizes PAM limits within the /etc/security/ hierarchy:

  1. /etc/security/limits.conf: The primary configuration file containing global definitions and documentation.
  2. /etc/security/limits.d/: A drop-in directory where packages or administrators can place individual .conf files. Files in this directory are read alphabetically and override settings in the main limits.conf file.

Each configuration entry follows a strict four-column format:

<domain>    <type>    <item>    <value>
  • Domain: Specifies who the rule applies to. This can be a username, a group name prefixed with an @ symbol (e.g., @developers), a wildcard (*) matching all users, or % for maxlogins syntax.
  • Type: Defines whether the threshold is soft or hard. A soft limit is the actual enforced ceiling at login, which the user can alter via shell built-ins up to the hard limit. A hard limit can only be modified by the root user. The - character indicates that both soft and hard limits are set to the same value.
  • Item: The specific kernel resource being managed. Common examples include:
    • nofile: Maximum number of open file descriptors.
    • nproc: Maximum number of processes/threads available to the user.
    • as: Address space limit (total virtual memory).
    • memlock: Maximum locked-in-memory address space.
    • core: Maximum size of core dump files.
  • Value: The numerical boundary for the specified item, or unlimited.

For example, to prevent fork bombs and file exhaustion for standard users on Debian:

*               hard    nproc          2048
*               soft    nproc          1024
@developers     hard    nofile         65536
@developers     soft    nofile         32768

Systemd Integration and Limitations

Because Debian uses systemd as its default init system, the application of pam_limits depends on how a process is launched:

  • Interactive User Sessions: Interactive sessions managed by systemd-logind load PAM modules via the PAM stack, meaning settings in /etc/security/limits.conf and /etc/security/limits.d/ apply normally.
  • System Services (Daemons): System services managed directly by systemd bypass the PAM stack entirely. Systemd sets its own process limits through unit directives like LimitNOFILE= or LimitNPROC=, or globally in /etc/systemd/system.conf. Consequently, rules configured for service accounts (like www-data or postgres) inside limits.conf will not take effect unless the service uses PAM to open a session (e.g., via PAMName=).

Verifying Active Limits

Once configured, an administrator or user can verify that Debian is enforcing PAM limits by opening a session and querying the shell's built-in ulimit command:

  • Run ulimit -a to view all currently active soft limits.
  • Run ulimit -Ha to view the associated hard limits.

To inspect the live limits applied to any running process, inspect the process's /proc entry:

cat /proc/<PID>/limits

This output displays the kernel-level soft limit, hard limit, and units for every resource assigned to that process, confirming whether pam_limits.so applied the requested policies.