Overview

Security-Enhanced Linux (SELinux) is a mandatory access control (MAC) framework built into the Linux kernel. Unlike traditional discretionary access controls (file permissions), SELinux enforces security policies at the kernel level, meaning even a process running as root can be denied access if the policy says so.

In this lab, I worked through a real-world scenario: a network team needed SELinux configured to allow their Zabbix network monitoring application to communicate through httpd. My tasks were to:

  1. Use an SELinux boolean to permit httpd → Zabbix communication.
  2. Switch SELinux from permissive to enforcing mode.
  3. Make the enforcing mode setting persistent across reboots.

Environment

DetailValue
OSRed Hat-based Linux (RHEL/CentOS)
AccessSSH as cloud_user, then escalated to root
SELinux tools usedgetsebool, setsebool, getenforce, setenforce, vi

Part 1 - Permitting httpd to Communicate with Zabbix

Why This Matters

SELinux ships with a large set of booleans, on/off switches that toggle specific pre-defined behaviors without requiring you to write custom policies. This is the safest and most maintainable way to adjust SELinux for known applications like Zabbix.

Step 1: Discover the Relevant Boolean

Before changing anything, I queried all SELinux booleans and filtered for Zabbix-related ones:

getsebool -a | grep zabbix

Output:

httpd_can_connect_zabbix --> off
zabbix_can_network --> off
zabbix_run_sudo --> off

Three booleans exist for Zabbix. The one I need is httpd_can_connect_zabbix, which controls whether the Apache httpd service is allowed to initiate connections to Zabbix, currently off.


Step 2: Enable the Boolean

The -P flag makes the change persistent, it survives a reboot by writing to the SELinux policy store.

setsebool -P httpd_can_connect_zabbix on

Without -P, the boolean change would only last until the next reboot. Always use -P in production unless you intentionally want a temporary change.


Step 3: Verify the Change

getsebool -a | grep zabbix

Output:

httpd_can_connect_zabbix --> on
zabbix_can_network --> off
zabbix_run_sudo --> off

httpd_can_connect_zabbix is now on. The other two booleans remain off, I only modified what was needed, following the principle of least privilege.


Part 2 - Switching SELinux to Enforcing Mode

Understanding SELinux Modes

ModeBehavior
EnforcingActively blocks policy violations and logs them
PermissiveLogs violations but does not block, useful for testing
DisabledSELinux is completely off, not recommended

The system was in permissive mode, which means violations were being logged but not stopped. The network team needed it in enforcing mode to properly test security behavior.


Step 1: Check the Current Mode

getenforce

Output:

Permissive

Step 2: Switch to Enforcing Mode

setenforce 1

setenforce accepts either 1 (Enforcing) or 0 (Permissive). This change is immediate but not persistent on its own, it lives only in the running kernel.


Step 3: Confirm the Change

getenforce

Output:

Enforcing

✅ SELinux is now actively enforcing policy.


Part 3 - Making Enforcing Mode Persistent

setenforce only affects the running system. If the server reboots, SELinux reads its startup mode from /etc/selinux/config. I needed to update that file.

Editing the SELinux Config File

vi /etc/selinux/config

I located the SELINUX= directive and changed it to:

SELINUX=enforcing

Verifying the Config File

cat /etc/selinux/config

Output:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

✅ The config confirms SELINUX=enforcing. On the next boot, the system will start SELinux in enforcing mode automatically.

Notice SELINUXTYPE=targeted - this means SELinux only confines specific high-risk processes (like httpd, sshd, etc.) rather than every single process on the system. This is the standard and practical default for most RHEL-based systems.


Key Takeaways

  • SELinux booleans are the cleanest way to enable known application behaviors without writing custom policies. Always search with getsebool -a | grep <app> before doing anything more complex.
  • setsebool -P is critical - always include -P unless you deliberately want a temporary change.
  • setenforce changes the running mode instantly but is not persistent. You must also update /etc/selinux/config to survive reboots.
  • Never disable SELinux just because it blocks something. Find the right boolean or policy adjustment instead.
  • The targeted policy type is the practical default, it protects what matters most without locking down every process.

Commands Reference

CommandPurpose
getsebool -a | grep <name>List and filter SELinux booleans
setsebool -P <boolean> on|offSet a boolean persistently
getenforceShow current SELinux mode
setenforce 1|0Switch mode at runtime (non-persistent)
vi /etc/selinux/configEdit persistent SELinux config
cat /etc/selinux/configVerify config file contents