Linux security systems

One of the reasons for the tremendous success of Linux OS on embedded, mobile devices and servers is the relatively high degree of security of the kernel, related services and applications. But if take a closer look to the architecture of the Linux kernel, then it is impossible to find a square in it responsible for security, as such. Where is the Linux security subsystem hiding and what does it consist of?

Background of Linux Security Modules and SELinux

Security Enhanced Linux is a set of rules and an access mechanism based on the mandatory and role-based access models to protect Linux systems from potential threats and fix the weaknesses of Discretionary Access Control (DAC), the traditional Unix security system. The project originated in the bowels of the US National Security Agency, and the contractors Secure Computing Corporation and MITER, as well as a number of research laboratories, were directly involved in the development.

Linux security systems
Linux Security Modules

Linus Torvalds contributed a number of notes on new NSA developments so that they could be included in the main branch of the Linux kernel. He described a common environment, with a set of interceptors for managing operations on objects and a set of some protective fields in the kernel data structures for storing the corresponding attributes. This environment can then be used by loadable kernel modules to implement any desired security model. LSM fully entered the Linux kernel v2.6 in 2003.

The LSM framework includes guard fields in data structures and interception function calls at critical points in the kernel code to manage them and perform access control. It also adds functionality for registering security modules. The /sys/kernel/security/lsm interface contains a list of active modules in the system. LSM hooks are stored in lists that are called in the order specified in CONFIG_LSM. Detailed hook documentation is included in the include/linux/lsm_hooks.h header file.

The LSM subsystem made it possible to complete the full integration of SELinux of the same version of the stable Linux kernel v2.6. Literally immediately, SELinux became the de facto standard for a secure Linux environment and became part of the most popular distributions: RedHat Enterprise Linux, Fedora, Debian, Ubuntu.

Glossary

  • Identity - The SELinux user is not the same as the usual Unix / Linux user id, they can coexist on the same system, but they are completely different in essence. Each standard Linux account can correspond to one or more in SELinux. The SELinux identity is part of the overall security context that determines which domains you can and cannot join.
  • Domains - In SELinux, the domain is the execution context of the subject, i.e. the process. The domain directly defines the access that a process has. A domain is basically a list of what processes can do or what actions a process can do with different types. Some examples of domains are sysadm_t for system administration, and user_t which is a regular unprivileged user domain. The init system runs in the init_t domain, and the named process runs in the named_t domain.
  • Roles - Something that serves as an intermediary between domains and SELinux users. Roles define what domains a user can belong to and what types of objects the user can access. Such an access control mechanism prevents the threat of a privilege escalation attack. Roles are written into the Role Based Access Control (RBAC) security model used in SELinux.
  • Types β€” Type Enforcement list attribute that is assigned to an object and determines who will have access to it. Similar to defining a domain, except that the domain applies to the process, while the type applies to objects such as directories, files, sockets, and so on.
  • Subjects and objects - Processes are subjects and run in a particular context, or security domain. Operating system resources: files, directories, sockets, etc., are objects that are assigned a certain type, in other words, a level of secrecy.
  • SELinux Policies - SELinux uses a variety of policies to protect the system. SELinux policy defines user access to roles, roles to domains, and domains to types. First, the user is authorized to obtain a role, then the role is authorized to access domains. Finally, a domain may only have access to certain types of objects.

LSM and SELinux architecture

Despite the name, LSMs are not generally loadable Linux modules. However, just like SELinux, it is directly integrated into the kernel. Any change to the LSM source code requires a new kernel compilation. The corresponding option must be enabled in the kernel settings, otherwise the LSM code will not be activated after boot. But even in this case, it can be enabled by the OS bootloader option.

Linux security systems
Stack of LSM checks

LSM is equipped with hooks in core kernel functions that may be relevant for checks. One of the main features of LSM is that they are stack based. Thus, the standard checks are still performed, and each LSM layer only adds additional controls and controls. This means that the ban cannot be rolled back. This is shown in the figure, if the result of routine DAC checks is a failure, then it will not even reach the LSM hooks.

SELinux adopted the Flask security architecture of the Fluke research operating system, specifically the principle of least privilege. The essence of this concept, as their name suggests, is to grant the user or process only those rights that are necessary for the implementation of the intended actions. This principle is implemented using forced access typing, so SELinux's access control is based on the domain => type model.

Through enforced access typing, SELinux has much greater access control capabilities than the traditional DAC model used in Unix/Linux operating systems. For example, you can limit the network port number that will happen to the ftp server, allow writing and changing files in a certain folder, but not deleting them.

The main components of SELinux are:

  • Policy Enforcement Server - The main mechanism for organizing access control.
  • Database of system security policies.
  • Interaction with the LSM event listener.
  • Selinuxfs - Pseudo-FS, same as /proc and mounted in /sys/fs/selinux. Populated dynamically by the Linux kernel at runtime and contains files containing SELinux status information.
  • Access Vector Cache - Auxiliary mechanism to improve performance.

Linux security systems
How SELinux Works

All this works as follows.

  1. A subject, in SELinux terms, performs a permitted action on an object after a DAC check, as shown in the top picture. This operation request goes to the LSM event listener.
  2. From there, the request, along with the security context of the subject and object, is passed to the SELinux Abstraction and Hook Logic module responsible for interacting with the LSM.
  3. The Policy Enforcement Server is the decision-making authority on the subject's access to the object, and it receives data from SELinux AnHL.
  4. To make a decision on access, or prohibition, the Policy Enforcement Server refers to the caching subsystem of the most used Access Vector Cache (AVC) rules.
  5. If the solution for the corresponding rule is not found in the cache, then the request is passed on to the security policy database.
  6. The search result from the database and AVC is returned to the Policy Enforcement Server.
  7. If the found policy is consistent with the requested action, then the operation is allowed. Otherwise, the operation is prohibited.

Managing SELinux Settings

SELinux operates in one of three modes:

  • Enforcing - Strict enforcement of security policies.
  • Permissive - A violation of restrictions is allowed, the corresponding mark is made in the log.
  • Disabled - Security policies are not in effect.

You can see what mode SELinux is in with the following command.

[admin@server ~]$ getenforce
Permissive

Changing the mode before reboot, for example, set it to enforcing, or 1. The permissive parameter corresponds to the numeric code 0.

[admin@server ~]$ setenfoce enforcing
[admin@server ~]$ setenfoce 1 #Ρ‚ΠΎ ΠΆΠ΅ самоС

You can also change the mode by editing the file:

[admin@server ~]$ cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.

SELINUXTYPE=target

The difference with setenfoce is that when the operating system boots, the SELinux mode will be set in accordance with the value of the SELINUX parameter in the configuration file. In addition, enforcing <=> disabled changes take effect only through editing the /etc/selinux/config file and after a reboot.

View summary status report:

[admin@server ~]$ sestatus

SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 31

To view SELinux attributes, some stock utilities use the -Z option.

[admin@server ~]$ ls -lZ /var/log/httpd/
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20200920
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20200927
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20201004
-rw-r--r--. root root system_u:object_r:httpd_log_t:s0 access_log-20201011
[admin@server ~]$ ps -u apache -Z
LABEL                             PID TTY          TIME CMD
system_u:system_r:httpd_t:s0     2914 ?        00:00:04 httpd
system_u:system_r:httpd_t:s0     2915 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     2916 ?        00:00:00 httpd
system_u:system_r:httpd_t:s0     2917 ?        00:00:00 httpd
...
system_u:system_r:httpd_t:s0     2918 ?        00:00:00 httpd

Compared to the normal ls -l output, there are several additional fields in the following format:

<user>:<role>:<type>:<level>

The last field denotes something like a security stamp and consists of a combination of two elements:

  • s0 - significance, also recorded as lowlevel-highlevel interval
  • c0, c1… c1023 is the category.

Changing the access configuration

Use semodule to load SELinux modules, add and remove them.

[admin@server ~]$ semodule -l |wc -l #список всСх ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ
408
[admin@server ~]$ semodule -e abrt #enable - Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ
[admin@server ~]$ semodule -d accountsd #disable - ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ
[admin@server ~]$ semodule -r avahi #remove - ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ

First team semanage login associates an SELinux user with an operating system user, the second lists it. Finally, the last command with the -r switch removes the mapping of SELinux users to OS accounts. An explanation of the syntax for MLS/MCS Range values ​​is found in the previous section.

[admin@server ~]$ semanage login -a -s user_u karol
[admin@server ~]$ 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 *
[admin@server ~]$ semanage login -d karol

Team semanage user used to manage mappings between SELinux users and roles.

[admin@server ~]$ semanage user -l
                Labeling   MLS/       MLS/                          
SELinux User    Prefix     MCS Level  MCS Range             SELinux Roles
guest_u         user       s0         s0                    guest_r
staff_u         staff      s0         s0-s0:c0.c1023        staff_r sysadm_r
...
user_u          user       s0         s0                    user_r
xguest_u        user       s0         s0                    xguest_r
[admin@server ~]$ semanage user -a -R 'staff_r user_r'
[admin@server ~]$ semanage user -d test_u

Command options:

  • -a add a custom role mapping entry;
  • -l list of matching users and roles;
  • -d remove custom role mapping entry;
  • -R list of roles attached to the user;

Files, ports and booleans

Each SELinux module provides a set of file marking rules, but you can also add your own rules if needed. For example, we want the web server to have access rights to the /srv/www folder.

[admin@server ~]$ semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?
[admin@server ~]$ restorecon -R /srv/www/

The first command registers new marking rules, and the second resets, or rather exposes, file types in accordance with the current rules.

Likewise, TCP/UDP ports are marked in such a way that only the appropriate services can listen on them. For example, in order for a web server to listen on port 8080, you need to run a command.

[admin@server ~]$ semanage port -m -t http_port_t -p tcp 8080

A significant number of SELinux modules have parameters that can take boolean values. The entire list of such options can be seen with getsebool -a. Boolean values ​​can be changed using setsebool.

[admin@server ~]$ getsebool httpd_enable_cgi
httpd_enable_cgi --> on
[admin@server ~]$ setsebool -P httpd_enable_cgi off
[admin@server ~]$ getsebool httpd_enable_cgi
httpd_enable_homedirs --> off

Practicum, access the Pgadmin-web interface

Consider an example from practice, we installed pgadmin7.6-web on RHEL 4 to administer the PostgreSQL database. We passed a small quest with setting up pg_hba.conf, postgresql.conf and config_local.py, set permissions on folders, installed missing Python modules from pip. Everything is ready, run and get 500 Internal Server error.

Linux security systems

We start with typical suspects, check /var/log/httpd/error_log. There are some interesting entries there.

[timestamp] [core:notice] [pid 23689] SELinux policy enabled; httpd running as context system_u:system_r:httpd_t:s0
...
[timestamp] [wsgi:error] [pid 23690] [Errno 13] Permission denied: '/var/lib/pgadmin'
[timestamp] [wsgi:error] [pid 23690] [timestamp] [wsgi:error] [pid 23690] HINT : You may need to manually set the permissions on
[timestamp] [wsgi:error] [pid 23690] /var/lib/pgadmin to allow apache to write to it.

At this point, most Linux administrators will be strongly tempted to run setencorce 0, and be done with it. To be honest, this is the first time I did it. This, of course, is also a way out, but far from the best.

Despite the cumbersome designs, SELinux can be user friendly. Just install the setroubleshoot package and view the system log.

[admin@server ~]$ yum install setroubleshoot
[admin@server ~]$ journalctl -b -0
[admin@server ~]$ service restart auditd

Please note that the auditd service must be restarted in this way, and not with systemctl, despite the presence of systemd in the OS. In the system log will be indicated not only the fact of blocking, but also the reason and way to overcome the ban.

Linux security systems

We execute these commands:

[admin@server ~]$ setsebool -P httpd_can_network_connect 1
[admin@server ~]$ setsebool -P httpd_can_network_connect_db 1

We check access to the pgadmin4-web web page, everything works.

Linux security systems

Linux security systems

Source: habr.com

Add a comment