The principle of least privilege applies to capabilities: grant only what is needed. CAP_SYS_ADMIN Is especially dangerous as it encompasses many sub-capabilities. Use more specific capabilities Whenever possible.
SELinux (Security-Enhanced Linux) is a mandatory access control (MAC) framework integrated into the Linux kernel. Unlike DAC (Discretionary Access Control, i.e., standard Unix permissions), MAC Policies are enforced by the kernel and cannot be overridden by the file owner.
Mode Enforcement Description enforcingYes Policy violations are blocked and logged permissiveNo Policy violations are logged but not blocked (audit mode) disabledNo SELinux is completely disabled (not recommended)
# Change mode (temporary)
setenforce 0 # permissive
# Set default mode (persistent)
Every file, process, and network socket has an SELinux context (also called a label) consisting of Four parts:
system_u:object_r:httpd_sys_content_t:s0
Component Example Description User system_u``user_uSELinux user identity Role object_r``staff_rRole determines which types can be accessed Type httpd_sys_content_tType enforcement policy (most important component) Level s0``s0-s15:c0.c1023MLS/MCS level (for multi-level security)
chcon -t httpd_sys_content_t /var/www/html/index.html
# Restore default context (from policy)
restorecon -Rv /var/www/html/
# Show default context for a path
matchpathcon /var/www/html/index.html
Booleans are runtime toggles that modify policy behavior without changing the policy itself:
getsebool httpd_can_network_connect
# Set boolean (temporary)
setsebool httpd_can_network_connect 1
# Set boolean (persistent)
setsebool -P httpd_can_network_connect 1
# httpd_can_network_connect — allow Apache to connect to network
# httpd_can_network_connect_db — allow Apache to connect to databases
# httpd_read_user_content — allow Apache to read user home dirs
# sshd_permit_root_login — allow root login via SSH
# ftpd_full_access — allow full FTP access
# View audit log for SELinux denials
ausearch -m AVC,USER_AVC,SELINUX_ERR -ts recent
# Search for specific denial
ausearch -m AVC -ts recent | grep httpd
# Generate human-readable report from audit log
sealert -a /var/log/audit/audit.log
# Check if SELinux is blocking a specific operation
grep " denied " /var/log/audit/audit.log
# 2. Generate troubleshooting report
sealert -l & lt ; audit-event-id & gt ;
# restorecon -Rv /path/ — fix file context
# setsebool -P boolean 1 — enable required boolean
# semanage fcontext -a -t type "/path(/.*)?" — add permanent context rule
# semanage port -a -t type -p tcp 8080 — allow service to bind port
Policy Description targetedConfines specific system services (httpd, mysqld, etc.) mlsMulti-Level Security — mandatory for classified environments minimumMinimal policy for embedded systems
AppArmor is an alternative MAC framework that uses path-based profiles (unlike SELinux’s label-based Approach). It is the default on Ubuntu, SUSE, and some other distributions.
aa-status | grep profiles
# View profile for a process
cat /proc/ $PID /attr/current
apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx
# Enforce mode (block violations)
aa-enforce /etc/apparmor.d/usr.sbin.nginx
# Complain mode (log only)
aa-complain /etc/apparmor.d/usr.sbin.nginx
aa-disable /etc/apparmor.d/usr.sbin.nginx
apparmor_parser -r /etc/apparmor.d/ *
#include <tunables/global>
#include <abstractions/base>
#include <abstractions/nameservice>
capability net_bind_service,
Aspect SELinux AppArmor Model Label-based (security context on inodes) Path-based (profiles reference paths) Policy Policy compiled from TE rules Profiles as plain text Learning Strict — must write policy explicitly Can generate profiles from log data Complexity Higher learning curve Simpler to configure Default on RHEL, Fedora, CentOS, Debian Ubuntu, SUSE Granularity Finer (type enforcement) Coarser (path matching) File moves Context preserved with inode Broken if file moves to new path
Seccomp (secure computing mode) restricts the system calls a process can make. When combined with BPF (Berkeley Packet Filter), it provides fine-grained syscall filtering.
Mode Description disabledNo restrictions (default) strictOnly read``write``_exit``sigreturn allowed filterBPF program defines allowed syscalls (most flexible)
# Docker uses seccomp profiles by default
docker run --rm --security-opt seccomp=default.json nginx
# Use unconfined (no seccomp — NOT recommended for production)
docker run --rm --security-opt seccomp=unconfined nginx
docker run --rm --security-opt seccomp=/path/to/profile.json nginx
# Allow only specific system calls
SystemCallFilter = @system-service @basic-io
SystemCallFilter = ~@mount @debug @privileged
# Architecture restriction
SystemCallArchitectures = native
SystemCallFilter = ~mount umount2 pivot_root swapon swapoff
The Linux Audit framework provides a mechanism for tracking security-relevant system events. It is Controlled by auditd and configured via auditctl rules.
# Watch a file for access
auditctl -w /etc/passwd -p rwxa -k identity_changes
# Watch a directory recursively
auditctl -w /etc/sudoers.d/ -p wa -k sudoers_changes
# Monitor system calls by user
auditctl -a always,exit -F arch=b64 -S open,openat -F uid= 0 -k root_file_access
# Monitor execution of a specific binary
auditctl -a always,exit -F path=/usr/bin/sudo -F perm=x -k sudo_execution
# Monitor failed file access
auditctl -a always,exit -F arch=b64 -S open,openat -F exit=-EACCES -k access_denied
# Monitor network connections
auditctl -a always,exit -F arch=b64 -S connect -k network_connections
# /etc/audit/rules.d/audit.rules
-w /etc/passwd -p rwxa -k identity_changes
-w /etc/shadow -p rwxa -k identity_changes
-w /etc/sudoers -p rwxa -k identity_changes
ausearch -m AVC -ts recent # SELinux denials
ausearch -m USER_LOGIN -ts recent # login events
ausearch -k identity_changes # by key
ausearch -sv no # unsuccessful events
ausearch -a 1234 # by audit event ID
aureport -x # executable summary
aureport -au # audit events by user
aureport -m # by audit event type
aureport -k # by audit key
log_file = /var/log/audit/audit.log
max_log_file_action = ROTATE
# View current kernel parameters
sysctl -a | grep net.ipv4
sysctl net.ipv4.ip_forward
# Set parameter (temporary)
sysctl -w net.ipv4.ip_forward= 1
# Persistent configuration
# /etc/sysctl.d/99-hardening.conf
# Disable IP forwarding (unless needed)
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Enable reverse path filtering (anti-spoofing)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP redirect sending
net.ipv4.conf.all.send_redirects = 0
# Enable SYN cookies (SYN flood protection)
net.ipv4.tcp_syncookies = 1
# Log martian packets (packets with impossible source addresses)
net.ipv4.conf.all.log_martians = 1
# Disable IPv6 if not used
net.ipv6.conf.all.disable_ipv6 = 1
# Restrict kernel pointer access
kernel.dmesg_restrict = 1
kernel.core_pattern = |/bin/false
# ASLR (Address Space Layout Randomization) — already enabled by default
kernel.randomize_va_space = 2
# Restrict loading kernel modules (if not needed)
kernel.modules_disabled = 1 # cannot be reversed without reboot!
# /etc/ssh/sshd_config — recommended settings
# Protocol and authentication
PermitRootLogin prohibit-password # or 'no'
PasswordAuthentication no # key-only auth
AuthorizedKeysFile .ssh/authorized_keys
ChallengeResponseAuthentication no
# Restrict to specific users/groups
# Disable unused features
# Reload SSH configuration
# Test configuration before reload
The most common SELinux issue is a service being denied access to a file or port because the SELinux Context is wrong. Symptoms include “Permission denied” errors that appear even when standard Unix Permissions are correct:
ausearch -m AVC -ts recent
sealert -l & lt ; audit-id & gt ;
# Quick fix (not recommended for production)
setenforce 0 # switch to permissive to confirm SELinux is the cause
restorecon -Rv /path/to/files
semanage fcontext -a -t httpd_sys_content_t " /custom/path(/.*)? "
restorecon -Rv /custom/path
CAP_SYS_ADMIN covers many sub-operations (mount, pivot_root, IPC, etc.). Granting it is equivalent To granting near-root access. Always use more specific capabilities:
setcap cap_sys_admin=+ep /usr/bin/myapp
# CORRECT — use specific capabilities
setcap cap_net_bind_service=+ep /usr/bin/myapp
PAM processes modules in the order they appear. A sufficient module early in the stack can Short-circuit the entire auth process:
# WRONG — pam_unix.so is sufficient, so pam_faillock is never reached
auth sufficient pam_unix.so
auth required pam_faillock.so
# CORRECT — check faillock first
auth required pam_faillock.so preauth
auth sufficient pam_unix.so
auth required pam_faillock.so authfail
auditctl rules are not persistent. Rules must be placed in /etc/audit/rules.d/ to survive Reboots:
# WRONG — rules lost on reboot
auditctl -w /etc/passwd -p rwxa -k identity
# CORRECT — persistent rule in /etc/audit/rules.d/audit.rules
echo " -w /etc/passwd -p rwxa -k identity " >> /etc/audit/rules.d/audit.rules
SSH requires strict permissions on key files and directories. If permissions are too open, SSH will Refuse to use the key:
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys
# "Permissions 0644 for '/home/user/.ssh/id_rsa' are too open"
Setting SELINUX=disabled in /etc/selinux/config requires a reboot and relabels the filesystem With no SELinux contexts, making it hard to re-enable. Instead, use SELINUX=permissive during Troubleshooting and switch back to enforcing when done:
# Temporary switch (no reboot needed)
setenforce 0 # permissive
# NEVER set SELINUX=disabled unless absolutely certain
Historically, /etc/passwd contained password hashes. Modern systems store hashes in /etc/shadow (readable only by root). If you see a hash in /etc/passwdThe system is misconfigured:
# Check: second field should be 'x'
# root:x:0:0:root:/root:/bin/bash ← CORRECT (x means shadow)
# root:$6$...:0:0:root:/root:/bin/bash ← WRONG (hash in passwd)
setenforce 0 changes the mode only for the running system. After a reboot, the system returns to The mode specified in /etc/selinux/config. Do not rely on setenforce for persistent Configuration changes.
This topic covers the core concepts of linux security, including underlying theory, practical implementation, and key applications.
Key concepts include:
TCP/IP and the OSI model network topologies protocols (HTTP, FTP, SMTP) encryption and security client-server and peer-to-peer Understanding these concepts thoroughly is essential for both examinations and practical programming, and requires both theoretical knowledge and hands-on practice.
Worked examples demonstrating the application of key concepts are covered in the detailed sub-pages linked above.