Remediation Guides

How to Fix “Ensure SELinux Is Not Disabled in Bootloader Configuration”

26 September 2026 8 min read

“Ensure SELinux is not disabled in bootloader configuration” is a CIS benchmark check that fails when a GRUB boot entry passes selinux=0 or enforcing=0 to the kernel. To fix it, run grubby –update-kernel ALL –remove-args “selinux=0 enforcing=0”, remove the same tokens from GRUB_CMDLINE_LINUX in /etc/default/grub, set SELINUX=enforcing in /etc/selinux/config, and reboot.

The command itself is quick. What you need to plan is the reboot: if SELinux has been fully off, the next boot relabels every file, and a host that goes straight from disabled to enforcing can fail to boot or break its applications.

What the scanner is actually detecting

This is a CIS Linux audit item that Tenable runs during an authenticated compliance scan. It has no CVE and no plugin ID of its own; it reports PASSED or FAILED based on whether any boot entry carries selinux=0 (the kernel does not load SELinux at all) or enforcing=0 (SELinux starts in permissive mode). Item numbers change between benchmark versions, so search your report by title:

Tenable audit (CIS benchmark) Item
CIS Rocky Linux 9 v2.0.0 L1 Server 1.3.1.2
CIS Red Hat Enterprise Linux 9 v2.0.0 L1 Server 1.3.1.2
CIS AlmaLinux OS 9 v2.0.0 L1 Server 1.3.1.2
CIS Oracle Linux 9 v2.0.0 L1 Server 1.3.1.2
CIS Red Hat EL8 Server v3.0.0 L1 1.5.1.2
CIS Red Hat EL7 Server L1 v3.0.1 1.7.1.2

Some older audits, such as CIS Amazon Linux 2 v2.0.0, split the check into two items whose titles end in “- selinux” and “- enforcing”. The same benchmarks contain a companion item, “Ensure the SELinux mode is not disabled” (1.3.1.4 on Rocky Linux 9 and RHEL 9 v2.0.0), which passes when SELinux runs in either enforcing or permissive mode and fails when it is disabled. Level 2 profiles add “Ensure the SELinux mode is enforcing” (1.3.1.5 on Rocky Linux 9), which accepts only enforcing.

Real-world risk, stated honestly

SELinux is a mandatory access control layer. With selinux=0, a compromised service is limited only by ordinary file permissions and the account it runs as; the confinement that would keep a hijacked web server or database from reading unrelated files is gone. With enforcing=0, the policy is loaded and denials are logged, but nothing is blocked.

This is not a vulnerability an attacker can exploit on its own. It removes a containment layer that matters after something else goes wrong. Red Hat’s documentation says not to use selinux=0 in production. There is also a practical cost: files created while SELinux is disabled get no labels at all, and the longer a host runs that way, the more work it takes to turn SELinux back on.

How to confirm it on the host

Run these as root or with sudo:

# Running state
getenforce
sestatus
cat /proc/cmdline

# Arguments in every boot entry (RHEL 8/9, Rocky, Alma, Oracle Linux 8/9, Fedora)
sudo grubby --info=ALL | grep -E '^(kernel|args)='

# Any selinux=0 or enforcing=0 left anywhere in the boot configuration
sudo grep -rsnE 'b(selinux|enforcing)=0b' /etc/default/grub /boot/grub2 /boot/loader/entries /boot/efi/EFI

# Persistent mode
grep -E '^s*SELINUX(TYPE)?=' /etc/selinux/config

Where the arguments live depends on the release. On RHEL 9 family systems and Fedora, each boot entry is a file under /boot/loader/entries with its own options line. On RHEL 8 family systems, entries usually reference the kernelopts variable stored in /boot/grub2/grubenv. On RHEL 7 and CentOS 7, arguments sit directly on the linux16 or linuxefi lines in grub.cfg. The recursive grep covers all three.

Check the getenforce result. Disabled means the files are probably unlabeled, so follow the relabel steps below. Permissive with enforcing=0 in the boot entries means labels exist, but the policy has never been enforced.

How to fix it

RHEL 8 and 9, Rocky, AlmaLinux, Oracle Linux 8 and 9, Fedora

Start with prerequisites and backups:

sudo dnf install -y selinux-policy-targeted libselinux-utils policycoreutils
sudo cp -a /etc/default/grub /root/grub.default.bak
sudo cp -a /etc/selinux/config /root/selinux-config.bak
sudo grubby --info=ALL | sudo tee /root/grubby-info.before > /dev/null

Set permissive mode first, so the next boot cannot block anything while labels are being fixed:

sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config

Remove the arguments from every boot entry. This is the command the CIS remediation gives:

sudo grubby --update-kernel ALL --remove-args "selinux=0 enforcing=0"

According to the grubby man page, using ALL also rewrites GRUB_CMDLINE_LINUX in /etc/default/grub. Check it anyway, and strip any leftover tokens:

grep -E '^GRUB_CMDLINE_LINUX' /etc/default/grub
sudo sed -i -E '/^GRUB_CMDLINE_LINUX/ s/[[:space:]]*b(selinux|enforcing)=0b//g' /etc/default/grub

This file matters on RHEL 9. grub2-mkconfig -o /boot/grub2/grub.cfg –update-bls-cmdline overwrites the options of every boot entry with GRUB_CMDLINE_LINUX, so a stale selinux=0 there would come back the next time someone runs it. On RHEL 8, grubby edits kernelopts in grubenv, and newly installed kernels inherit it.

If getenforce reported Disabled, queue a full relabel and reboot. Red Hat’s guidance is to be in permissive mode before running this command, which the sed step above takes care of:

sudo fixfiles -F onboot
sudo reboot

The relabel runs early in the boot, and the host restarts once more when it finishes. After the host is back up, look for denials that enforcing mode would have caused:

sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts today

Fix whatever turns up (see below), then switch to enforcing:

sudo sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
sudo setenforce 1

setenforce 1 switches the running system right away, and the config file controls every later boot. Reboot in your next window to prove the host comes up enforcing.

RHEL 7, CentOS 7 and Oracle Linux 7

These releases generate a flat grub.cfg. The CIS remediation edits /etc/default/grub and regenerates the file. Use the same permissive, relabel and enforce sequence as above, and replace the grubby step with:

sudo cp -a /etc/default/grub /root/grub.default.bak
sudo sed -i -E '/^GRUB_CMDLINE_LINUX/ s/[[:space:]]*b(selinux|enforcing)=0b//g' /etc/default/grub

# BIOS
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# UEFI: write to the grub.cfg in your vendor directory, for example
sudo grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

RHEL 7 and CentOS 7 are past the end of standard support, so plan the replacement too.

How to verify the fix and rescan

sudo grubby --info=ALL | grep -Ec 'b(selinux|enforcing)=0b'     # expect 0
sudo grep -rsnE 'b(selinux|enforcing)=0b' /etc/default/grub /boot/grub2 /boot/loader/entries /boot/efi/EFI   # expect no output

# after a reboot
cat /proc/cmdline      # no selinux=0 or enforcing=0
getenforce             # Enforcing
sestatus

Then rerun the same compliance scan with the same audit file. The bootloader item and “Ensure the SELinux mode is not disabled” should both move to PASSED, and so should the Level 2 enforcing item if you scan against Level 2.

What can break and how to roll back

  • Longer first boot: the CIS impact statement warns that the relabel can take a long time and extend downtime. On hosts with large file systems, schedule a real maintenance window.
  • Boot failure if you skip permissive: Red Hat warns that relabeling in enforcing mode can stop a boot when systemd needs files that are still unlabeled.
  • Application denials: software that uses non-default paths, ports or network access is the usual casualty. Fix it with semanage fcontext plus restorecon for custom paths, semanage port for non-standard ports, or setsebool -P for booleans, instead of turning SELinux off.
  • Vendor requirements: some third-party products document that SELinux must be disabled. Get that in writing and record an exception.

Rollback options, from least to most drastic:

# One domain only: stop enforcing for a single service type, keep the rest enforced
sudo semanage permissive -a httpd_t

# Whole host, keeps this bootloader item passing (fails the Level 2 enforcing item)
sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
sudo setenforce 0

# Full revert (brings the finding back)
sudo grubby --update-kernel ALL --args selinux=0
sudo cp -a /root/grub.default.bak /etc/default/grub

If a host will not boot, press e at the GRUB menu, add enforcing=0 to the line starting with linux, and press Ctrl+x. That applies to one boot only. If a GRUB password is set, you need it for this.

Common false positive reasons

  • The scan could not read the boot files. grub.cfg, grubenv and the entry files are often root-only on hardened hosts. Without working sudo elevation, the item can fail or error on a clean host. Our guide to configuring SSH credentials and sudo for Linux authenticated scans covers the scan account.
  • Old or rescue entries. /proc/cmdline is clean, but an older kernel or rescue entry still carries selinux=0. That is a true positive, and –update-kernel ALL fixes it.
  • Only the runtime was changed. setenforce 1 makes getenforce say Enforcing, but enforcing=0 stays in the boot entries until you remove it. The scan is right.
  • No GRUB at all. Containers and VMs that boot a kernel directly have no GRUB entries to fix; SELinux is decided by the host or the hypervisor configuration. Record a documented exception.
  • Wrong benchmark for the distribution. Debian and Ubuntu CIS profiles check AppArmor instead. A RHEL audit pointed at those hosts will fail items that do not apply. Our overview of why vulnerability scanners report false positives covers this and similar mismatches.

FAQ

Is permissive mode enough to pass?

For this item, yes, as long as permissive comes from /etc/selinux/config and not from enforcing=0 on the kernel command line. The companion “mode is not disabled” item also accepts permissive. Level 2 profiles require enforcing.

Can I fix this without a reboot?

The scan result, yes: it reads the boot configuration, so removing the arguments is enough for a rescan. The running kernel keeps its current arguments until the next boot, and a host with SELinux disabled cannot switch it on with setenforce.

Why not just set SELINUX=disabled in /etc/selinux/config instead of selinux=0?

Red Hat removed kernel support for disabling SELinux that way in RHEL 9: the host starts with SELinux enabled but no policy loaded. It would also fail the “mode is not disabled” item.

How long does the relabel take?

It depends on the number of files and the storage speed. Time it on a similar host first.

Tracking this finding across many hosts

On a large RHEL-family estate, the usual trouble is drift: a golden image or an old kickstart keeps adding selinux=0 to new builds. If you use SITEY, you can upload the .nessus export from the compliance scan, have its AI draft a host-specific remediation script that runs only after a human approves it, deploy it through its agents on Linux endpoints, and re-test to confirm the finding closed.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing