SELinux adds another layer of permission checks on Linux systems. On SELinux enabled systems regular DAC permissions are checked first, and if they permit access, SELinux policy is consulted. If SELinux policy denies access, a log entry is generated in audit log in
/var/log/audit/audit.log or in dmesg if
auditd isn't running on the system.
SELinux assigns a label, called security context, to every object (file, process, etc) in the system:
Files have security context stored in extended attributes. These can be viewed with
SELinux maintains a database mapping paths patterns to default file contexts. This database is used when you need to restore default file contexts manually or when the system is relabeled. This database can be queried with
Processes are assigned a security context when an executable is run (
execve syscall). Process security contexts can be viewed with most system monitoring tools, for example with
ps Z $PID.
Other labeled objects also exist, but are not relevant to this answer.
SELinux policy contains the rules that specify which operations between contexts are allowed. SELinux operates on whitelist rules, anything not explicitly allowed by the policy is denied. The reference policy contains policy modules for many applications and it is usually the policy used by SELinux enabled distributions. This answer is primarily describing how to work with a policy based on the reference policy, which you are most likely using if you use the distribution provided policy.
When you run your application as your normal user, you probably do not notice SELinux, because default configuration places the users in unconfined context. Processes running in unconfined context have very few restrictions in place. You might be able to run your program without issues in user shell in unconfined context, but when launched using init system it might not work anymore in a restricted context.
When files are in a non-default location (not described in default policy) the issues are often related to the following reasons:
Files have incorrect/incompatible file context: Files moved with
mv keep their metadata including file security contexts from old location. Files created in new location inherited the context from parent directory or creating process.
Having multiple daemons using the same files: The default policy does not include rules to allow the interaction between the security contexts in question.
Files with incorrect security context
If the files are not used by another daemon (or other confined process) and
the only change is the location where files are stored, the required changes to SELinux configuration are:
- Add a new rule to file context database
- Apply correct file context to existing files
The file context on the default location can be used as template to for the new location. Most policy modules include man page documentation (generated using
sepolicy manpages) explaining possible alternative file contexts with their access semantics.
File context database uses regualr expression syntax, which allows writing overlapping specifications. It is worthwhile to note that applied context is the last specification found [src].
To add a new entry to file context database:
semanage fcontext -a -t <type> "/path/here/(/.*)?"
After new context entry is added to the database, the context from database can be applied on your files using
restorecon <files>. Running
-vn flags will show what file contexts would be changed without applying any changes.
Testing a new file context without adding a new entry in database
Context can be changed manually with
chcon tool. This is useful when you want to test the new file context without adding an entry to file context database.
New file context is specified in the arguments to
chcon. When used with
--reference= option, the security context from a reference file is copied to the target files.
using a specific context (
chcon -t default_t <target files>
or using a reference:
chcon --reference=<path to default location> <target files>
Note about different file systems & mount points
If the new location is its own mount point, the context can be set with a mount option. Context set with mount option isn't stored on disk, so it can also be used with file systems that do not support extended attributes.
mount <device> <mount point> -o context="<context>"
Allowing processes running in different security contexts to use the same files
Option 1: Booleans
Reference policy includes tunable options, called booleans, which enable/disable certain additional rules. Many of them allow inter-operation of different system daemons which usually do not use same files.
List of all possible tunable options and their descriptions can be listed using
semanage boolean -l.
audit2allow might also be able to directly tell which boolean needs to be enabled.
To enable/disable a boolean using
semanage boolean --on <boolean name>
semanage boolean --off <boolean name>
Booleans are the simplest way to modify the policy. However, all possible situations can not be addressed by toggling a boolean. Some booleans also allow very broad access, being overly permissive.
Option 2: Extend policy with a new module
If no boolean exists to allow the access, the policy needs to be modified by adding a custom module.
A simple module adding the required rules to allow access can be generated from log files using
audit2allow with following steps:
Set the daemon's domain (security context) to permissive mode. In permissive mode the policy isn't enforced, but logs are generated on the access the policy would normally deny.
semanage permissive -a <domain>
Test your daemon in normal operation to generate log entries.
Create a new policy module and insert it.
audit2allow -a -M <name>
semodule -i <name>.pp'
Re-enable enforcing mode
semanage permissive -d <domain>
This method works best when there are only a few security contexts involved. In a complex configuration you quite likely have to write your own policy module. Some resources for getting started are gentoo wiki and the reference policy API documentation.