Skip to main content
1 of 7
sebasth
  • 15.8k
  • 6
  • 53
  • 71

SELinux adds another layer of permission checks on Linux systems. Every object in system is assigned a label (one label per object), called security context. The context is usually displayed in user_t:role_t:type_t format, but for the scope of this answer the relevant part is the last component of the representation, the type.

SELinux policy contains the rules for what operations are allowed between these contexts. SELinux operates on whitelist rules. Anything not explicily permitted 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 primarly describing how to work with a policy based on the reference policy, which you are most likely using if you using the distribution provided policy.

For processes, the type in the context is called domain. Processes are assigned a context when the file is executed (execve syscall). If the policy doesn't contain rules describing a new security context, the new process inherits the context from the calling process. SELinux aware programs can also change their context runtime. The policy describes what executions and context transitions are allowed. You can view in what context your process is running in with ps Z $PID.

Security context for files are stored on file extended attributes. You can view the labels on files using ls -Z. File context for new file is inherited from the directory or set by the policy on creation. SELinux maintains a database for paths and default file contexts. This database can be queries using semanage tool.

When you run your application as your normal user, you probably do not notice SELinux in any way. Default configuration sets the users in unconfined context. Processes running in unconfined context have almost not restrictions in place.

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.

Problems

  • Files might have incorrect/incompatible file contexts when they are placed in non-default location. Files moved with mv also keep their old metadata (including security information in extended attributes) and file contexts.

  • If you have multiple daemons using the same files, the default policy might doesn't have rules to allow the interaction between the security contexts.

Non-default location: Relabel files

If the files are not used by another deamon (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 contexts to existing files

The context used 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) covering possible file contexts.

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>.

Context can be changed manually using chcon tool. When used with --reference= option, the security context from reference file is copied to the target files, otherwise the new context needs to be specified in the arguments.

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>" 

Sharing files between processes running in with different security contexts

Booleans

Reference policy includes many tunable options (booleans) to turn on/off specific rules. Many of them enable inter-operation of multiple daemons which in usually do not use same files.

List of all possible tunable options and their descriptions can be listed using semanage boolean -l. audit2why might also be able to directly tell which boolean needs to be enabled.

To enable/disable a boolean using semanage:

semanage boolean --on <boolean name> semanage boolean --off <boolean name> 

Booleans are the simplest way to modify the policy. However there are only limited amount of booleans covering these specific scenarios. Some booleans also allow very broad access, being overly permissive.

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.

  1. 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> 
  2. Test your daemon in normal operation to generate log entries

  3. Create a new policy module and insert it

     audit2allow -a -M <name> semodule -i <name>.pp' 
  4. Re-enable enforcing mode

     semanage permissive -d <domain> 
sebasth
  • 15.8k
  • 6
  • 53
  • 71