Need help?

Our experts have had an average response time of 11.7 minutes in August 2021 to fix urgent issues.

We will keep your servers stable, secure, and fast at all times for one fixed price.

Files and Processes in SELinux on CentOS 7 – Let’s discuss

by | Mar 25, 2021

Don’t know about Files and Processes in SELinux. We can help you.

A Linux kernel security module, SELinux brings heightened security for Linux systems.

A file security context is a type and a process security context is a domain.

As part of our Server Management Services, we assist our customers with several Linux queries.

Today, let us discuss Files and Processes in SELinux on CentOS 7.


Files and Processes in SELinux on CentOS 7

In this article, we run the commands as the root user.

  • Creating Test User Accounts

Initially, we create four user accounts to demonstrate SELinux capabilities.

  1. regularuser
  2. switcheduser
  3. guestuser
  4. restricteduser

As the root user, we run the following command to add the regularuser account:

# useradd -c “Regular User” regularuser

Then we change its password:

# passwd regularuser

In the output we give the new password:

Changing password for user regularuser.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

Similarly, we create the other accounts too:

# useradd -c “Switched User” switcheduser
# passwd switcheduser
# useradd -c “Guest User” guestuser
# passwd guestuser
# useradd -c “Restricted Role User” restricteduser
# passwd restricteduser


SELinux for Files and Processes

SELinux secure how processes access files in a Linux environment. Without it, if the system compromises under the root user, the app can do whatever it wants because the root has all-encompassing rights on every file.

With SELinux, a process or application will have only the rights it needs to function and NOTHING more.

The SELinux policy for the application will determine what types of files it needs access to and what processes it can transition to. A policy is basically a set of rules that maps processes and users to their rights.

  • SELinux File Contexts

Initially, we will understand SELinux file contexts.

If we perform a regular ls -l command against the /etc directory.

# ls -l /etc/*.conf

Our output will be similar to:

-rw-r–r–. 1 root root 19 Aug 19 21:42 /etc/locale.conf
-rw-r–r–. 1 root root 662 Jul 31 2013 /etc/logrotate.conf
-rw-r–r–. 1 root root 5171 Jun 10 07:35 /etc/man_db.conf
-rw-r–r–. 1 root root 936 Jun 10 05:59 /etc/mke2fs.conf

Here, we will add the -Z flag:

# ls -Z /etc/*.conf

This gives an extra column of information after the user and group ownership:

-rw-r–r–. root root system_u:object_r:locale_t:s0 /etc/locale.conf
-rw-r–r–. root root system_u:object_r:etc_t:s0 /etc/logrotate.conf
-rw-r–r–. root root system_u:object_r:etc_t:s0 /etc/man_db.conf
-rw-r–r–. root root system_u:object_r:etc_t:s0 /etc/mke2fs.conf

Then let us take a closer look at one of the security contexts.

-rw-r–r–. root root system_u:object_r:etc_t:s0 /etc/logrotate.conf

Here, the security context is:


We can see four parts and each separates by a colon (:). The first part is the SELinux user context for the file. We can see that it is system_u.

The second part specifies the SELinux role, which is object_r.

The most important part is the third one, etc_t. This is the part that defines what type the file or directory belongs to.

As another example, let us check the type contexts for user home directories:

# ls -Z /home

Usually, home directories have a different context type: user_home_dir_t

drwx——. guestuser guestuser unconfined_u:object_r:user_home_dir_t:s0 guestuser
drwx——. root root system_u:object_r:lost_found_t:s0 lost+found
drwx——. regularuser regularuser unconfined_u:object_r:user_home_dir_t:s0 regularuser
drwx——. restricteduser restricteduser unconfined_u:object_r:user_home_dir_t:s0 restricteduser
drwx——. switcheduser switcheduser unconfined_u:object_r:user_home_dir_t:s0 switcheduser
drwx——. sysadmin sysadmin unconfined_u:object_r:user_home_dir_t:s0 sysadmin

The fourth part of the security context is s0. Basically, this is another way of enforcing the SELinux security policy and shows the sensitivity of the resource (s0).

  • SELinux Process Contexts

Initially, we start the Apache and SFTP services.

# service httpd start
# service vsftpd start

We can run the ps command with a few flags:

# ps -efZ | grep ‘httpd\|vsftpd’

Generally, the -Z flag is for displaying SELinux contexts.

The output gives us the user running the process, the process ID, and the parent process ID:

system_u:system_r:httpd_t:s0 root 7126 1 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 7127 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 7128 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 7129 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 7130 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:httpd_t:s0 apache 7131 7126 0 16:50 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
system_u:system_r:ftpd_t:s0-s0:c0.c1023 root 7209 1 0 16:54 ? 00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 7252 2636 0 16:57 pts/0 00:00:00 grep –color=auto httpd\|vsftpd

Here, the security context is this part:


It has four parts: user, role, domain, and sensitivity. The user, role and sensitivity work like the same contexts for files. However, the domain is unique to processes.

For instance, above we saw that a few processes run within the httpd_t domain, while one runs within the ftpd_t domain.

The domain gives the process a context to run within. It tells the process what it can do and what it cannot do. This ensures that each process domain can act on only certain types of files and nothing more.

With this model, the worst a hijacker can do is damage the files it has access to.

For example, the vsftp daemon will not have access to files like Sendmail or samba. This restriction enforces as the SELinux policy loads into memory, and thus the access control becomes mandatory.

  • How Processes Access Resources

In order to run, a process have to access its files and perform some actions on them (open, read, modify, or execute). Each process has access to certain types of resources only (files, directories, ports, etc.).

Generally, the access rules follow a standard allow statement structure:

allow <domain> <type>:<class> { <permissions> };

A generic allow statement means:

  1. If a process is of a certain domain
  2. And the resource object it is trying to access is of a certain class and type
  3. Then allow the access
  4. Else deny access

For instance, let us consider the security contexts of the httpd daemon running on the CentOS 7 system:

system_u:system_r:httpd_t:s0 7126 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 7127 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 7128 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 7129 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 7130 ? 00:00:00 httpd
system_u:system_r:httpd_t:s0 7131 ? 00:00:00 httpd

The default home directory for the webserver is /var/www/html.

Hence, let us create a file within that directory and check its context:

# touch /var/www/html/index.html
# ls -Z /var/www/html/*

The file context for our web content will be httpd_sys_content_t:

-rw-r–r–. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html

We use the sesearch command to check the type of access for the httpd daemon:

# sesearch –allow –source httpd_t –target httpd_sys_content_t –class file

Here, the source domain is httpd_t, the same domain Apache is running in.

The output will be similar to:

Found 4 semantic av rules:
allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t httpd_content_type : file { ioctl read getattr lock open } ;
allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename execute open } ;

Notice the first line:

allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ;

It says that the httpd daemon has I/O control, read, get attribute, lock, and open access to files of the httpd_sys_content type.

In this case, our index.html file has the same type.

Let us first modify the web page (/var/www/html/index.html):
This is a test web page
<h1>This is a test web page</h1>

Next, we will change the permission of the /var/www/ folder and its contents, followed by a restart of the httpd daemon:

# chmod -R 755 /var/www
# service httpd restart

Then we try to access it from a browser.

Depending on how the server is set up, we may have to enable port 80 in the IPTables firewall for allowing incoming HTTP traffic from outside the server.

Next, let us change the context of the file. We will use the chcon command for it.

The –type flag for the command allows us to specify a new type for the target resource. Here, we are changing the file type to var_t.

# chcon –type var_t /var/www/html/index.html

We can confirm the type change:

# ls -Z /var/www/html/
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 index.html

Then, when we try to access the web page, we may come across a Forbidden error, or the generic CentOS “Testing 123” page.

The error occurs because we changed the context of the index.html file to var_t and Apache can no longer read it.

To resolve this, we change the file type with the restorecon command. The -v shows the change of context labels:

# restorecon -v /var/www/html/index.html
restorecon reset /var/www/html/index.html context unconfined_u:object_r:var_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

Now, when we access the page it will show, “This is a test web page” text again.

Making sure files and directories have the correct context is pivotal to making sure SELinux is behaving as it should.


Context Inheritance for Files and Directories

Context inheritance means unless specified by the policy, processes, and files are created with the contexts of their parents.

For instance, if we have a process “proc_a” spawning another process “proc_b”, the spawned process will run in the same domain as “proc_a” unless the SELinux policy specifies otherwise.

Similarly, if we have a directory with a type of “some_context_t”, any file or directory under it will have the same type of context unless the policy says otherwise.

To illustrate this, let us check the contexts of the /var/www/ directory:

# ls -Z /var/www

The HTML directory within /var/www/ has the httpd_sys_content_t type context. The index.html file within it has the same context (ie, the context of the parent):

drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html

In a copy operation, the copied file or directory will assume the type context of the target location.

In the command below, we copy the index.html file (with “httpd_sys_content_t” type context) to the /var/ directory:

# cp /var/www/html/index.html /var/

Now we can see it has changed to var_t, the context of its current parent directory:

# ls -Z /var/index.html
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /var/index.html

We can override this change of context by the –preserver=context clause in the cp command.

We preserve the original contexts when files or directories move.

In the following command, we move the /var/index.html to the /etc/ directory:

# mv /var/index.html /etc/

Eventually, if we check we can see that the var_t context is preserved under the /etc/ directory:

# ls -Z /etc/index.html
-rwxr-xr-x. root root unconfined_u:object_r:var_t:s0 /etc/index.html

We do this to simplify the backup process and also to tighten security.

  • SELinux in Action: Testing a File Context Error

Initially, we will create a directory named www under the root. We will also create a folder called HTML under www.

# mkdir -p /www/html

The ls -Z command will show these directories have been created with the default_t context:

# ls -Z /www/
drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 html

Then we copy the contents of the /var/www/html directory to /www/html:

# cp /var/www/html/index.html /www/html/

We now edit the httpd.conf file to point to this new directory as the website’s root folder. We will also have to relax the access rights for this directory.

# vi /etc/httpd/conf/httpd.conf

First, we comment out the existing location for document root and add a new DocumentRoot directive to /www/html:

# DocumentRoot “/var/www/html”
DocumentRoot “/www/html”

We also comment out the access rights section for the existing document root and add a new section:

#<Directory “/var/www”>
# AllowOverride None
# Allow open access:
# Require all granted

<Directory “/www”>
AllowOverride None
# Allow open access:
Require all granted

Finally, we restart the httpd daemon:

# service httpd restart

Once done, the web page will give us the same “403 Forbidden” error (or default “Testing 123” page).

This happens because the index.html file’s context changes during the copy operation. We need to change it back to its original context (httpd_sys_content_t).

  • Change and Restore SELinux File Contexts

To change file contents we can use the commands chcon and restorecon. However, this method is only temporary: a file system relabel or restorecon command will revert the file back to its original context.

Also, running chcon requires knowledge of the correct context for the file. If we run restorecon, the file will have the correct context re-applied and the changes will be made permanent.

Conveniently, SELinux “remembers” the context of every file or directory in the server.

In CentOS 7, contexts of files already existing in the system are in the /etc/selinux/targeted/contexts/files/file_contexts file. Contexts of new directories and files are in the /etc/selinux/targeted/contexts/files/file_contexts.local file.

So when we run the restorecon command, SELinux will look up the correct context from one of these two files and apply it to the target.

The command below shows an extract from one of the files:

# cat /etc/selinux/targeted/contexts/files/file_contexts
/usr/(.*/)?lib(/.*)? system_u:object_r:lib_t:s0
/opt/(.*/)?man(/.*)? system_u:object_r:man_t:s0
/dev/(misc/)?agpgart -c system_u:object_r:agp_device_t:s0
/usr/(.*/)?sbin(/.*)? system_u:object_r:bin_t:s0
/opt/(.*/)?sbin(/.*)? system_u:object_r:bin_t:s0
/etc/(open)?afs(/.*)? system_u:object_r:afs_config_t:s0

To permanently change the context of our index.html file under /www/html, we have to follow a two-step process.

First, we run the semanage fcontext command.

This will write the new context to the /etc/selinux/targeted/contexts/files/file_contexts.local file. We do this for both directories.

# semanage fcontext –add –type httpd_sys_content_t “/www(/.*)?”
# semanage fcontext –add –type httpd_sys_content_t “/www/html(/.*)?”

To ensure, we can check the file context database:

# cat /etc/selinux/targeted/contexts/files/file_contexts.local

We can see the updated contexts as:

# This file is auto-generated by libsemanage
# Do not edit directly.

/www(/.*)? system_u:object_r:httpd_sys_content_t:s0
/www/html(/.*)? system_u:object_r:httpd_sys_content_t:s0

Then, we run the restorecon command to relabel the file or directory:

# restorecon -Rv /www
restorecon reset /www context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /www/html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
restorecon reset /www/html/index.html context unconfined_u:object_r:default_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0

Now accessing the web page will work.

In addition, the nifty tool, matchpathcon can help troubleshoot context problems.

This command will look at the current context of a resource and compare it with what is listed under the SELinux context database. If different, it will suggest the changes.

For instance, in the /www/html/index.html file we use the -V flag that verifies the context:

# matchpathcon -V /www/html/index.html

The matchpathcon output will show that the context is verified.

/www/html/index.html verified.

On the other hand, for an incorrectly labeled file, the message will say:

/www/html/index.html has context unconfined_u:object_r:default_t:s0, should be system_u:object_r:httpd_sys_content_t:s0


Domain Transition

Domain transition is the method where a process changes its context from one domain to another.

The illustration of the same is like this:

Process a -> Executable file -> Process b
Context a -> Context x -> Context b

Domain transition is fairly common in SELinux.

For instance, consider the vsftpd process on the server. If it is not running, we can run the service vsftpd start command to start the daemon.

Next, we consider the systemd process. It is the replacement of the System V init process and runs within a context of init_t:

# ps -eZ | grep init
system_u:system_r:init_t:s0 1 ? 00:00:02 systemd
system_u:system_r:mdadm_t:s0 773 ? 00:00:00 iprinit

The process running within the init_t domain is a short-lived one.

To check the domain contexts of the files and processes, we run:

# ls -Z /usr/sbin/vsftpd
-rwxr-xr-x. root root system_u:object_r:ftpd_exec_t:s0 /usr/sbin/vsftpd

In order to check the process, we run:

# ps -eZ | grep vsftpd
system_u:system_r:ftpd_t:s0-s0:c0.c1023 7708 ? 00:00:00 vsftpd

So here the process running in the init_t domain is executing a binary file with the ftpd_exec_t type. That file starts a daemon within the ftpd_t domain.

The application or the user cannot control this transition.

This has been stipulated in the SELinux policy that loads into memory as the system boots. In SELinux, pre-written policies control such access.

Domain transition is subject to three strict rules:
  • The parent process of the source domain must have the execute permission for the application sitting between both the domains.
  • The file context for the application must identify as an entrypoint for the target domain.
  • The original domain must allow transitioning to the target domain.

Taking the vsftpd daemon example above, let us run the sesearch command with different switches to see if the daemon conforms to these three rules.

First, the source domain init_t needs to have execute permission on the entrypoint application with the ftpd_exec_t context. So if we run the following command:

# sesearch -s init_t -t ftpd_exec_t -c file -p execute -Ad

The result shows that processes within init_t domain can read, get attribute, execute, and open files of ftpd_exec_t context:

Found 1 semantic av rules:
allow init_t ftpd_exec_t : file { read getattr execute open } ;

Then, we check if the binary file is the entrypoint for the target domain ftpd_t:

# sesearch -s ftpd_t -t ftpd_exec_t -c file -p entrypoint -Ad
Found 1 semantic av rules:
allow ftpd_t ftpd_exec_t : file { ioctl read getattr lock execute execute_no_trans entrypoint open } ;

The output verifies the same.

And finally, the source domain init_t needs to have permission to transition to the target domain ftpd_t:

# sesearch -s init_t -t ftpd_t -c process -p transition -Ad

As we can see below, the source domain has permission:

Found 1 semantic av rules:
allow init_t ftpd_t : process transition ;

[Stuck with the process? We can help you]



In short, managing file and process context are at the heart of a successful SELinux implementation. Today, our Support Techs took you through the Files and Processes in SELinux.


Never again lose customers to poor server speed! Let us help you.

Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.


var google_conversion_label = "owonCMyG5nEQ0aD71QM";


Submit a Comment

Your email address will not be published. Required fields are marked *

Privacy Preference Center


Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.

PHPSESSID - Preserves user session state across page requests.

gdpr[consent_types] - Used to store user consents.

gdpr[allowed_cookies] - Used to store user allowed cookies.

PHPSESSID, gdpr[consent_types], gdpr[allowed_cookies]


Statistic cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.

_ga - Preserves user session state across page requests.

_gat - Used by Google Analytics to throttle request rate

_gid - Registers a unique ID that is used to generate statistical data on how you use the website.

smartlookCookie - Used to collect user device and location information of the site visitors to improve the websites User Experience.

_ga, _gat, _gid
_ga, _gat, _gid


Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.

IDE - Used by Google DoubleClick to register and report the website user's actions after viewing or clicking one of the advertiser's ads with the purpose of measuring the efficacy of an ad and to present targeted ads to the user.

test_cookie - Used to check if the user's browser supports cookies.

1P_JAR - Google cookie. These cookies are used to collect website statistics and track conversion rates.

NID - Registers a unique ID that identifies a returning user's device. The ID is used for serving ads that are most relevant to the user.

DV - Google ad personalisation

IDE, test_cookie, 1P_JAR, NID, DV, NID
IDE, test_cookie


These are essential site cookies, used by the google reCAPTCHA. These cookies use an unique identifier to verify if a visitor is human or a bot.