What is SELinux?
SELinux , Secure Enhanced Linux , is the module which enhances Linux Kernel security. SELinux watches and controls the Processes to access the Linux Kernel resources.
In principle, SELinux controlls processes to access the all resource managed by OS, but as an implementation, control related to access to the filesystem and use of the TCP/UDP port is centrally set.
In many cases, when receiving a system call from an application, it hooks at the Linux Security Module (LSM) , the kernel function , to check with permission. Since the amount of system calls and the number of allow rules are large, checking is carried out by judging with the cache named AVC to reduce the load.
Some applications that are made conscious of SELinux (SELinux-Aware applications) , can access control using the SELinux library instead of system call. (for example, SE-postgreSQL. There is few app.)
The architectural overview of SELinux is shown below.
SELinux gives a label named "context" to all process and resource managed by OS. Process's context is called "Source Context(scontext)" , and resource accessed by process such as file/dir is called "Target Context".
On the other hand, SELinux's access control rule is called "Access Vector Rules(AV rules)" and it is defined which operation from scontext to tcontext is permitted. If Process's operation is not allowed by AV rules, the operation is denied.
Context format is below.
[ User : Role : Type/Domain : Sensitivity range ]
Third attribute is called "Domain" when labeled to process, and called "Type" when labeled to resource like file/dir, or network. Although they are called differently, basically treated the same.
Scope covered in this article
In this article, I will explain assuming "SELINUX=enforcing, SELINUXTYPE=targeted" which is the default setting of SELinux.
In this mode, Access Vector Rules(AV rules: ACL) deals only Type/Domain, which is the third attriburte of context, and ignore other attribute, User, Role, and Sensitivity range.
FAQ
Q. Is SELinux effective even with default settings?
A. Yes, it has sufficient effect.
Access Vector Rules(ACL) is created based on general information such as "what kind of directory can httpd process access to concretely?" or "what type of TCP port should she use?"
So, if you do not make any special settings, it should work fine by default.
However, if you change the public directory by httpd from /var/www/html, or change the listen port from tcp:80/443, you need SELinux configuration corresponding to it.
Although less troubles less than before, permission rules (policy rules) as a bug fix still are added by the update.
Q. How many are there policy rules? Do I have to write policies?
A. More than 200,000. But you need not make basically.
There are two major policy rules.
One is Type Enforcement rules (TE rules) , including AV rules mentioned above and Type Transition rules described later , and has rules more than 200,000.
You can check the Type Enforcement rules with the following command.
If shown "command not found", you should install "setools-console" with yum.
If you want to display only AV rules, you type "sesearch --allow".
Another is Labeling rules which defines "Newly created file/dir under THIS directory is allocated THIS context". This rules have about 6,000 rules. For example, in case there is File Labeling Rule like the following,
all kind of file (including symlink, dir, block-device-file, and so on) under /tmp ot /tmp itself is labeled this context(fileB_u:fileB_r:fileB_t:s0). Even if it is not new, the context is restored according to this rule by doing the "restorecon -RFv" command.
Although File Labeling rules is not showned by sesearch command, you can check with following command.
semanage needs "yum -y install policycoreutils-python" command for install the package.
In the label rules, there are also Network Labeling Rules, which is combined TCP/UDP port to context. You can check this rules with following command.
Below is an image diagram of the Labeliing Rule (purple places).
Q. Where is SELinux's entity?
A. Configuration is under /etc/selinux and /var/lib/selinux , and file/dir context are in Extended Attributes of filesystems, binary at runtime is under /sys/fs/selinux
Configuration files of Policy rules is in /etc/selinux and /var/lib/selinux. The basic config file is /etc/selinux/config, and the reference policy, which is as main, is at /etc/selinux/targeted/policy/policy.##.
And, file/dir's context exists in "security.selinux" Extended Attribute which at i-node realm of filesystem. Extended Attribute is displayed with "getfattr" command, and is set with "setfattr".
[root@localhost ~] yum -y install attr [root@localhost ~] touch test1.txt [root@localhost ~] getfattr -m security.selinux -d test1.txt # file: test1.txt security.selinux="unconfined_u:object_r:admin_home_t:s0" [root@localhost ~] setfattr -n security.selinux -v system_u:object_r:httpd_sys_content_t:s0 test1.txt [root@localhost ~] getfattr -m security.selinux -d test1.txt # file: test1.txt security.selinux="system_u:object_r:httpd_sys_content_t:s0"
However, normally it is not used "getfattr" or "setfattr", but used "ls -Z" and "chcon".
[root@localhost ~]# ls -Z test1.txt -rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 test1.txt [root@localhost ~]# chcon -t httpd_sys_rw_content_t test1.txt [root@localhost ~]# ls -Z test1.txt -rw-r--r--. root root system_u:object_r:httpd_sys_rw_content_t:s0 test1.txt
And, if you want to reset as Labeling rule, you can use "restorecon -RFv" command. (R: recursively execute, F: force, v: verbose)
[root@localhost ~]# restorecon -RFv test1.txt restorecon reset /root/test1.txt context system_u:object_r:httpd_sys_rw_content_t:s0->system_u:object_r:admin_home_t:s0
Q. How many kinds of permissions are there?
A. A lot
You can list all permissions with "seinfo" commad.
[root@localhost ~] yum -y install setools-console [root@localhost ~] seinfo -c -x
For example, compared with operations for files and networks, the content to be allowed is completely different. There is an operation called reading in the file, but it is not on the network. In other words, the specific content of the operation to be permitted differs depending on the operation target.
The object to be operated is called Object Class, and the content of operation to be permitted is called Permission.
The number of object classes is around 100, and the number of permissions exceeds 1000. See below URL for the detail.
Q. What effect can we expect specifically in SELinux eventually?
A. We will look in detail in the next chapter and beyond.
example of httpd
An httpd process is usually started in the domain httpd_t. The context can be confirmed with ps command with "Z" option.
[root@localhost ~] yum -y install httpd [root@localhost ~] systemctl start httpd [root@localhost ~]# ps auxZ | grep httpd_t system_u:system_r:httpd_t:s0 root 1526 0.0 0.1 224024 5024 ? Ss 23:51 0:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 1527 0.0 0.0 224024 2956 ? S 23:51 0:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 1528 0.0 0.0 224024 2956 ? S 23:51 0:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 1529 0.0 0.0 224024 2956 ? S 23:51 0:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 1530 0.0 0.0 224024 2956 ? S 23:51 0:00 /usr/sbin/httpd -DFOREGROUND system_u:system_r:httpd_t:s0 apache 1531 0.0 0.0 224024 2956 ? S 23:51 0:00 /usr/sbin/httpd -DFOREGROUND
On the other hand, what rules are applied to "/var/www/html" which is the general location of web server contents?
[root@localhost ~]# semanage fcontext -l | grep /var/www/html /var/www/html(/.*)?/uploads(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/wp-content(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/wp_backups(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/sites/default/files(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html(/.*)?/sites/default/settings.php regular file system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/[^/]*/cgi-bin(/.*)? all files system_u:object_r:httpd_sys_script_exec_t:s0 /var/www/html/munin(/.*)? all files system_u:object_r:munin_content_t:s0 /var/www/html/cgi/munin.* all files system_u:object_r:munin_script_exec_t:s0 /var/www/html/munin/cgi(/.*)? all files system_u:object_r:munin_script_exec_t:s0 /var/www/html/owncloud/data(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/nextcloud/data(/.*)? all files system_u:object_r:httpd_sys_rw_content_t:s0 /var/www/html/configuration.php all files system_u:object_r:httpd_sys_rw_content_t:s0
A rule matching the directory under "/var/www/html" is displayed. Looking at the rule on the directory above,
[root@localhost ~]# semanage fcontext -l | grep /var/www | more /var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0 ~~~omit~~~
it is displayed like this. That is, the content under "/var/www" is labeled "httpd_sys_content_t".
(/.*)? is a regular expression, meaning here refers to all files/dirs under /var/www and /var/www itself.
Then, what kind of operation is permitted from domain "httpd_t" to type "httpd_sys_content_t"?
[root@localhost ~]# sesearch --allow | grep "allow httpd_t httpd_sys_content_t " allow httpd_t httpd_sys_content_t : dir { ioctl read getattr lock search open } ; allow httpd_t httpd_sys_content_t : lnk_file { read getattr } ; allow httpd_t httpd_sys_content_t : file { ioctl read getattr lock open } ; allow httpd_t httpd_sys_content_t : dir { ioctl read write getattr lock add_name remove_name search open } ;
Four permission rules (AV rules) are displayed. The first rule is included in the fourth rule. Since permission rules are installed from various modules, duplication often occurs frequently. (So as the number of rules lines increases...)
"lnk_file" is a symbolic link file. "read" means generic file access permission, and "getattr" means access permission to attribute information. Since symbolic link has link destination information in meta (attribute) information, getattr is necessary.
"file" is a general file. "read" and "getattr" are the same as lnk_file. "ioctl" means permission to access functions provided by the IO driver (Disk IO driver in this case). "lock" is exclusive, "open" is to make file I/O (read / write) possible by linking file descriptor.
"dir" is the directory. In addition to file permission, write meaning generic writing to the directory, "add_name" to create files under the directory, "remove_name" to delete files are allowed.
These are operations to files under "/var/www/html" which are given to httpd (However, if it falls under this directory and hits with another File Labeling Rule, another context will be assigned, so operation permission The contents are different.)
Type Transition Rules for determining process domain
By the way, how is it determined that the domain of httpd is "httpd_t"?
Actually, the element that decides process domain is the Type Transition Rules. The execution file of httpd is /usr/sbin/httpd, but the type of this file is httpd_exec_t.
[root@localhost ~]# ls -Z /usr/sbin/httpd
-rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd
On the other hand, Type Transition Rules have the following rules.
[root@localhost ~]# sesearch --type | grep httpd_exec_t
~~~
type_transition init_t httpd_exec_t : process httpd_t;
~~~
This means that if a process in the domain called init_t invokes an executable file of type httpd_exec_t, that process will transition to the domain of httpd_t. Because the domain of "systemd" process is "init_t", it matches this rule at startup and when starting httpd service with the systemctl command (since it is activated by operation with systemd).
[root@localhost ~]# ps auxZ | more LABEL USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND system_u:system_r:init_t:s0 root 1 0.0 0.1 193512 6612 ? Ss 11:30 0:04 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
In the case that does not correspond to this type_transition rule, httpd inherit the domain of the process that started up. For example, the type when the root user is in bash with login or su - is "unconfined_t". This means "no restriction", and as SELinux, it is a type that can operate quite freely. It is determined in advance by the login definition rule, but it is also possible to change the setting so as to lower the authority.
[root@localhost ~]# ps -Z LABEL PID TTY TIME CMD unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 4152 pts/0 00:00:00 bash
If you run httpd directly (not systemctl) in this state, the context of httpd will also be unconfined_t.
[root@localhost ~]# ps auxZ | grep httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 4315 0.0 0.0 224020 3488 ? Ss 22:27 0:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 apache 4316 0.0 0.0 224020 2956 ? S 22:27 0:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 apache 4317 0.0 0.0 224020 2956 ? S 22:27 0:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 apache 4318 0.0 0.0 224020 2956 ? S 22:27 0:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 apache 4319 0.0 0.0 224020 2956 ? S 22:27 0:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 apache 4320 0.0 0.0 224020 2956 ? S 22:27 0:00 /usr/sbin/httpd
In here, we can see what SELinux aimed for. That is, an httpd process started with a domain "httpd_t" once, he can not get out of this domain whatever the process is hijacked, promoted to root authority, or a shell is started, and fork the child process (unless matching type_transition rule), so what he can do is limited within the AV rules given to httpd_t, regardless of root. (Caution: If you take over the process of unconfined_t, the SELinux will be useless, so you should never start httpd directly from the login user's shell.)
The answer of the FAQ "I heared it's OK even if a process is hijacked and promoted to root in enabling SELinux, but will not SELinux be invalidated if the process is taken over?" was indicated as above.
Vision of SELinux -DAC and MAC -
As I have already laid the grounds for the answer, SELinux does not aim to prevent the attack itself. The purpse is to place the process under Mandatory Access Control (MAC) and limit the behavior even if the process is compromised or root privilege is taken.
The MAC by SELinux is different from the DAC (Discretely Access Control) of the filesystem up to now.
Since the DAC of the filesystem can be changed by each user, so it is called like this, but there is another reflection that the authorization to root is made too much otherwise.
That is, if you become root, you can become God who freely manipulates the system and decide the law, but due to the vulnerability of the program cracking acts promoting from remote to root have been done many times.
Access control by SELinux can not be changed simply by being root. In order to become God of the system, it needs to be a root authority and domain "unconfined_t".
So as a point, if an attacker is password cracked and logged in by ssh, you can not restrict attacks. What is effective is a story when a process that is running with httpd etc. is hijacked by buffer overflow etc. to the last.
Restrict login user's operation with SELinux
As mentioned above, there is a risk that if you start up from the shell by default, it will run in an unlimited domain called "unconfined_t". This is true even for general users.
To restrict this, you need to change the login domain from unconfined_t. In order to realize this, it is necessary to link "local account user" to "SELinux user (the first attribute of the context)".
The default SELinuix user (__default__) at Linux login is "unconfind_u" user.
[root@localhost ~]# semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
The default value is __default__, and all users are associated with "unconfind_u", and the role of this SELinux user is linked to "unconfined_r".
[root@localhost ~]# semanage user -l Labeling MLS/ MLS/ SELinux User Prefix MCS Level MCS Range SELinux Role guest_u user s0 s0 guest_r root user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r staff_u user s0 s0-s0:c0.c1023 staff_r sysadm_r system_r unconfined_r sysadm_u user s0 s0-s0:c0.c1023 sysadm_r system_u user s0 s0-s0:c0.c1023 system_r unconfined_r unconfined_u user s0 s0-s0:c0.c1023 system_r unconfined_r user_u user s0 s0 user_r xguest_u user s0 s0 xguest_r
And the domain at login will be partially changed role "_r" to "_t".
Let's actually link "testuser" to a user who is not "unconfined_u".
[root@localhost ~]# semanage login -a -s staff_u testuser
[root@localhost ~]# semanage login -l
Login Name SELinux User MLS/MCS Range Service
__default__ unconfined_u s0-s0:c0.c1023 *
root unconfined_u s0-s0:c0.c1023 *
system_u system_u s0-s0:c0.c1023 *
testuser staff_u s0-s0:c0.c1023 *
In this state, "su - testuser" does not change the domain because it is a shell which is originally working with "unconfined_t".
[root@localhost ~]# su - testuser
Last login: Sun Jul 1 21:58:14 JST 2018 on pts/0
[testuser@localhost ~]$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Therefore, connect with a new SSH session and log in with testuser. Surely, the domain has changed to staff_t.
[testuser@localhost ~]$ id -Z
staff_u:staff_r:staff_t:s0-s0:c0.c1023
コメント