Getting to know SELinux booleans and tunables as policy behavior switches that can be changed without rewriting modules: how to read status with getsebool, changing temporarily and persistently with setsebool -P, common booleans for web, samba, and FTP, and how to audit changes that have been made.

In episode 5, you saw how policy modules govern domains: each process uses a specific domain, and allow rules determine what that domain may do. When a denial appears, the first instinct is to open the policy and write a new module. Yet in many cases there's a much faster and safer path: booleans.
SELinux booleans are policy behavior switches already prepared by the policy authors. You don't need to write a single rule — just flip the switch.
Think of the SELinux policy like a house's electrical installation. A boolean is a light switch: its position can be changed at any time without cutting off the house's power source. A tunable is rewiring work at the electrical panel: changing it requires thorough work because it involves recompiling the policy. Both produce different behavior — different current flow — but the cost and way of changing them are not the same.
At the technical level, booleans live in if blocks inside the policy:
if (httpd_can_network_connect) {
allow httpd_t http_client_port_t:tcp_socket name_connect;
}If the boolean is true, the rule branch above gets loaded and the denial disappears. If false, that rule doesn't exist. This value is what you change with the setsebool command, not by modifying the module.
Tunables are distinguished by a special flag inside the policy. When the policy is compiled, dead tunable branches are even stripped from the final policy — as a consequence, changing a tunable requires a policy reload, not as easy as flipping a switch. For daily practice, just consider: booleans can be changed anytime, tunables only when there's a strong reason.
Note
A quick way to tell them apart: all tunables also appear in getsebool -a, but in semanage boolean -l they appear with a special marker. Your main focus as an administrator is regular booleans — because that's the tool most often used to resolve production denials without downtime.
Before changing anything, look at the current values first. Two commands you must memorize:
getsebool -a for a list of all booleans and their current values.semanage boolean -l for a complete list along with short descriptions.getsebool -a | grep httpdThe semanage boolean -l output looks roughly like this (simplified):
httpd_can_network_connect (on, on) httpd can make network connections
httpd_can_network_connect_db (off, off) httpd can connect to database
httpd_enable_homedirs (off, off) support httpd in home dirsNotice the last column: the description is a short sentence from the policy author. This isn't decoration — it's the official documentation of what the boolean does. Get in the habit of reading descriptions before turning anything on. The (on, on) column shows the current value and the default value; comparing the two quickly tells you which settings deviate from the defaults.
There are two ways to turn on a boolean, and they have very different effects:
sudo setsebool httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect onThe first command only lasts until the system reboots — great for a quick test: if it turns out that wasn't the cause, just reboot or set it back to off. The second command with the -P (persistent) flag writes the value into the policy store so it survives reboots.
Persistent values are stored as a simple text file inside the policy store, usually /var/lib/selinux/targeted/active/booleans.local:
httpd_can_network_connect=1
samba_enable_home_dirs=1Because the contents are just text, you can make them part of your versioned configuration: use semanage boolean -E to export the current boolean settings to a file, and semanage boolean -F to import them back. This is the foundation of the policy-as-code approach we'll dive into in the final episodes of this series.
Warning
Be careful not to misuse the mode. If you only run setsebool without -P on a production server and then forget about it, the change silently disappears at reboot — and an incident that was supposedly "resolved" will appear again. Good habit: use -P only after testing is complete, and record every change in a changelog. For many hosts, don't set them manually one by one — use Ansible or config management tooling, which we'll cover in a dedicated episode.
Some booleans appear over and over in almost every sysadmin job description. The table below is a "pocket dictionary" you need to memorize:
| Boolean | Effect | Example usage |
|---|---|---|
httpd_can_network_connect | allow httpd to make outbound connections | reverse proxy to a backend application |
httpd_can_network_connect_db | allow httpd to connect to a database | web app using MySQL or PostgreSQL |
httpd_enable_homedirs | allow httpd to read home directories | per-user web hosting |
httpd_enable_cgi | allow CGI script execution | CGI-based applications |
samba_enable_home_dirs | allow samba to read home directories | file server for user homes |
ftpd_anon_write | allow writes by anonymous FTP | FTP server for uploads |
container_connect_any | allow containers to reach any port | container workloads with dynamic ports |
Tip
The correct troubleshooting pattern: a denial appears, look at the description of the boolean that best matches the symptoms, enable only that boolean, then verify the denial is gone with ausearch or the application logs. Never "turn on all booleans" to stop errors — that's the same as switching SELinux off piece by piece, and it negates the protection you're building.
Booleans are configuration that's easy to pull out and plug in — and therefore also easy to misuse. The audit log records every policy load, including those triggered by setsebool -P. Check the history with:
ausearch -m MAC_POLICY_LOAD -ts recentMake this part of your investigation workflow: when did the boolean change, does that change correlate with the start of the problem, and who did it. Without an audit trail, debugging strange security issues is just guesswork.
In this episode 6, you've understood that booleans are policy behavior switches that don't require rewriting modules: how to read them with getsebool and semanage boolean -l, how to change them temporarily and persistently with setsebool -P, the dictionary of the most-used booleans, and how to audit changes through the logs.
The key takeaways:
setsebool without -P first, then make it persistent after it's proven.There are times when booleans don't provide the switch you need, and denials persist even with all relevant booleans on. That's when you enter the world of local policy creation. In episode 7, we'll unpack audit2allow & Local Policy Generation: the correct denial debugging workflow, from reading audit logs, asking audit2allow for rule suggestions, to creating and installing your own policy module with audit2allow -M and semodule -i, along with best practices so you don't just generate policies blindly.