Learn › RHCSA (EX200) › Security
getenforce - a hands-on Linux lab on a real virtual machine.
Read and change the SELinux mode, the first move in every SELinux problem. Three modes: Enforcing (blocks and logs), Permissive (logs only), Disabled (neither). Use getenforce for the live mode in one word, sestatus for the full block with both the current and the config-file mode, setenforce 0/1 to flip Permissive and Enforcing at RUNTIME only, and the SELINUX= line in /etc/selinux/config to set the mode at BOOT. A permanent change is both halves together. Serves EX200 security: set enforcing and permissive modes for SELinux.
You installed a web server, dropped a page into /var/www/html, opened the firewall port, and started the daemon. Everything you can see is correct. Yet the browser returns nothing, and the logs show a permission problem on a file that is plainly world-readable. You stare at ls -l and the permissions are fine. Standard file permissions are not the thing blocking you here.
What is blocking you is SELinux, a second layer of access control sitting underneath the ordinary user-and-group permissions you already know. It has its own idea of what each process is allowed to touch, and when it says no, it can say no silently. Before you can diagnose a single SELinux denial, you have to know one thing cold: what mode SELinux is running in. That mode decides whether SELinux is actively blocking, quietly watching, or switched off entirely. This lesson teaches you to read that state and change it, which is the first move in every SELinux problem on the exam.
The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches. The outputs are from a real RHEL 10 machine (AlmaLinux 10.2) running as root with SELinux left Enforcing. A few values, like the loaded policy name and the exact wording of one line, depend on the build, so treat those as illustrative. What is stable everywhere is the SHAPE: getenforce prints one word, sestatus prints a labeled block, and /etc/selinux/config holds one SELINUX= line.
SELinux, short for Security-Enhanced Linux, is a mandatory access control system built into the kernel. Ordinary permissions ask who owns a file and what its rwx bits are. SELinux asks a different question: does the policy allow a process of this type to act on a resource of that type. It is a second gate, and both gates must open for an action to succeed.
Think of standard permissions as the lock on your front door, the one you control. SELinux is the building's own security desk downstairs, following a rulebook you did not write and cannot casually override. The mode is simply how strict that security desk is being right now: actively turning people away, only writing names in a logbook, or off duty entirely. Everything you do with SELinux starts by knowing which of those three it is.
SELinux has exactly three modes, and you must be able to name all three and say what each does.
Enforcing means the policy is active: SELinux blocks any action the policy forbids, and it writes a log entry each time. This is the normal, secure state and the one the exam expects you to keep or return to.
Permissive means SELinux still evaluates every action and logs the ones it would block, but it blocks nothing. Nothing is denied, everything is recorded. This is the diagnosis mode: you flip to Permissive to see the full list of what would be denied without breaking the service while you investigate.
Disabled means SELinux is switched off entirely: no checks, no logging, no labels being enforced. It is the least secure state, it can only be set at boot, and turning it back on later can require a slow full relabel of the disk. On the exam you almost never want Disabled.
A useful way to hold the three: Enforcing blocks and logs, Permissive only logs, Disabled does neither. The middle mode, Permissive, is the one people forget, and it is the most practically useful, because it lets you collect every denial a service would hit without taking the service down.
When you sit at an unfamiliar machine, the very first SELinux question is: which mode is this in right now. The fastest way to ask is getenforce. It takes no arguments and prints exactly one word: Enforcing, Permissive, or Disabled. Nothing else. It is the quickest possible read of the live state.
Before you run it, predict the answer on a secured RHEL 10 box: it should say Enforcing, because that is the default and the secure state. Ask the machine its current mode:
getenforce
prompt: [root@servera ~]# answer: getenforce output: Enforcing hint: The one-word mode reader is getenforce, with no arguments: getenforce
One word, Enforcing, and that is the whole answer: SELinux is active and blocking what the policy forbids. getenforce never prints anything but one of the three mode names, which is exactly why it is the fast check. When a service misbehaves in a way plain permissions cannot explain, this is the first command you run, because if the answer is Enforcing then SELinux is a live suspect. If it read Permissive, SELinux would be logging but not the cause of a block; if Disabled, you would rule SELinux out entirely.
getenforce gives you the live mode in one word. sestatus gives you the whole situation in a labeled block. It reports whether SELinux is enabled at all, which policy is loaded, the mode running right now, and the mode set in the config file that will take effect at the next boot. That last distinction is the one that trips people: the current mode and the config-file mode can differ, and sestatus shows both side by side.
Before you run it, know what to look for: two mode lines, Current mode and Mode from config file. Read the full SELinux status:
sestatus
prompt: [root@servera ~]# answer: sestatus output: SELinux status: enabled Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing hint: The full status reporter is sestatus, no arguments: sestatus
Four lines, each a fact. SELinux status: enabled means the subsystem is switched on at all. Loaded policy name: targeted is the ruleset in force; targeted is the RHEL default, which confines specific services and leaves the rest unconfined. Current mode: enforcing is the mode running this instant, the same thing getenforce reported. Mode from config file: enforcing is what /etc/selinux/config says, which is what the machine will boot into next time. When those two mode lines agree, the running state is also the persistent state. When they disagree, someone changed the mode at runtime without writing it to the config, and a reboot will snap it back to the config value.
The Loaded policy name may read differently on another build, and the exact spacing of the labels can vary, so read the field names rather than counting spaces. What is stable is that sestatus reports both a Current mode and a Mode from config file, and that gap between them is the whole reason the command exists.
To change the mode right now, without a reboot, you use setenforce. It flips between the two live modes only: Enforcing and Permissive. It cannot reach Disabled, because turning SELinux off is a boot-time decision, not a runtime one. You give it either a word or a number: setenforce 0 or setenforce Permissive drops to Permissive, and setenforce 1 or setenforce Enforcing raises it back to Enforcing. The 0 is off-the-blocking, the 1 is on.
The critical fact is that setenforce is runtime only. It changes the mode this instant and prints nothing on success, but it does not touch /etc/selinux/config, so the change does not survive a reboot. That is a feature: dropping to Permissive to watch denials, then raising back to Enforcing, is the standard diagnostic dance, and you would not want a reboot to leave the box stuck Permissive. Drop the machine to Permissive to gather denials:
setenforce 0
prompt: [root@servera ~]# answer: setenforce 0 output: hint: The runtime mode switch is setenforce; 0 is Permissive, 1 is Enforcing: setenforce 0
No output means it worked: setenforce is silent on success. The live mode is now Permissive. SELinux logs every action it would have blocked but blocks nothing, so you can reproduce the problem and collect the full list of denials without the service actually failing. Run getenforce right after and it would read Permissive. When you are done investigating, setenforce 1 returns the box to Enforcing. Neither call wrote anything to the config file, so a reboot would restore whatever Mode from config file said, which is why this is only half of a permanent change.
setenforce does NOT persist. If a task says leave the machine in a given mode after a reboot, setenforce alone will not do it, because it only changes the running state and the config file wins at boot. The other trap is Disabled: you cannot setenforce your way to Disabled, and moving between Enforcing/Permissive and Disabled is a reboot-only change made in the config file, not at runtime.
To set the mode permanently, so it survives a reboot, you edit one line in /etc/selinux/config. That file holds a SELINUX= directive whose value is enforcing, permissive, or disabled. Whatever that line says is the mode the machine boots into. Set it to enforcing and the box comes up Enforcing every time, no matter what setenforce did during the last session.
You are not editing here, only reading the current setting so you know the persistent state. The clean way to see just that one line is to grep for it. Before you run it, predict: on a secured box it should read SELINUX=enforcing. Read the config-file mode:
grep ^SELINUX= /etc/selinux/config
prompt: [root@servera ~]# answer: grep ^SELINUX= /etc/selinux/config output: SELINUX=enforcing hint: Filter the config to the one directive that sets the boot mode: grep ^SELINUX= /etc/selinux/config
SELINUX=enforcing is the boot-time mode, the value that decides what the machine comes up as. The ^SELINUX= pattern anchors to the start of a line so you match the real directive and not the SELINUXTYPE= line just below it, which names the policy and is a different setting entirely. To make a permanent change you would edit this value to permissive or disabled and reboot. The complete, exam-safe permanent change is both halves together. Edit SELINUX= in the config so the next boot is right, then setenforce so the running mode matches immediately and you never have to reboot just to prove it.
One direction is slow and worth flagging. Switching from Disabled back to Enforcing can force a full filesystem relabel on the next boot, because while Disabled the system stops maintaining SELinux labels and they must all be rebuilt. This is a real reason to leave a box at Enforcing or Permissive rather than Disabled: getting back is expensive. Your machine's config value is whatever was set at install; a hardened image will read enforcing.
Scaffolding off. No command is printed this time. You have every piece you need.
You have just sat down at a RHEL 10 server that a service is failing on, and permissions look correct. Before you touch anything else, a task asks you the single fastest question: what SELinux mode is this machine running in right now. You do not want the full labeled status block, and you do not want the config-file value that only applies at the next boot. You want the live mode, this instant, in one word. Which single command, with no arguments, prints exactly that one word?
prompt: [root@servera ~]# answer: getenforce output: Enforcing hint: It is the one-word live reader, not sestatus and not grep. No arguments.
getenforce prints one word, Enforcing, and that is the fastest possible read of the live mode. sestatus would have given you the fuller block with both the current and the config-file modes, and grep ^SELINUX= /etc/selinux/config would have shown only the boot-time value, but when the question is just what mode am I in right now, getenforce answers it in a single word with no arguments. That is the command you run first at every SELinux-flavored problem.
You earned this cheat sheet. Every row is a command you just ran or a change you now know how to make:
The one thing to burn in for the exam: setenforce changes the mode NOW but does not persist, and the config file sets the mode at BOOT but does not change it now. A permanent change is both halves, together. Enforcing blocks and logs, Permissive only logs, Disabled does neither.
The classic diagnostic move is to setenforce 0, then reproduce the broken action so every denial gets logged without the service failing. Read the denials, apply the real fix (a context relabel, a boolean, or a port label), then setenforce 1 to return to Enforcing and confirm the service now works with SELinux fully on. Never leave a box in Permissive as the fix; Permissive is for diagnosis, Enforcing is the destination.
The practice terminal has walked you through reading and changing the SELinux mode. You used getenforce for the one-word live state and sestatus for the full block with both the current and the boot-time modes. You used setenforce 0 and setenforce 1 to flip Permissive and Enforcing at runtime, and the SELINUX= line in /etc/selinux/config to set the mode that survives a reboot. Every one of those you typed yourself.
The security module mission, Operation Lockdown, is where you run these against a real RHEL 10 machine. A full VM boots for you, with SELinux live and a service to secure. The mission hands you objectives that use exactly what you practiced here. Confirm the current mode, drop to Permissive to diagnose a denial, apply the fix, then return the machine to Enforcing and make sure it stays that way after a reboot. One difference from this lesson: the mission shows no commands. You read the objective, recall the getenforce, sestatus, and setenforce forms, and type them. That recall is what makes it stick on exam day.
Finish the other security lessons, then take Operation Lockdown and lock a real machine down.
Practice SELinux Modes in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.