SeLinux - the Basics

dos2unix

Well-Known Member
Joined
May 3, 2019
Messages
4,421
Reaction score
4,627
Credits
41,747
OK, so this is mostly a fedora/rhel/rocky thing. Most Debian distro's don't use SeLinux, they usually use appArmor.
I'm nor nearly as familiar with that one. So for now... just SeLinux basics. Now I have to confess something here, I've been using
SeLinux since the early 2000's. Seems like it was in Fedora 3 or 4. Redhat had it by at least RHEL 4 for sure. But in all that time using it..
I never really used "audit2why". It didn't have all the tools it has now in the early days, but now.. well things are a lot better.

The SELinux Troubleshooting Toolkit - Detailed

ausearch - Search the audit log
bashausearch -m avc -ts recent
ausearch -m avc -ts today
ausearch -m avc -ts 10:00
Code:
- Searches `/var/log/audit/audit.log` (the SELinux audit log)
- `-m avc` = look for AVC (Access Vector Cache) denial messages
- `-ts recent` = last 10 minutes
- Much easier than grepping through audit.log manually
- Shows you WHAT was denied, by WHOM, and WHEN

**Example output:**
type=AVC msg=audit(1234567890.123:456): avc: denied { read } for pid=1234
comm="httpd" name="index.html" dev="sda1" ino=789012
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:user_home_t:s0
tclass=file permissive=0
Translation: httpd tried to read a file labeled as user_home_t (wrong context for web content)
audit2why - Explains WHY something was denied
bashausearch -m avc -ts recent | audit2why
# or directly from log
audit2why < /var/log/audit/audit.log
Code:
- Takes AVC denial messages and explains them in plain English
- Tells you if it's a boolean, file context, or port issue
- Often suggests the fix
- Part of the `policycoreutils-python-utils` package (RHEL/Fedora)

**Example output:**
type=AVC msg=audit(1234567890.123:456): avc: denied { read } ...

Was caused by:
Missing type enforcement (TE) allow rule.
You can use audit2allow to generate a loadable module to allow this access.
Code:
or better:
Was caused by:
Incorrect file context on /data/website/index.html
Run: restorecon -v /data/website/index.html
audit2allow - Generate policy modules (USE CAREFULLY!)
bashausearch -m avc -ts recent | audit2allow -M mypolicy
semodule -i mypolicy.pp

Creates a custom SELinux policy to allow what was denied
DANGER: This is the "just make it work" hammer
Only use when you understand WHY it's being denied and there's no better fix
If audit2why suggests a boolean or restorecon, do that instead!

Think of it as chmod 777 - it works, but it's usually the wrong solution.
chcon - Change context (TEMPORARY)
bashchcon -t httpd_sys_content_t /data/website/index.html
chcon -R -t httpd_sys_content_t /data/website/
ls -Z /data/website/

Changes the SELinux security context of a file/directory
-t = type (the most common thing you change)
-R = recursive
Problem: Next time you run restorecon or the system relabels, your change is GONE
Good for testing: "If I change this context, does it work?"
Not good for production

semanage fcontext - Set context policy (PERMANENT)
bash# Add a rule
semanage fcontext -a -t httpd_sys_content_t "/data/website(/.*)?"

# List existing rules
semanage fcontext -l | grep website

# Delete a rule
semanage fcontext -d "/data/website(/.*)?"

Adds rules to the SELinux policy database
Uses regex patterns: "/data/website(/.*)?" = this directory and everything under it
Changes survive reboots and restorecon
After adding a rule, you MUST run restorecon to apply it
Part of policycoreutils-python-utils package

The pattern explained:

/data/website = the directory itself
(/.*)? = optionally match slash + any characters (everything inside)

restorecon - Restore contexts based on policy
bashrestorecon -v /data/website/index.html # single file, verbose
restorecon -Rv /data/website/ # recursive, verbose
restorecon -Rvn /data/website/ # dry-run (show what would change)

Reads the policy database and sets contexts to what they SHOULD be
-R = recursive
-v = verbose (show what changed)
-n = dry run (don't actually change anything)
The missing piece: After you use semanage fcontext to set policy, use restorecon to apply it
Also useful after copying files (they might have wrong contexts)

Think of it as:

semanage fcontext = "This is what /data/website SHOULD be labeled as"
restorecon = "Go apply those rules now"

semanage port - Manage port labels
bash# List all port definitions
semanage port -l | grep http

# Add a custom port
semanage port -a -t http_port_t -p tcp 8080

# Delete a port definition
semanage port -d -t http_port_t -p tcp 8080

SELinux doesn't just care about file contexts, it also cares about network ports
Apache can only bind to ports labeled http_port_t (default: 80, 443, 8008, 8009, 8443)
If you want Apache on port 8080, you need to label that port

getsebool / setsebool - Toggle policy behaviors
bash# List all booleans
getsebool -a

# Check specific boolean
getsebool httpd_can_network_connect

# Set temporarily (until reboot)
setsebool httpd_can_network_connect on

# Set permanently
setsebool -P httpd_can_network_connect on

SELinux has built-in policy "switches" called booleans
Common ones:

httpd_can_network_connect - can Apache make outbound connections?
httpd_can_sendmail - can Apache send email?
httpd_enable_homedirs - can Apache read from home directories?


ALWAYS use -P for permanent changes or they'll reset on reboot

The Typical Workflow
bash# 1. Something broke - check the log
ausearch -m avc -ts recent

# 2. Understand WHY it was denied
ausearch -m avc -ts recent | audit2why

# 3a. If it says "wrong file context":
semanage fcontext -a -t httpd_sys_content_t "/data/website(/.*)?"
restorecon -Rv /data/website/

# 3b. If it says "needs boolean":
setsebool -P httpd_can_sendmail on

# 3c. If it says "wrong port":
semanage port -a -t http_port_t -p tcp 8080

# 4. Test - try the operation again
 


audit2allow - The "Just Make It Work" Tool
bash# Basic usage
cat /var/log/audit/audit.log | audit2allow

# Generate a loadable module
ausearch -m avc -ts recent | audit2allow -M mypolicy
semodule -i mypolicy.pp

What It Does

audit2allow reads AVC denial messages and automatically generates SELinux policy rules that would allow whatever was blocked. It's essentially saying "here's the policy change that would make this work."
The Problem With It
It's the sledgehammer approach to SELinux. It works, but:

It's often too broad - might allow more than you actually need
It doesn't tell you WHY - just gives you a rule to allow it
It can mask real problems - like wrong file contexts or incorrect booleans
Security risk - blindly applying its suggestions can open holes in your security

Think of it as the SELinux equivalent of chmod 777 - it'll make things work, but you're bypassing security controls.
The History (and why it was frustrating)
audit2allow started as a Perl script, then Dan Walsh rewrote it in Python because he hates Perl. Karl MacMillan later rewrote it to use sepolgen LiveJournal.
The frustrating part? Dan Walsh would use audit2allow to generate a rule, load it into policy, and STILL get the exact same AVC denial. The problem was usually a constraint or RBAC violation that audit2allow couldn't detect or fix LiveJournal.
So in the FC2/FC3 days (2004-2005), you had:

Raw, cryptic AVC denials in /var/log/messages or /var/log/audit/audit.log
audit2allow that would generate rules...that sometimes didn't work
No audit2why to tell you what the actual problem was
No good documentation
Trial and error as your only debugging method

Example of audit2allow Output
bash$ cat /var/log/audit/audit.log | audit2allow

#============= httpd_t ==============
allow httpd_t user_home_t:file { read open };
allow httpd_t user_home_dir_t:dir search;
This tells you "add these allow rules" but it doesn't tell you:

WHY httpd is trying to access user home directories
Whether this is actually the right fix
If there's a boolean you should toggle instead
If the file contexts are just wrong

When audit2allow IS Useful
It's actually helpful in these scenarios:

After you understand the problem - use audit2why first, then if you genuinely need a custom policy, audit2allow can help draft it
For custom applications - if you're running software that doesn't have proper SELinux policy and you understand what it needs
As a starting point - generate the rules, then review and refine them rather than blindly loading them

The Modern Workflow (with audit2why)
bash# 1. See what was denied
ausearch -m avc -ts recent

# 2. Understand WHY (this is the game-changer)
ausearch -m avc -ts recent | audit2why

# 3. If audit2why says "wrong context" or "needs boolean":
# Fix it properly with restorecon or setsebool

# 4. Only use audit2allow if truly needed:
ausearch -m avc -ts recent | audit2allow -M mycustompolicy
# Review mycustompolicy.te carefully!
semodule -i mycustompolicy.pp

The Command Differences That Were Annoying
audit2allow uses -i to read input files, but audit2why uses < for redirection, so Dan Walsh was constantly getting them mixed up LiveJournal. Eventually he fixed audit2why to accept -i as well.
So back in my FC2/FC3 days, I was dealing with audit2allow generating rules that may or may not work, with no way to know if you were fixing the real problem or just papering over it. No wonder I have PTSD! (just kidding.. kind of)
 
I use fedora 95% of the time. Have been for years and I will admit that I usually disable SELinux because of the problems it causes. Maybe write a thing about what SELinux is, what it does and why it should or should not be used based on different Needs. You know.... A total beginner thing on SELinux. most of what I know on that is leave it alone and if it causes problems setenforce 0 is your friend. I would not mind learning more about it if it is worth the time.
 


Follow Linux.org

Members online


Latest posts

Top