Understanding Linux Security Architecture

Linux security operates on multiple layers, providing robust protection through a combination of traditional Unix permissions, mandatory access controls (MAC), and application confinement systems. This comprehensive approach ensures that even if one security mechanism fails, others remain in place to protect the system.

Linux Security: Complete Guide to Permissions, SELinux, and AppArmor Protection

Linux File Permissions: The Foundation

Understanding Permission Types

Linux file permissions control who can read, write, or execute files and directories. Every file has three permission sets: owner (user), group, and others. Each set contains three permission types:

  • Read (r): View file contents or list directory contents
  • Write (w): Modify file contents or create/delete files in directory
  • Execute (x): Run executable files or enter directories

Permission Representation

Permissions are displayed in two formats: symbolic notation (letters) and octal notation (numbers).

# Example file listing
$ ls -l example.txt
-rwxr--r-- 1 john developers 1024 Aug 28 18:04 example.txt

# Breaking down the permissions:
# - : Regular file (d for directory, l for symlink)
# rwx : Owner permissions (read, write, execute)
# r-- : Group permissions (read only)
# r-- : Others permissions (read only)

Octal Permission Values

Permission Octal Value Binary
— (none) 0 000
–x (execute) 1 001
-w- (write) 2 010
-wx (write + execute) 3 011
r– (read) 4 100
r-x (read + execute) 5 101
rw- (read + write) 6 110
rwx (all permissions) 7 111

Managing Permissions with chmod

# Set permissions using octal notation
$ chmod 755 script.sh          # rwxr-xr-x
$ chmod 644 document.txt       # rw-r--r--
$ chmod 600 private_key        # rw-------

# Set permissions using symbolic notation
$ chmod u+x script.sh          # Add execute for owner
$ chmod g-w file.txt          # Remove write for group
$ chmod o=r file.txt          # Set others to read-only
$ chmod a+r file.txt          # Add read for all (owner, group, others)

# Recursive permission changes
$ chmod -R 755 /var/www/html/  # Apply to directory and all contents

Special Permissions

Linux provides three special permission types that extend basic permission functionality:

  • SUID (Set User ID): Executes with owner’s privileges
  • SGID (Set Group ID): Executes with group’s privileges or inherits group ownership
  • Sticky Bit: Restricts file deletion in shared directories
# Setting special permissions
$ chmod u+s /usr/bin/passwd    # Set SUID bit (4755)
$ chmod g+s /shared/directory  # Set SGID bit (2755)
$ chmod +t /tmp               # Set sticky bit (1755)

# Viewing special permissions
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 59640 Jan 25  2024 /usr/bin/passwd
#    ^
#    SUID bit (s instead of x)

$ ls -ld /tmp
drwxrwxrwt 15 root root 4096 Aug 28 18:04 /tmp
#        ^
#        Sticky bit (t instead of x)

Access Control Lists (ACLs)

ACLs provide fine-grained permission control beyond traditional Unix permissions, allowing multiple users and groups to have different access levels to the same file.

# Install ACL support (if needed)
$ sudo apt-get install acl

# Set ACL permissions
$ setfacl -m u:alice:rw file.txt      # Give alice read/write access
$ setfacl -m g:developers:rx dir/     # Give developers group read/execute
$ setfacl -m o::r file.txt           # Set others to read-only

# View ACL permissions
$ getfacl file.txt
# file: file.txt
# owner: john
# group: staff
user::rw-
user:alice:rw-
group::r--
group:developers:r-x
mask::rw-
other::r--

# Remove ACL entries
$ setfacl -x u:alice file.txt        # Remove alice's entry
$ setfacl -b file.txt               # Remove all ACL entries

SELinux: Mandatory Access Control

What is SELinux?

Security-Enhanced Linux (SELinux) is a mandatory access control (MAC) system that provides an additional layer of security beyond traditional discretionary access control (DAC). Originally developed by the NSA, SELinux enforces security policies that define what actions processes and users can perform on system resources.

Linux Security: Complete Guide to Permissions, SELinux, and AppArmor Protection

SELinux Operating Modes

SELinux operates in three distinct modes:

  • Enforcing: Actively enforces security policies and denies unauthorized access
  • Permissive: Logs policy violations but allows all access (useful for debugging)
  • Disabled: SELinux is completely turned off
# Check current SELinux status
$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing

# Check current mode
$ getenforce
Enforcing

# Temporarily change mode (until reboot)
$ sudo setenforce 0     # Set to permissive
$ sudo setenforce 1     # Set to enforcing

# Permanently change mode (edit /etc/selinux/config)
$ sudo vi /etc/selinux/config
SELINUX=enforcing      # or permissive, disabled

SELinux Security Contexts

Every process, file, and resource in SELinux has a security context consisting of four components: user:role:type:level.

# View file security contexts
$ ls -Z /var/www/html/
-rw-r--r--. apache apache unconfined_u:object_r:httpd_exec_t:s0 index.html

# View process security contexts
$ ps -eZ | grep httpd
system_u:system_r:httpd_t:s0    1234 ?        00:00:02 httpd

# View user security contexts
$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

# Components breakdown:
# user: SELinux user (unconfined_u, system_u, etc.)
# role: SELinux role (unconfined_r, system_r, etc.)
# type: SELinux type (httpd_t, httpd_exec_t, etc.)
# level: MLS/MCS level (s0, s0:c0.c1023, etc.)

Managing SELinux File Contexts

# Set file security context
$ sudo chcon -t httpd_exec_t /var/www/cgi-bin/script.cgi

# Restore default context based on file path
$ sudo restorecon /var/www/html/index.html

# Restore contexts recursively
$ sudo restorecon -R /var/www/

# Set persistent file context rules
$ sudo semanage fcontext -a -t httpd_exec_t "/var/www/cgi-bin(/.*)?"
$ sudo restorecon -R /var/www/cgi-bin/

# List file context rules
$ semanage fcontext -l | grep httpd

SELinux Booleans

SELinux booleans allow runtime policy modifications without recompiling the entire policy. They control specific features and behaviors.

# List all booleans
$ getsebool -a | grep httpd
httpd_can_network_connect --> off
httpd_can_network_connect_db --> off
httpd_can_sendmail --> off
httpd_enable_cgi --> on

# Check specific boolean
$ getsebool httpd_can_network_connect
httpd_can_network_connect --> off

# Set boolean temporarily
$ sudo setsebool httpd_can_network_connect on

# Set boolean permanently
$ sudo setsebool -P httpd_can_network_connect on

# Common useful booleans for web servers:
$ sudo setsebool -P httpd_can_network_connect on      # Allow HTTP network connections
$ sudo setsebool -P httpd_can_network_connect_db on   # Allow database connections
$ sudo setsebool -P httpd_execmem on                  # Allow executable memory

Troubleshooting SELinux Issues

# Check SELinux denials in audit log
$ sudo ausearch -m avc -ts recent

# Use sealert for detailed analysis
$ sudo sealert -a /var/log/audit/audit.log

# Generate local policy from denials
$ sudo audit2allow -a
$ sudo audit2allow -a -M mypolicy
$ sudo semodule -i mypolicy.pp

# Common troubleshooting commands
$ sudo tail -f /var/log/audit/audit.log     # Monitor real-time denials
$ sudo journalctl -f | grep -i selinux      # Monitor SELinux messages
$ sudo setroubleshoot                       # Install troubleshooting tools

AppArmor: Application Security Framework

Introduction to AppArmor

AppArmor (Application Armor) is a Linux security module that provides mandatory access control by confining applications to a limited set of resources. Unlike SELinux, AppArmor uses path-based access control and focuses on simplicity and ease of use.

Linux Security: Complete Guide to Permissions, SELinux, and AppArmor Protection

AppArmor vs SELinux Comparison

Feature AppArmor SELinux
Access Control Model Path-based Label-based
Learning Curve Easier Steeper
Policy Language Human-readable Complex
Default on Ubuntu, SUSE RHEL, CentOS, Fedora
Profile Creation Simpler More complex
Granularity Application-focused System-wide

AppArmor Installation and Setup

# Install AppArmor (Ubuntu/Debian)
$ sudo apt-get update
$ sudo apt-get install apparmor apparmor-utils

# Install AppArmor (CentOS/RHEL/Fedora)
$ sudo dnf install apparmor apparmor-utils

# Check AppArmor status
$ sudo apparmor_status
apparmor module is loaded.
15 profiles are loaded.
10 profiles are in enforce mode.
   /sbin/dhclient
   /usr/bin/firefox
   /usr/sbin/tcpdump
5 profiles are in complain mode.
   /usr/bin/evince
0 processes have profiles defined.
0 processes are unconfined but have a profile defined.

# Enable AppArmor service
$ sudo systemctl enable apparmor
$ sudo systemctl start apparmor

AppArmor Profile Modes

AppArmor profiles can operate in different modes:

  • Enforce mode: Actively restricts application behavior
  • Complain mode: Logs violations but allows access (learning mode)
  • Unconfined: No restrictions applied
# Set profile to complain mode
$ sudo aa-complain /usr/bin/firefox

# Set profile to enforce mode
$ sudo aa-enforce /usr/bin/firefox

# Disable profile
$ sudo aa-disable /usr/bin/firefox

# Check profile status
$ sudo aa-status | grep firefox
   /usr/bin/firefox (complain)

Creating AppArmor Profiles

# Generate profile automatically
$ sudo aa-genprof /usr/bin/myapp

# This starts an interactive process:
# 1. Run the application in another terminal
# 2. Exercise all application functionality
# 3. Return to aa-genprof and press 'S' to scan logs
# 4. Review and approve/deny access requests
# 5. Save the profile

# Example profile structure (/etc/apparmor.d/usr.bin.myapp):
#include <tunables/global>

/usr/bin/myapp {
  #include <abstractions/base>
  #include <abstractions/nameservice>

  # Executable files
  /usr/bin/myapp mr,
  /bin/bash ix,

  # Configuration files
  /etc/myapp/** r,
  owner /home/*/.myapp/** rw,

  # Log files
  /var/log/myapp/ w,
  /var/log/myapp/** w,

  # Network access
  network inet tcp,
  network inet udp,

  # System capabilities
  capability net_bind_service,
}

AppArmor Profile Syntax

AppArmor profiles use a simple, human-readable syntax:

# File access permissions:
# r - read
# w - write  
# x - execute
# m - memory map with PROT_EXEC
# k - lock
# l - link

# Path specifications:
/path/to/file r,                    # Read access to specific file
/path/to/dir/ r,                    # Read access to directory
/path/to/dir/** r,                  # Recursive read access
owner /home/*/.config/myapp/** rw,  # Read/write for owner only

# Network permissions:
network inet tcp,                   # TCP IPv4 network access
network inet6 udp,                  # UDP IPv6 network access

# Capabilities:
capability net_bind_service,        # Bind to privileged ports
capability sys_admin,               # System administration

# Includes:
#include <abstractions/base>         # Basic system abstractions
#include <abstractions/apache2-common>  # Apache-specific rules

Managing AppArmor Profiles

# Load/reload profile
$ sudo apparmor_parser -r /etc/apparmor.d/usr.bin.myapp

# Load all profiles
$ sudo systemctl reload apparmor

# View profile violations
$ sudo aa-logprof

# Update profile based on logs
$ sudo aa-logprof /usr/bin/myapp

# Profile locations:
# /etc/apparmor.d/          - Main profile directory
# /etc/apparmor.d/local/    - Local customizations
# /etc/apparmor.d/tunables/ - Tunable variables
# /etc/apparmor.d/abstractions/ - Common rule sets

Advanced Security Configurations

Combining Security Mechanisms

For maximum security, you can combine multiple protection layers:

Linux Security: Complete Guide to Permissions, SELinux, and AppArmor Protection

Security Best Practices

  • Principle of Least Privilege: Grant only necessary permissions
  • Regular Auditing: Monitor and review security logs
  • Profile Testing: Test security profiles in complain mode first
  • Keep Updated: Maintain current security policies and patches
  • Document Changes: Record security configuration modifications
# Security auditing commands
$ sudo find / -perm -4000 2>/dev/null              # Find SUID files
$ sudo find / -perm -2000 2>/dev/null              # Find SGID files
$ sudo netstat -tulpn                              # Check listening services
$ sudo ss -tulpn                                   # Modern alternative to netstat
$ sudo systemctl list-unit-files --state=enabled  # Check enabled services

# Regular security maintenance
$ sudo updatedb && locate "*.log" | grep -E "(auth|secure|audit)"
$ sudo logrotate -f /etc/logrotate.conf            # Rotate security logs
$ sudo aide --check                                # File integrity checking

Troubleshooting Common Issues

# Permission denied errors - check:
$ ls -la /path/to/file                    # File permissions
$ getfacl /path/to/file                   # ACL permissions
$ ls -Z /path/to/file                     # SELinux contexts (RHEL/CentOS)
$ sudo aa-status | grep application      # AppArmor status (Ubuntu)

# Service startup failures:
$ sudo journalctl -u service-name -f     # Check service logs
$ sudo ausearch -m avc -ts recent        # SELinux denials
$ sudo dmesg | grep -i apparmor          # AppArmor messages

# Network access issues:
$ getsebool -a | grep network            # SELinux network booleans
$ sudo aa-status | grep network          # AppArmor network profiles
$ sudo netstat -tlnp                     # Check listening ports

Conclusion

Linux security relies on a comprehensive, multi-layered approach combining traditional Unix permissions with modern mandatory access control systems. File permissions provide the foundation with user, group, and other access controls, while ACLs offer fine-grained permission management for complex scenarios.

SELinux delivers enterprise-grade mandatory access control through label-based policies, making it ideal for high-security environments that require granular control over system resources. AppArmor offers a more user-friendly approach with path-based profiles, making it excellent for application-specific confinement with easier management.

The key to effective Linux security lies in understanding when and how to use each mechanism appropriately. Start with solid file permissions, add ACLs for complex access scenarios, and implement either SELinux or AppArmor based on your environment’s complexity and security requirements. Regular monitoring, testing in non-production environments, and following the principle of least privilege will ensure your Linux systems remain secure and functional.