## Introduction to SELinux concepts w/pictures
- [Your visual how-to guide for SELinux policy enforcement](https://opensource.com/business/13/11/selinux-policy-guide)
- [The SELinux Coloring Book](http://people.redhat.com/duffy/selinux/selinux-coloring-book_A4-Stapled.pdf)
## RHEL 7 SELinux User's & Administrator's Guide
This is great. You should read at least the 1st and 10th chapter of it.
- [Introductory Chapter 1](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/chap-Security-Enhanced_Linux-Introduction.html) (short link: bit.ly/selinux-guide-rhel7)
- [1.1. Benefits of running SELinux](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/chap-Security-Enhanced_Linux-Introduction.html#sect-Security-Enhanced_Linux-Introduction-Benefits_of_running_SELinux)
- [1.2. Examples](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Introduction-Examples.html)
- [1.3. SELinux Architecture](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Introduction-SELinux_Architecture.html)
- [1.4. SELinux States and Modes](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Introduction-SELinux_Modes.html)
- [1.5. What Is New in Red Hat Enterprise Linux 7](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sec-What-is-new-in-RHEL-7.html)
- [Troubleshooting Chapter 10](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/chap-Security-Enhanced_Linux-Troubleshooting.html) (short link: bit.ly/selinux-guide-rhel7-troubleshooting)
- [10.1. What Happens when Access is Denied](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/chap-Security-Enhanced_Linux-Troubleshooting.html#sect-Security-Enhanced_Linux-Troubleshooting-What_Happens_when_Access_is_Denied)
- [10.2. Top Three Causes of Problems](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Top_Three_Causes_of_Problems.html)
- [10.3. Fixing Problems](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html)
- [10.3.1. Linux Permissions](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Linux_Permissions)
- [10.3.2. Possible Causes of Silent Denials](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Possible_Causes_of_Silent_Denials)
- [10.3.3. Manual Pages for Services](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Manual_Pages_for_Services)
- [10.3.4. Permissive Domains](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Permissive_Domains)
- [10.3.5. Searching For and Viewing Denials](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Searching_For_and_Viewing_Denials)
- [10.3.6. Raw Audit Messages](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages)
- [10.3.7. sealert Messages](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-sealert_Messages)
- [10.3.8. Allowing Access: audit2allow](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Allowing_Access_audit2allow)
## Targeted KCS Solutions
Solutions to specific problems.
- [How to add custom SELinux filename transition rules in RHEL7](https://access.redhat.com/solutions/2220381)
- [How to create SELinux dontaudit rules to hide avc denied warnings](https://access.redhat.com/solutions/1523643)
- [Is there a way to copy the entire SELinux config between machines?](https://access.redhat.com/solutions/108443)
## Man pages
- See [Guide: 10.3.3. Manual Pages for Services](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Manual_Pages_for_Services)
- Most useful are `man -k semanage`
- Additional man pages like `httpd_selinux` not installed by default but are available in the **selinux-policy-doc** package
```
yum install selinux-policy-doc
mandb &>/dev/null
man -k _selinux
```
Note that prior to RHEL 7.3, the man pages were in the **selinux-policy-devel** package
```
yum install selinux-policy-devel
mandb &>/dev/null
man -k _selinux
```
## Checking enforcing/permissive/disabled status
SELinux can be globally disabled via `/etc/default/selinux` or the kernel cmdline, requiring a reboot. SELinux can be put into permissive mode in the same way, but that can also be done on the fly without a reboot.
- See [Guide: 1.4. SELinux States and Modes](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Introduction-SELinux_Modes.html)
- Commands to check status:
```
sestatus # Show current & config-file status
getenforce # Show current status
grep ^SELINUX= /etc/selinux/config # Show config-file (permanent) status
grep -e enforcing= -e selinux= /etc/default/grub /etc/grub2.cfg # Check for kernel args
```
## Permissive domains
Instead of using `setenforce 0` on the whole system when you suspect a problem, switch a particular process domain into permissive mode.
- See `man semanage-permissive` and [Guide: 10.3.4. Permissive Domains](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Permissive_Domains)
- Immediately & permanently switch a process domain into permissive mode
```
semanage permissive --add logrotate_t
semanage permissive -a httpd_t
```
- Immediately & permanently switch a permissive domain back to enforcing
```
semanage permissive --del logrotate_t
semanage permissive -d httpd_t
```
- Check for permissive domains
```
semodule -l | grep permissive
```
- Immediately disable all permissive domains (i.e., switch them back to enforcing)
```
semodule -d permissivedomains
```
- Immediately enable any previously-set permissive domains (i.e., switch them back to permissive)
```
semodule -e permissivedomains
```
## File labels
Every file gets a label. Policy determines what a process domain can do to files of each label.
- See `man semanage-fcontext` and [Guide: 10.2.1. Labeling Problems](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Top_Three_Causes_of_Problems.html#sect-Security-Enhanced_Linux-Top_Three_Causes_of_Problems-Labeling_Problems)
- Set a file type on a directory
```
semanage fcontext --add samba_share_t "/path/to/dir(/.*)?" && restorecon -RF /path/to/dir
semanage fcontext -a httpd_sys_content_t "/path(/.*)?" && restorecon -RF /path
```
- Create an alternate location (equivalency rule) based on an existing directory (which is useful because it recursively includes rules)
```
semanage fcontext -a -e /var/www /web && restorecon -RF /web
semanage fcontext -a -e /home /our/home && restorecon -RF /our/home
```
- Check what a particular [source] process domain can do to a particular [target] file type
```
sesearch -CA -s httpd_t -t var_log_t
```
## Network port labels
Policy must explicitly allow confined services specific access to certain network port labels; however, the labels can be changed just as easily as file labels.
- See `man semanage-port` and [Guide: 10.2.2. How are Confined Services Running?](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Top_Three_Causes_of_Problems.html#sect-Security-Enhanced_Linux-Top_Three_Causes_of_Problems-How_are_Confined_Services_Running)
- Check for port labels for a particular domain/service
```
semanage port -l | grep http # Look for http-labeled ports
semanage port -l | grep ssh # Look for ssh-labeled ports
semanage port -l | grep 3333 # Look for a specific port
man httpd_selinux
man sshd_selinux
sesearch -CA -s httpd_t -c tcp_socket -p name_bind # Look for tcp port types that a particular domain is allowed to bind to
```
- Permanently set labels on network ports
```
semanage port -a -t http_port_t -p tcp 3333 # Permanently add a label to a specific port
semanage port -a -t ssh_port_t -p tcp 2222
```
## Boolean on/off switches
There are many commonly-used configurations that require opening up the default SELinux policy a little, e.g.: allowing webservers to send email or read content from NFS. This can always be done by flipping simple toggles.
- See `man semanage-boolean` and [Guide: 10.2.2. How are Confined Services Running?](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Top_Three_Causes_of_Problems.html#sect-Security-Enhanced_Linux-Top_Three_Causes_of_Problems-How_are_Confined_Services_Running)
- Check for booleans for a particular domain
```
semanage boolean -l | grep httpd
man httpd_selinux
```
- Set booleans
```
setsebool httpd_can_sendmail on # Immediate & temporary
setsebool -P httpd_use_nfs on # Permanent & takes a minute to rebuild policy
setsebool -P httpd_builtin_scripting=off httpd_tmp_exec=1 # "on" and "1", "off" and "0" all work; equals sign optional unless trying to do multiple booleans at once
```
## Inspect audit AVC records
All SELinux AVC denials get logged by the kernel to audit (assuming `auditd` is running) and thus show up in `/var/log/audit/audit.log` by default. These can be inspected directly or with `ausearch` & `aureport`.
- See `man ausearch` and `man aureport` and [Guide: 10.3.5. Searching For and Viewing Denials](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Searching_For_and_Viewing_Denials) and [Guide: 10.3.6. Raw Audit Messages](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages)
- Use `aureport` to get a broad overview
```
aureport -a # Get a report of all AVC denial events
aureport -i -a | awk 'NR==4 || NR>5' | column -t # Interpret syscall numbers to names; show in columnized list
```
- Use `ausearch` to drill down
```
ausearch -i -m avc # Show all from standard audit.log files
ausearch -i -m avc -ts recent # Show last 10 minutes
ausearch -i -m avc -ts today -c httpd # Show particular command since midnight
ausearch -i -m avc -ts 16:05 -su httpd_t # Show particular source (subject) SELinux context since 16:05 PM
```
## Leverage setroubleshoot to get recommendations
There's an optional `setroubleshoot-server` package that will automatically translate audit AVC records into more human-readable syslog messages with actionable recommendations.
- See `man sealert` and [Guide: 10.3.7. sealert Messages](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-sealert_Messages)
- Example usage
1. Install and enable
```
yum install setroubleshoot-server
service auditd restart
```
1. Note that there's a bug in the `setroubleshoot` packages shipped with RHEL 7.2 and older which makes the sealert command somewhat unusable. Update to the latest version. (See: [sealert (from setroubleshoot-server) in RHEL 7 fails with error: failed to connect to server: No such file or directory](https://access.redhat.com/solutions/2529361))
1. Do something that SELinux denies and watch the journal (or `/var/log/messages`) for the logs, e.g.:
```
~]# yum install httpd
...
~]# echo Listen 18888 >/etc/httpd/conf.d/listen18888.conf
~]# systemctl restart httpd
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
~]# journalctl _COMM=setroubleshootd
-- Logs begin at Tue 2016-08-16 00:28:39 EDT, end at Tue 2016-08-16 00:30:02 EDT. --
Aug 16 00:30:02 a72.example.com setroubleshoot[1463]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 18888. For complete SELinux messages. run sealert -l 87fea572-9f35-47cc-8c81-eb9e9ae8cad0
Aug 16 00:30:02 a72.example.com python[1463]: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 18888.
***** Plugin bind_ports (92.2 confidence) suggests ************************
If you want to allow /usr/sbin/httpd to bind to network port 18888
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 18888
where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_messaging_port_t, ntop_port_t, puppet_port_t.
***** Plugin catchall_boolean (7.83 confidence) suggests ******************
If you want to allow nis to enabled
Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.
Do
setsebool -P nis_enabled 1
***** Plugin catchall (1.41 confidence) suggests **************************
If you believe that httpd should be allowed name_bind access on the port 18888 tcp_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep httpd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp
```
1. Instead of using `journalctl`, you could of course also do something like ...
```
grep sealert /var/log/messages
```
1. Execute the suggested `sealert` command to view full details, e.g., from above
```
sealert -l 87fea572-9f35-47cc-8c81-eb9e9ae8cad0
```
- Another possibility is to use `sealert` to analyze a file, getting recommendations for all AVCs in it (could be any audit.log file from any system)
```
sealert -a /var/log/audit/audit.log | less -S
```
## Confining users
In the standard targeted policy, all users are unconfined; however, you can easily change that. You can start simple with preset users but of course you can get as granular as you want.
- See `man semanage-login` and `man semanage-user` and [Guide: 3.3. Confined and Unconfined Users](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Targeted_Policy-Confined_and_Unconfined_Users.html) and [Guide: 6. Confining Users](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/chap-Security-Enhanced_Linux-Confining_Users.html)
- Create a new user that is mapped to `guest_u` (i.e., no internet, no sudo/su or most other setuid/setgid apps, no X)
```
useradd -Z guest_u newuserbob
```
- Make it so `guest_u` & `xguest_u` won't be allowed to execute anything in `/tmp` or `$HOME`
```
~]# setsebool -P guest_exec_content=off xguest_exec_content=off
~]# semanage boolean -l | grep exec_content
auditadm_exec_content (on , on) Allow auditadm to exec content
guest_exec_content (off , off) Allow guest to exec content
dbadm_exec_content (on , on) Allow dbadm to exec content
xguest_exec_content (off , off) Allow xguest to exec content
secadm_exec_content (on , on) Allow secadm to exec content
logadm_exec_content (on , on) Allow logadm to exec content
user_exec_content (on , on) Allow user to exec content
staff_exec_content (on , on) Allow staff to exec content
sysadm_exec_content (on , on) Allow sysadm to exec content
```
- Confine an existing user, mapping to `user_u` (i.e., no su/sudo or most other setuid/setgid apps)
```
semanage login -a -s user_u existinguseralice
```
## Fix SELinux denials by allowing requested access
This should be a *last* resort ... done sparingly & with care. The vast majority of problems can be solved by setting proper file labels or tweaking booleans or figuring out that the application/admin is doing something wrong.
- See `man audit2allow` and [Guide: 10.3.8. Allowing Access: audit2allow](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Allowing_Access_audit2allow)
- Example:
```
ausearch -i -m avc | grep xxxx | audit2allow
```