Infra, Illustrated.
LINUX FOUNDATION · SECURITY CONSOLE

Security & Access Control

Untangle Linux security architecture by exploring how independent layers—DAC, ACLs, capabilities, MAC, and firewalls—converge on every process and file operation.

← Back to Linux MapREFERENCE HOST · devbox-01DEEP DIVE · FOUNDATIONALPublished Sep 15, 2026 · Reviewed Sep 18, 2026
CHAPTER 07 / 08 · 7 VISUAL LESSONS

What this chapter builds

Linux security is a set of applicable decisions, not one onion where passing an inner layer defeats an outer layer. This chapter separates DAC, ACLs, capabilities, LSMs, seccomp, network policy, and audit evidence.

By the end, you can

  • Identify which control can decide an operation
  • Explain capability sets without treating root as magic
  • Distinguish SELinux and AppArmor policy models
  • Collect evidence for file, network, and authentication denials

Objects to keep straight

credentials and capabilitiesLSM hooksseccomp filterNetfilter hookaudit context

Applied task: Explain a file read where DAC allows but an enforcing LSM denies.

SCENARIO · devbox-01 / nginxControl layers
OBJECT DAC & POSIX ACLsSTATE ready to inspectOWNER kernel access controls
01 / SECURITY · SYSTEM MODEL

Linux security is a multi-layered gatekeeper; every check must pass.

How many independent security subsystems must approve an operation before the kernel grants access?

DEVBOX-01 · SYSTEM MODELREADY TO INSPECT
LAYER 1: DACDiscretionary Access ControlOwner/Group/Other mode bits (chmod)
LAYER 2: ACLsPOSIX Access Control ListsGranular per-user/group permissions (getfacl)
LAYER 3: CAPSLinux CapabilitiesDeconstructed root privileges (CAP_NET_BIND_SERVICE)
LAYER 4: MACMandatory Access ControlSELinux contexts / AppArmor profiles (type enforcement)
LAYER 5: SECCOMPSyscall BPF SandboxRestricts allowed kernel system calls
Security checks are cumulative. DAC permission does not override an AppArmor denial; a capability does not bypass a Seccomp filter.

Linux does not possess a single "allow" switch. When a process attempts to open a file or execute a syscall, the request traverses a series of completely independent kernel security layers. Discretionary Access Control (DAC) evaluates standard permissions; Linux capabilities determine process superpowers; Linux Security Modules (LSM) enforce mandatory MAC policies; and Seccomp filters syscall vectors. A single "Deny" from any layer immediately aborts the operation with EACCES or EPERM, regardless of what the other layers allow.

Model scope. A UID 0 process often starts with broad capabilities, but its effective capability sets, user namespace, LSM policy, seccomp filters, and other boundaries determine what a particular operation can do.

INSPECT · su -s /bin/bash -c "cat /etc/shadow" www-data 2>&1
cat: /etc/shadow: Permission denied
NEXT PROBE · grep Cap /proc/$$/status
CapInh:	0000000000000000
CapPrm:	0000000000000000
CapEff:	0000000000000000
CapBnd:	000001ffffffffff
Primary source ↗
02 / SECURITY · COMPARISON MODEL

Discretionary Access Control evaluates permissions via a strict first-match hierarchy.

How does the VFS check file permissions, and why doesn't group membership help if you own the file?

DEVBOX-01 · COMPARISON MODELREADY TO INSPECT
STEP 1: OWNER MATCHIs EUID == file.owner?YES → Apply Owner mode (rwx) & STOP
STEP 2: GROUP MATCHIs GID/Groups == file.group?YES → Apply Group mode (rwx) & STOP
STEP 3: OTHER MATCHNeither identity matches?Apply Others mode (rwx)
CAPABILITY CHECKSPrivileged credentialsMay override specific DAC checks; other controls still apply
DAC evaluation stops at the first matching identity class: Owner -> Group -> Others. If you own the file, group permissions are never evaluated.

Linux Discretionary Access Control operates via the classic 9-bit mode matrix (rwxrwxrwx) stored in the inode. The kernel VFS evaluates identity classes in a strict, non-cumulative hierarchy: if the process Effective UID matches the file owner, the owner permissions apply immediately and evaluation stops. If the owner permissions do not permit reading (e.g. 0044), access is denied immediately—the kernel never checks whether your group has read permissions! Extended ACLs (setfacl/getfacl) add granular per-user and per-group rules on top of the base mode bits.

Model scope. If a file is owned by your user with mode 0000, you cannot read it even if the group permissions are 0777. The owner check matches and halts evaluation.

INSPECT · stat -c "%a %A %U:%G" /etc/shadow
640 -rw-r----- root:shadow
NEXT PROBE · getfacl /var/log/syslog 2>/dev/null || echo "No ACLs set"
# file: /var/log/syslog
# owner: syslog
# group: adm
user::rw-
group::r--
other::---
Primary source ↗
03 / SECURITY · ARCHITECTURAL COMPARISON

Mandatory Access Control confines processes based on security labels and paths.

How do SELinux and AppArmor enforce mandatory access rules even against root processes?

DEVBOX-01 · ARCHITECTURAL COMPARISON4 ENTITIES COMPARED
01DAC (Traditional)

Owners control ordinary file modes. Privileged capability checks can override specific DAC denials, but do not automatically cancel other applicable controls.

$ ls -l /etc/shadow
-rw-r----- 1 root shadow 1234 Sep 16 10:00 /etc/shadow
02SELinux (Label-Based)

Assigns security contexts (user:role:type:level) to every process and file. Strict Type Enforcement policy matrix dictates which process domain types can access which target file types.

$ ls -Z /etc/nginx/nginx.conf 2>/dev/null || echo "system_u:object_r:httpd_config_t:s0"
system_u:object_r:httpd_config_t:s0 /etc/nginx/nginx.conf
03AppArmor (Path-Based)

Profiles attach directly to executable paths (/usr/sbin/nginx) and declare allowed filesystem paths, capabilities, and network calls. Default on Debian and Ubuntu.

$ aa-status 2>/dev/null | grep nginx || echo "nginx profile (enforce)"
  /usr/sbin/nginx (enforce)
04LSM Denial Audit (AVC)

When a confined process attempts an unapproved action, the kernel LSM hook logs an Access Vector Cache (AVC) denial to the system audit stream.

$ grep -i "avc: denied" /var/log/audit/audit.log 2>/dev/null || journalctl -t audit -g "denied" -n 1
type=AVC msg=audit(1694772600.123:45): avc: denied { read } for pid=421 comm="nginx" name="shadow" dev="sda1" ino=123 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:shadow_t:s0 tclass=file permissive=0
MAC enforces the principle of least privilege against processes. Even a compromised root daemon cannot touch files outside its declared security profile.

Mandatory Access Control (MAC) addresses the critical flaw of traditional UNIX security: that root can do anything, and users control file access. With MAC, the kernel enforces a centralized security policy across the entire machine. Even if an attacker compromises a web daemon running as root, SELinux or AppArmor prevents the process from reading /etc/shadow, accessing home directories, or opening arbitrary network sockets.

Model scope. Disabling SELinux ("setenforce 0") or disabling AppArmor is an operational antipattern. Use "audit2why" or "aa-logprof" to generate surgical policy exceptions instead.

INSPECT · sestatus 2>/dev/null || aa-status 2>/dev/null || echo "SELinux/AppArmor active"
SELinux status:                 enabled
Current mode:                   enforcing
Loaded policy name:             targeted
NEXT PROBE · grep -i avc /var/log/audit/audit.log 2>/dev/null | tail -n 1 || echo "No recent AVC denials"
# Audit stream clean; no active confinement violations
Primary source ↗
04 / SECURITY · RUNBOOK STATE MACHINE

Baseline host hardening minimizes the attack surface through 5 core controls.

What baseline security posture must be established on a modern Linux server before exposing it to the network?

DEVBOX-01 · RUNBOOK STATE MACHINEACTION 01 / 05 ACTIVE
RUNBOOK ACTION STEPPER

Action 01: Disable Passwords & Root SSH

$ sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config && sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config

Field Note: Enforces asymmetric Ed25519/RSA cryptographic key authentication and blocks automated brute-force attacks against the root account.

SSH keys over passwords, default-drop firewall rules, automated patching, and systemd service sandboxing form the core defense baseline.

A fresh Linux instance exposed to the internet will experience automated scanning and brute-force attacks within minutes. Host hardening reduces the attack surface: cryptographic SSH keys replace vulnerable passwords, a default-drop host firewall blocks probing, automatic security updates eliminate known CVE windows, and systemd sandboxing confines daemons in restricted namespaces.

Model scope. Cloud provider security groups (AWS SG, GCP VPC firewall) operate at the hypervisor layer outside the VM and should always provide the primary ingress perimeter.

INSPECT · ss -lntp
LISTEN 0 128   0.0.0.0:22   0.0.0.0:* users:(("sshd",pid=710,fd=3))
LISTEN 0 511   0.0.0.0:443  0.0.0.0:* users:(("nginx",pid=750,fd=6))
NEXT PROBE · sysctl net.ipv4.tcp_syncookies kernel.dmesg_restrict
net.ipv4.tcp_syncookies = 1
kernel.dmesg_restrict = 1
Primary source ↗
05 / SECURITY · SYSTEM MODEL

Inbound packets cross 4 distinct defense boundaries before reaching an application socket.

Why does an external client fail to connect even though ss -tulpn confirms the service is listening on port 443?

DEVBOX-01 · SYSTEM MODELREADY TO INSPECT
1. CLOUD VPCSecurity GroupHypervisor ingress packet drop
2. HOST FIREWALLnftables / iptablesKernel Netfilter INPUT hook
3. BIND ADDRESS0.0.0.0 vs 127.0.0.1Interface listener filter
4. TCP BACKLOGSocket Queueaccept() delivery to worker
Troubleshoot network blocks from the outside in: Cloud Security Group -> Host nftables -> Socket Bind IP -> Accept Backlog.

Network security is deeply layered. Even if an application is running and bound to port 443, incoming packets must survive a gauntlet: the cloud provider's hypervisor security group, the host operating system's Netfilter/nftables firewall rules, interface binding restrictions, and kernel socket queue capacity. Troubleshooting connection timeouts requires validating each boundary in order from the outside network inward.

Model scope. Container runtimes and Kubernetes networking components may install Netfilter rules or use other dataplanes. Their hook priority and forwarding behavior can interact unexpectedly with host firewall front ends, so inspect the effective ruleset and actual packet path.

INSPECT · iptables -S INPUT 2>/dev/null || nft list ruleset 2>/dev/null || echo "Host firewall active"
-P INPUT DROP
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
NEXT PROBE · ss -lnt 'sport = :443'
State  Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0      511    0.0.0.0:443      0.0.0.0:*
Primary source ↗
06 / SECURITY · PIPELINE WALKTHROUGH

Authentication, privilege, and audit records provide evidence—if you preserve them.

Where does the system record successful logins, brute-force attempts, sudo commands, and kernel audit events?

DEVBOX-01 · EXECUTION PIPELINESTAGE 01 / 04 ACTIVE
INTERACTIVE STAGE STEPPER

Stage 01: /var/log/auth.log (or /var/log/secure on RHEL) records PAM authentication events, public key logins, and rejected password attempts.

$ cat /var/log/auth.log | grep sshd | tail -n 3
Sep 16 10:00:01 devbox sshd[710]: Accepted publickey for darshan from 192.168.1.5 port 54321 ssh2: ED25519 SHA256:...
Sep 16 10:01:22 devbox sshd[715]: Invalid user admin from 10.0.0.9 port 43210
Sep 16 10:01:22 devbox sshd[715]: Connection closed by invalid user admin 10.0.0.9 port 43210 [preauth]

/var/log/auth.log (or /var/log/secure on RHEL) records PAM authentication events, public key logins, and rejected password attempts.

Monitor auth.log for login attempts, journalctl _COMM=sudo for command auditing, and ausearch for tamper-resistant kernel audit logs.

Linux security evidence comes from complementary subsystems: PAM-aware services may record authentication events in the journal or distribution-specific files; sudo records configured command events; wtmp stores login history; and the kernel audit framework emits structured records. The login UID helps attribute activity across many setuid transitions, but local logs are not inherently immutable or tamper-proof.

Model scope. Local log files can be modified or erased if an attacker achieves root access. Production systems must forward logs immediately over TLS to a centralized SIEM or remote syslog server.

INSPECT · grep -i "Failed password" /var/log/auth.log 2>/dev/null | tail -n 5 || journalctl -u ssh -g "Failed password" -n 5 --no-pager
# Displays recent failed password attempts from brute-force scanners
NEXT PROBE · last -n 3
darshan  pts/0        192.168.1.5      Wed Sep 16 10:00   still logged in
reboot   system boot  6.1.0-11-amd64   Wed Sep 16 08:00   still running
Primary source ↗
07 / SECURITY · EVIDENCE BOARD

A systematic chain of evidence to diagnose "Permission denied" errors.

When an application receives EACCES (Permission denied), how do you pinpoint the exact barrier blocking access?

DEVBOX-01 · EVIDENCE BOARDREADY TO INSPECT
Never use chmod 777. Use namei to test directory traversal, inspect process credentials, and check audit logs for MAC denials.

Diagnosing blocked file access requires methodical investigation. Begin by identifying the exact numeric UID and GIDs of the worker process. Next, use "namei -om" to verify that the process possesses execute (+x) permissions on every parent directory in the path. Then inspect the target file's owner, group, and mode bits. Finally, check if the filesystem is mounted read-only (ro) or if SELinux/AppArmor recorded an AVC denial in the audit log.

Model scope. Filesystems mounted with "noexec", "nosuid", or "ro" in /etc/fstab will block execution or write operations regardless of file permissions.

INSPECT · namei -om /srv/app/config.json
f: /srv/app/config.json
 drwxr-xr-x root     root     /
 drwxr-xr-x root     root     srv
 drwxr-x--- root     appgroup app
 -rw-r----- root     appgroup config.json
NEXT PROBE · sudo -u www-data stat /srv/app/config.json 2>&1
stat: cannot stat '/srv/app/config.json': Permission denied
Primary source ↗