dotlinux guide

Navigating SELinux for Enhanced Linux System Security

In the landscape of Linux security, discretionary access control (DAC) systems—relying on user ownership and file permissions (e.g., rwx)—have long been the default. However, DAC has limitations: it trusts users to manage their own permissions, leaving systems vulnerable to misconfigurations or compromised accounts. Enter SELinux (Security-Enhanced Linux), a mandatory access control (MAC) framework developed by the NSA. SELinux enforces granular, policy-driven access rules at the kernel level, independent of user identity, to mitigate threats like privilege escalation, data leaks, and unauthorized process interactions. This blog demystifies SELinux, covering its core concepts, practical usage, troubleshooting workflows, and best practices to help you leverage it for robust system security.

Table of Contents

  1. Understanding SELinux Basics
    • 1.1 What is SELinux?
    • 1.2 DAC vs. MAC: Why SELinux Matters
  2. Core SELinux Concepts
    • 2.1 SELinux Modes: Enforcing, Permissive, Disabled
    • 2.2 SELinux Contexts: The “Labels” of Access Control
    • 2.3 SELinux Policies: Rule Sets for Authorization
  3. Practical SELinux Usage
    • 3.1 Checking SELinux Status
    • 3.2 Changing SELinux Modes
    • 3.3 Managing SELinux Contexts
  4. Common Practices: Troubleshooting & Policy Management
    • 4.1 Analyzing SELinux Denials
    • 4.2 Using sealert for Automated Diagnosis
    • 4.3 Modifying Policies with Booleans
  5. Best Practices for SELinux
  6. Conclusion
  7. References

1. Understanding SELinux Basics

1.1 What is SELinux?

SELinux is a Linux kernel module that provides MAC, a security model where access to resources (files, processes, network ports) is controlled by policies enforced by the kernel, not just user permissions. It was designed to limit damage from attacks by confining processes to the minimum privileges required (principle of least privilege).

1.2 DAC vs. MAC: Why SELinux Matters

  • DAC (Discretionary Access Control): The default Linux security model, where access is determined by user ownership and mode bits (e.g., chmod 755). Users with root privileges can bypass DAC entirely, making systems vulnerable to privilege escalation.
  • MAC (Mandatory Access Control): SELinux adds a second layer, enforcing rules based on predefined policies. Even root is subject to SELinux policies, preventing unrestricted access.

2. Core SELinux Concepts

2.1 SELinux Modes: Enforcing, Permissive, Disabled

SELinux operates in three modes, configurable system-wide:

ModeBehavior
EnforcingActively enforces policies; denies unauthorized access and logs denials.
PermissiveLogs policy violations but does not enforce them (ideal for testing/troubleshooting).
DisabledSELinux is inactive; no policy enforcement or logging. Not recommended for production.

2.2 SELinux Contexts: The “Labels” of Access Control

Every process, file, directory, and network port in SELinux is assigned a context—a string of metadata that defines its role in the security policy. Contexts follow the format:

user:role:type:level  
  • User: Identifies the SELinux user (e.g., unconfined_u for regular users, system_u for system processes).
  • Role: Defines the access role (e.g., object_r for files, system_r for processes).
  • Type: The most critical component; determines allowed interactions (e.g., httpd_t for Apache processes, httpd_sys_content_t for web files).
  • Level: Used in Multi-Level Security (MLS) policies to enforce data classification (e.g., s0 for unclassified).

Example: A web file might have the context unconfined_u:object_r:httpd_sys_content_t:s0.

2.3 SELinux Policies: Rule Sets for Authorization

Policies are pre-defined rule sets that dictate how subjects (processes) interact with objects (files, ports). Common policy types:

  • Targeted: Default on most distributions (RHEL, CentOS, Fedora). Confines only critical system processes (e.g., httpd, sshd) while leaving others unconfined.
  • Strict: Confines all processes, including user applications (rarely used today).
  • MLS/MCS: Enforces Multi-Level Security (classification labels) or Multi-Category Security (fine-grained category tags) for high-security environments.

3. Practical SELinux Usage

3.1 Checking SELinux Status

Use sestatus to view the current SELinux state, policy type, and mode:

sestatus  

Sample Output:

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  
Policy MLS status:              enabled  
Policy deny_unknown status:     allowed  
Memory protection checking:     actual (secure)  
Max kernel policy version:      33  

To check only the enforcement mode, use getenforce:

getenforce  # Output: Enforcing, Permissive, or Disabled  

3.2 Changing SELinux Modes

Temporary Mode Changes (Runtime)

Use setenforce to switch modes temporarily (resets after reboot):

setenforce 0  # Switch to Permissive mode (log denials, don't block)  
setenforce 1  # Switch to Enforcing mode (block and log denials)  

Permanent Mode Changes (Persistent)

To persist mode changes across reboots, edit /etc/selinux/config:

sudo vi /etc/selinux/config  

Set SELINUX= to one of:

  • enforcing: Enforce policies.
  • permissive: Log denials only.
  • disabled: Disable SELinux (requires reboot).

Note: Disabling SELinux requires a reboot and is not recommended for production.

3.3 Managing SELinux Contexts

SELinux contexts determine access. Use these tools to view and modify contexts:

View Contexts

  • For files/directories: ls -Z

    ls -Z /var/www/html  # List SELinux contexts of web files  

    Output:

    -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 index.html  
  • For processes: ps -Z

    ps -Z | grep httpd  # View context of Apache processes  

    Output:

    system_u:system_r:httpd_t:s0    1234 ?        00:00:00 httpd  

Modify Contexts Temporarily with chcon

chcon changes a file’s context temporarily (resets after restorecon or system relabel). Use it for testing:

# Change context of /var/www/custom/file.html to httpd_sys_content_t (web-accessible)  
sudo chcon -t httpd_sys_content_t /var/www/custom/file.html  

Modify Contexts Permanently with semanage and restorecon

For permanent context changes, use semanage fcontext to define a rule, then restorecon to apply it:

# Add a permanent rule: all files under /var/www/custom/ inherit httpd_sys_content_t  
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/custom(/.*)?"  

# Apply the rule to existing files  
sudo restorecon -Rv /var/www/custom/  
  • -a: Add a rule.
  • -t: Specify the target type.
  • /var/www/custom(/.*)?: Regex to match the directory and its subdirectories.
  • restorecon -Rv: Recursively (-R) restore contexts and verbose (-v) output.

4. Common Practices: Troubleshooting & Policy Management

4.1 Analyzing SELinux Denials

When SELinux blocks access, it logs “AVC (Access Vector Cache) denials” to:

  • /var/log/audit/audit.log (via auditd service, default on RHEL/CentOS).
  • /var/log/messages (fallback if auditd is disabled).

Use ausearch to filter denials:

# Search for AVC denials in the last hour  
sudo ausearch -m AVC -ts recent  

Sample Audit Log Entry:

type=AVC msg=audit(1620000000.123:456): avc:  denied  { read } for  pid=1234 comm="httpd" name="file.html" dev="sda1" ino=789 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0  
  • scontext: Subject (process) context (httpd_t = Apache).
  • tcontext: Target (file) context (default_t = not web-accessible).
  • { read }: Action denied.

4.2 Using sealert for Automated Diagnosis

sealert (part of setroubleshoot-server) parses audit logs and suggests fixes for denials:

# Generate a report from audit.log  
sudo sealert -a /var/log/audit/audit.log  

# Or analyze a specific denial by UUID (from ausearch output)  
sudo sealert -l 12345678-1234-1234-1234-1234567890ab  

Sample sealert Output:

SELinux is preventing httpd from reading access to file file.html.  

*****  Plugin catchall (100. confidence) suggests   **************************  

If you want to allow httpd to read access to the file.html file  
Then you need to change the label on file.html  
Do  
# semanage fcontext -a -t httpd_sys_content_t '/var/www/custom/file.html'  
# restorecon -v '/var/www/custom/file.html'  

4.3 Modifying Policies with Booleans

SELinux booleans are toggleable settings that modify policy behavior without rewriting rules. Use getsebool and setsebool to manage them:

# List all booleans related to Apache  
sudo getsebool -a | grep httpd  

# Example output: httpd_can_network_connect --> off  

Enable a boolean temporarily:

# Allow Apache to connect to the network (temporarily)  
sudo setsebool httpd_can_network_connect on  

Enable a boolean permanently (survives reboot) with -P:

# Allow Apache to connect to the network permanently  
sudo setsebool -P httpd_can_network_connect on  

5. Best Practices for SELinux

  1. Keep SELinux in Enforcing Mode: Disabling SELinux removes a critical security layer. Use Permissive mode only for troubleshooting.
  2. Use Permanent Context Changes: Prefer semanage fcontext over chcon to avoid context resets.
  3. Leverage Booleans First: Use booleans to adjust policy behavior before writing custom rules.
  4. Log Everything: Ensure auditd is running to capture denials in /var/log/audit/audit.log.
  5. Relabel Files After Mode Changes: If switching from Disabled to Enforcing, relabel the filesystem with sudo fixfiles -F onboot (reboot required).
  6. Document Changes: Track semanage, setsebool, and context modifications for compliance and troubleshooting.
  7. Update Policies: Regularly update selinux-policy packages to patch vulnerabilities.

6. Conclusion

SELinux is a powerful tool for hardening Linux systems, but its reputation for complexity often leads users to disable it. By mastering contexts, modes, and troubleshooting workflows (e.g., sealert, ausearch), you can enforce granular access controls without sacrificing usability. Remember: SELinux is not a barrier but a guardrail—embrace it to protect against zero-day exploits, misconfigurations, and insider threats.

7. References


Let me know if you need further clarification on any section—happy securing! 🛡️