Chapter 4: Identity, Authentication, and Access Control
Chapter 4: Identity, Authentication, and Access Control
Identity and access management is the gateway to Linux administration. An attacker who compromises valid credentials or exploits a flaw in authentication mechanisms bypasses network perimeters and lands directly in an authenticated session.
This chapter establishes a robust identity, authentication, and privilege-delegation framework. We examine secure user account lifecycle management, password hashing and aging policies, the Pluggable Authentication Modules (PAM) architecture, production OpenSSH server hardening, controlled sudo delegation, multi-factor authentication (MFA), and service account compartmentalization.
User and Group Administration for Security
Default user provisioning frequently creates unnecessary accounts and grants excessive permissions. Secure user lifecycle management adheres to the following principles:
Unique Identity Enforcement: Every human operator must possess an individual account with a unique UID. Shared accounts (e.g., sharing the
ubuntuorrootaccount among multiple team members) eliminate non-repudiation and prevent reliable auditing.Explicit Shell Restrictions: Service accounts that run background daemons must never possess interactive login shells. Assign them
/usr/sbin/nologinor/bin/false:# Create a dedicated, unprivileged system user without an interactive shell sudo useradd -r -s /usr/sbin/nologin -d /var/lib/worker -M -c "Background Worker" workerLocking Inactive and Unused Accounts: Stale accounts represent dormant vectors for exploitation. Lock unused default distribution accounts:
# Lock password and expire account sudo passwd -l daemon sudo chage -E 0 daemon
Password Policy and Credential Security
When password authentication cannot be eliminated entirely, passwords must be protected using modern hashing algorithms and complexity constraints.
Modern Password Hashing (yescrypt & SHA-512)
Legacy hashing algorithms like MD5 ($1$) and DES are completely obsolete and can be brute-forced in seconds using consumer GPUs. Modern enterprise distributions default to yescrypt ($y$) or SHA-512 ($6$):
# /etc/pam.d/common-password
password [success=1 default=ignore] pam_unix.so obscure yescrypt rounds=11Enforcing Quality with pam_pwquality
Configure minimum password complexity requirements in /etc/security/pwquality.conf:
# /etc/security/pwquality.conf
# Minimum password length
minlen = 14
# Require at least one uppercase letter
ucredit = -1
# Require at least one lowercase letter
lcredit = -1
# Require at least one digit
dcredit = -1
# Require at least one special character
ocredit = -1
# Reject passwords with consecutive repeated characters
maxrepeat = 3
# Enforce dictionary check
dictcheck = 1Password Aging in /etc/login.defs
Control credential lifespans globally in /etc/login.defs:
PASS_MAX_DAYS 90
PASS_MIN_DAYS 7
PASS_WARN_AGE 14Pluggable Authentication Modules (PAM)
PAM is the dynamic framework that handles authentication, authorization, credential management, and session setup across all Linux login services (SSH, local consoles, GUI display managers, sudo).
┌────────────────────────────────────────────────────────────────────────┐
│ THE PAM STACK ARCHITECTURE │
│ │
│ Application (e.g., sshd, sudo, login) │
│ │ │
│ ▼ calls pam_authenticate() │
│ PAM Configuration Layer (/etc/pam.d/<service>) │
│ ├─► auth (Verify identity: password, token, biometrics) │
│ ├─► account (Validate account status: expiration, time) │
│ ├─► password (Update authentication tokens / hashes) │
│ └─► session (Prepare environment: mounts, limits, motd) │
└────────────────────────────────────────────────────────────────────────┘
PAM Control Flags
Each module inside a PAM service stack is governed by a control flag that dictates execution flow:
required: The module must succeed. If it fails, the stack continues executing subsequent modules to obscure which check failed, but access is ultimately denied.requisite: The module must succeed. If it fails, the stack terminates immediately and denies access.sufficient: If the module succeeds and no previousrequiredmodule failed, the stack succeeds immediately without evaluating subsequent modules.optional: Success or failure is ignored unless it is the only module in the stack.
Hardening Example: Enforcing Account Lockout with pam_faillock
Protect against brute-force password guessing by locking accounts after repeated authentication failures:
# Add to /etc/pam.d/common-auth
auth required pam_faillock.so preauth silent audit deny=5 unlock_time=900
auth [success=1 default=bad] pam_unix.so
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900
auth sufficient pam_faillock.so authsucc# View and unlock locked accounts
sudo faillock --user alice
sudo faillock --user alice --resetSSH: Secure Remote Administration
The OpenSSH daemon (sshd) is the primary administrative entry point into Linux infrastructure. A hardened sshd_config eliminates legacy cryptographic algorithms, prevents credential abuse, and enforces strict operational boundaries.
# /etc/ssh/sshd_config.d/99-hardened-sshd.conf
# Protocol and Port
Port 22
Protocol 2
# Authentication Constraints
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
PubkeyAuthentication yes
AuthenticationMethods publickey
# Limit Authentication Attempts
MaxAuthTries 3
MaxSessions 4
LoginGraceTime 30
# Disable Insecure Forwarding by Default
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
# Idle Timeout (Terminate unresponsive sessions after 15 minutes)
ClientAliveInterval 300
ClientAliveCountMax 3
# Modern, Post-Quantum & Resilient Cryptography
KexAlgorithms sntrup761x25519-sha512@openssh.com,curve25519-sha256,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com
# Whitelist Allowed Administrative Groups
AllowGroups wheel sudo ssh-adminsAfter modifying the configuration, validate syntax before restarting the daemon:
sudo sshd -t
sudo systemctl reload sshSudo and Privilege Escalation Control
The sudo utility enables granular privilege delegation without sharing the root password. However, misconfigured sudoers rules are one of the most common vectors for privilege escalation.
Best Practices for /etc/sudoers
Never edit
/etc/sudoersdirectly with a normal editor: Always usevisudo, which validates syntax and locks the file against race conditions.Use Modular Drop-Ins: Place site-specific rules in
/etc/sudoers.d/, ensuring files are mode0440.Avoid Wildcard Matching (
*): Path wildcards allow users to bypass restrictions via directory traversal (../) or flags.Disable Dangerous Shell Escapes: Restrict utilities that have built-in shell escape features (e.g.,
vi,less,awk,find):# INSECURE: Grants instant root via ':!/bin/bash' inside vi alice ALL=(ALL) /usr/bin/vi /etc/nginx/nginx.conf # SECURE: Use sudoedit to edit files without granting binary execution alice ALL=(ALL) sudoedit /etc/nginx/nginx.confLog All Sudo Invocations:
Defaults log_input, log_output Defaults logfile="/var/log/sudo.log"
Multi-Factor Authentication Integration
For high-security bastion hosts and production management nodes, passwords or SSH keys alone should be paired with Time-based One-Time Passwords (TOTP) or hardware tokens (FIDO2/YubiKey).
┌────────────────────────────────────────────────────────────────────────┐
│ SSH MULTI-FACTOR FLOW │
│ │
│ SSH Client ──► 1. Present Ed25519 Public Key ──► sshd verifies │
│ │ │
│ ▼ OK │
│ SSH Client ◄── 2. Prompt: "Enter TOTP verification code" │
│ │ │
│ ▼ │
│ Operator inputs 6-digit code ──► pam_google_authenticator verifies │
│ │ │
│ ▼ OK │
│ Session Granted │
└────────────────────────────────────────────────────────────────────────┘
Configuring TOTP with Google Authenticator PAM
Install PAM TOTP module:
sudo apt install -y libpam-google-authenticatorInitialize TOTP for the user account:
google-authenticator -t -d -f -r 3 -R 30 -WConfigure PAM for SSH in
/etc/pam.d/sshd:# Add at the top of /etc/pam.d/sshd auth required pam_google_authenticator.so nullokEnable multi-factor authentication in
/etc/ssh/sshd_config:KbdInteractiveAuthentication yes AuthenticationMethods publickey,keyboard-interactive
Service Accounts and Privilege Separation
Daemons and automated background jobs must operate with strictly minimal privileges:
- Unique UID/GID per Service: Never group multiple services under a common user (e.g., running both Apache and custom Python scripts under
www-data). - No Login and No Password: Ensure
passwd -S <user>indicatesL(locked) orNP(no password). - Dedicated Directory Boundaries: Restrict service account ownership to specific paths under
/var/lib/<service>,/etc/<service>, and/run/<service>. Set directory permissions to0750or0700to prevent other local accounts from inspecting data or sockets.