Search This Blog




High-level overview

·      SELinux is a labeling system
·      You apply labels to every component in your system incuding
o   Users
o   Files
o   Directories
·      You then write a policy to utilize these policies

Example: men can only use mens toilets

Basically all things that have the same label you can define to be able to access each other.

DAC still functions, but once DAC allows permissions for a specific action, MAC kicks in and does a secondary check to ensure that the labels match the policy.

Flaws of DAC:
·      Owners can do whatever they want to a file and can mess things up
o   Especially if root


Made up of objects and labels

Objects are anything in a linux system including files, processes, users, etc

Labels are security context of individual objects stating which objects have access to what


SELinux is turned on but not enforcing
The point of it is to observe what is going on and to log a message saying that if it was enforcing it would have blocked it.

Useful for temporarily enabling and seeing what would be blocked if you were to enable SElinux

This ensures that all labeling is happening to ensure you’re ready for enforcing.

Viewing and Setting SELinux mode from cmdline

Setenforce – can temporarily enable/disable selinux

Can edit grub to change selinux to debug why a system wont boot for SELinux reasons.

Just use the option: enforcing=0 or enforcing=1 on the kernel line

Labels and Security Contexts

Every label has the following 4 values set
·      User
·      Role
·      Type
·      Level

The ls –Z option shows the SELinux label
The –Z actually shows the majority of selinux contexts

Id –Z
Ls –Z
Ps –Z
Netstat –Z

They all show colon delimited values where it is laid out as follows:

Policy Types

Targeted is the default and likely the only one we need to use

Government grade security will likely use MLS for differnet levels of access for different levels of security (secret, top secret, etc)

Minimum is for lower spec machines.

/etc/selinux/* is where your policy is actually stored. You would need to install other policies if you need them

SELinux Labels

Type Enforcement

Objects with the same type are grouped together so that they can access each other

Normally used for service separation.

Model is called “The model of least permission”

Ps –eZ | grep crond

The type field will be crond_t
It will only be able to interact with other objects of type crond_t

Unconfined_t type
Any process that doesn’t have an selinux policy confining it to a domain is tagged with unconfined_t

Processes in unconfined_t are basically running outside of selinux as they can all interact with each other. User processes and custom apps will all be run in unconfined_t

By default in a targeted policy users get mapped through to unconfined_t as the type. So even user created processes will be created with a user role of unconfined_u as well.

To check all of the kinds of types on a linux system:
Selinux –t

User Types

Seinfo –u
Type is king so not many user types are created.
All users are mapped to an selinux type and this can be viewed using:
semanage login –l

This shows how users are mapped to selinux users.
The default is to map them to unconfined_u and root are unconfined_u

Role Attribute

Roles can be configured then users mapped to those roles.
Tells which users can access which roles and which roles can access which domains.

seinfo –r
Mostly useful for defining a RBAC system

Level Attribute

Levels are only used by MLS (Multi Level Security) in government and military situations.
Top Secret
The above levels are what are defined in the level attribute

SELinux Decision Making Process

The default action to any request on SELinux system is to deny and all allowed access needs to be configured using an allow rule

SElinux first checks and then if it says yes the operation goes ahead if it is denied then it is logged.

Policy look-up results get stored in Access Vector Cache (AVC) which it uses to cache some lookups.

If DAC rules deny it it wont even bother looking at MAC

SELinux Policy

Targeted Policy – Generally focuses on Type enforcement

Targeted processes confines specific daemons
·      Network facing
·      Start at boot
The above are the targeted services as they are likely the most vulnerable

Most user processes are unconfined which us usually unconfined_t domain
seinfo –aunconfined_domain_type –x
Will list all of the unconfined domains

Targeted are said to be run in confined domains
unconfined domains are just subject to traditional DAC rules
No MAC is defined for unconfined domains

This is kind of like locking the front door but leaving everything inside unlocked. You’re basically targeting things that you think are likely to be attacked.

Apache is a good demonstration because it is a large attack vector perfect for targeted policy
sestatus – to check if targeted policy is running

systemctl status httpd.service – check if its running

ps –eZ | grep httpd

Apache web server can access files of many times including: httpd_content_type httpd_sys_content

Files under /var/www get the httpd_sys_content type applied automatically by default

ls –Z /var/www/html/ - view to make sure they have httpd_sys_content_t

All file will inherit a new SELinux context from the folder they’re copied to
Example: If you copy an index.html from another web server that has a type of httpd_sys_content_t on it to just a general local directory called /tmp. You will not actually get the httpd_sys_content_t type copied over it will actually take over the type that you have under the /tmp directory.

Changing Contexts

chcon –t user_home_t /var/www/html/index.html
ls –Z /var/www/html/index.html

The above will change the contexts of the file index.html and disallow you to wget the file remotely as apache no longer has access to the file because it is now in a different context.

Allow Rules

sesearch --allow
# above lists out all of the allow rules
sesearch --allow | grep http_content
# lists all http context types

# Allows any process in httpd_t type access to files of httpd_content_type as long as they are files and give them the operations (ioctl, read, getattr, lock, and open) actions
allow httpd_t httpd_content_type : file { ioctl read getattr lock open };

allow|deny domain_t context_type_t : file|dir { operations };

Policy Modules

You can dynamically load new modules in SELinux but they all need to be explicitly loaded. They wont work just because you’ve added the appropriate contexts.

You can view existing loaded modules using:
semodule -l
More and more services are being targeted in newer version of linux

You can also view active modules using
ls -l /etc/selinux/targeted/modules/active/modules
Which will show a bunch of policy modules named *.pp AKA policy package modules

semodule -d xen - unload the xen module

All of the packages are recompiled put into a binary and loaded in kernel and is stored in /etc/selinux/targeted/policy.ver#

Policy config which shows the default file contexts for the entire filesystem.

The above basically stores all of the rules that by default apply file contexts to files under specific directories.

An example is below of all of the /var/www files being labeled with httpd_sys_content_t
/var/www(/.*)? system_u:object_r:http_sys_content_t:s0
The above is useful for figuring out what the default type value would have been if you accidentally changed it

SELinux Advanced Topics

You can enable or disable policy settings on the fly using SELinux Booleans
getsebool -a
semanage boolean -l
The above is how we see the Booleans and list them
You can set Booleans by using:
setsebool name <on|off>
To make permanent changes you have to:
setsebool name <on|off> -P
Takes a new version of the policy and loads it into the kernel

The SELinux Booleans are the easiest to change policy markets and enable you to make these changes on the fly easily.

To view any locally set Boolean values that someone has changed on the system look in the following file:

Creating policy rules from scratch can be difficult so theres an easy way to do so other than booleans.

Creating Allow Rules for policy with Audit2Allow

ls -Z /var/www/html/index.html
We will make sure that the context is incorrect using chcon
chcon -t user_home_t /var/www/html/index.html

Since apache doesn’t have access to this file you get a deny and can check this by looking at /var/log/audit/audit.log and looking for AVC deny messages.

The following gives you a more detailed view of the error
audit2allow -wa

The audit2allow utility will tell you that it is caused by an incorrect Boolean and will then tell you how to actually fix it giving the command required to allow it.

If a Boolean can be set that is preferred. It will be fairly hard to find a scenario where something cannot be allowed purely by a Boolean but audit2allow does allow the creation of new policy where booleans cannot be set.

Create a new policy from the log
audit2allow -aM test.local

It will then tell you how to load it:
semodule -i test.local.pp

Ensure the new module is loaded:
semodule -l | grep test

Try to wget the file again and it will be successful:

audit2allow looks at AVC deny messages and creates new rules to stop the errors from occurring in the future.

This can be pretty dangerous if you’re not careful you can circumvent poorly.

Permissive Domains

Testing the impact of SELinux on apps is challenging and you used to have to put the entire system in permissive mode and look at AVC deny messages and make required changes.

The entire system in permissive mode is not a great idea.

Permissive domains allows us to put only specific domains into permissive mode for testing.

Get a list of permissive domains on the system:
semanage permissive -l

Show how many total permissive domains we have:
seinfo | grep Permissives

To make a domain permissive:
semanage permissive -a <domain_name>

Disable and remove previous modules:
semodule -d test.local
semodule -r test.local
Validate it is gone:
semodule -l | grep test

wget should fail again

You could make the domain that apache runs in as permissive.

First check which domain apache runs in:
ps -eZ | grep httpd
It will show you that apache runs in the httpd_t domain.

Make the domain permissive:
semanage permissive -a httpd_t
Now you will be able to wget the file and view the log messages as well to see what is wrong with the existing policy.

Remove permissive domain:
semanage permissive -d httpd_t

SELinux Troubleshooting

Common Mistakes

-       Running services in custom directories
-       Running services against custom ports
-       Think about SELinux impact any time a customization is complete (say we want apache installed in a different directory)

Troubleshooting steps
setenforce 0 - set to permissive mode to debug

targeted policy means its type related
-       debug with ls -Z in the directory

Change to correct content type if set incorrectly
semanage fcontext -at httpd_sys_content_t “/www(/.*)?”
The above changes the context from default to the appropriate http context for the directory www and all directories/files below.
Run restorecon on the directory
restorecon -R -v /www
Turn selinux back on

Copying and Moving files

Copied files inherit new labels for its parent directory at the destination
Moved files will keep the old label

You can preserve context via cp -c or --preserve=context

Relabel the filesystem and Permanent Changes

Go from disabled > permissive > reboot > enforcing > reboot

A full filesystem relabel will reset labels to default values but will overwrite changes you’ve made using the utility chcon.

You can autorelabel the entire filesystem by touching a file in the root directory
touch /.autorelabel

Any changes to labels using chcon can be restored using autorelabel or restorecon.

chcon doesn’t update the file_contexts file

Chcon are just stored in extended filesystem attributes not as part of the policy. semanage or fcontexts will make permanent changes and you can reference format in the file_contexts file.

Using fcontext it will create a file_contexts.local

Log Files

/var/log/audit/audit.log - deny messages

Useful string to search “SElinux is preventing” under /var/log/messages

Don’t audit rules
-       don’t report on harmless denials
-       seinfo and look for dontaudit logs
-       semodule -DB - disable the don’t audit rules
-       semodule -B - enable the don’t audit rules

No comments:

Post a Comment