💣 Как управлять и устранять неполадки SELinux |

💣 Как управлять и устранять неполадки SELinux

Медиа

В этой статье мы попробуем рассмотреть, как включение системы безопасности SELinux в Linux обеспечивает дополнительный уровень безопасности, а также попытаемся устранить некоторые проблемы, с которыми мы можем столкнуться, если SELinux включен.

Что такое DAC

В Linux все называется файлом.

В linux существуют различные типы файлов.

Это обычные файлы, файлы директорий, специальные файлы, блочные или символьные файлы, файлы сокетов и т.д.

Дискреционный контроль доступа, также известный как DAC, – это модель безопасности, которую реализует большинство операционных систем.

В этой модели пользователи контролируют права доступа к файлам, которые им принадлежат.

Утечка конфиденциальной информации может произойти в тех случаях, если владельцы файлов не реализуют адекватные ограничения с помощью разрешений.

В ней не реализована централизованная политика безопасности, управляемая администратором безопасности, которая может быть наложена на систему.

Она не обеспечивает защиту от вредоносных программ, если они скомпрометированы.

Что такое MAC

Безопасность MAC позволяет системе адекватно защищать себя и обеспечивает критическую поддержку безопасности приложений, защищая от несанкционированного вмешательства и обхода защищенных приложений.

Она также обеспечивает надежную изоляцию приложений и позволяет безопасно выполнять недоверенные приложения.

Решения по управлению доступом MAC основываются на информации, относящейся к безопасности, которая прикрепляется к файлам и процессам в виде меток.

Что такое SELinux

Security Enhanced Linux, также известный как SELinux, – это дополнительный уровень безопасности, реализующий модель Mandatory Access Control (MAC).

В ней файлы, такие как каталоги и устройства, называются объектами, а процессы, такие как команды, инициированные пользователем, или приложения – субъектами.

Обязательный контроль доступа применяет административно заданную политику безопасности ко всем процессам и файлам в системе, основывая решения по контролю доступа на метках, содержащих различную информацию, относящуюся к безопасности.

Правила политики SELinux, реализующие модель MAC, не используются, если правила DAC сначала запрещают доступ.

Система с отключенным SELinux

Убедитесь, что SELinux отключен

Утилита SELinux “sestatus” предоставляет нам статус SELinux, если он включен или отключен в операционной системе linux, как показано ниже.

/usr/sbin/sestatus
SELinux status:                 disabled

Установка и запуск Nginx

В конфигурации по умолчанию nginx прослушивает порт 80, который является привилегированным портом. Для запуска любой службы на привилегированном порту нам необходимо запустить службу под пользователем с правами root.

sudo dnf install nginx
sudo systemctl start nginx.service
ps -efZ | grep nginx
kernel                          root        2078       1  0 03:35 ?        00:00:00 nginx: master process /usr/sbin/nginx
kernel                          nginx       2079    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2080    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2081    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2083    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2084    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2085    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2086    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          nginx       2087    2078  0 03:35 ?        00:00:00 nginx: worker process
kernel                          admin       2309    1067  0 04:20 pts/0    00:00:00 grep --color=auto nginx

Давайте также остановим службу брандмауэра, чтобы увидеть эффект безопасности SELinux.

sudo systemctl stop firewalld.service

Обновление порта по умолчанию и перезапуск службы

Теперь давайте обновим наш сервис, чтобы он запускался не на стандартном порту “2222”, обновив файл nginx.conf, как показано ниже.

grep listen /etc/nginx/nginx.conf
listen       2222;
listen       [::]:2222;

Давайте перезапустим службу и посмотрим, нет ли проблем с ее запуском.

sudo systemctl restart nginx.service

При отключенном SELinux нет ограничений на порт, на котором должна прослушиваться служба.

Пока пользователь, инициирующий службу, имеет доступ к конфигурационному файлу, он может обновить конфигурацию в соответствии со своими потребностями и перезапустить службу.

Обновим корневик перезапустим службу

Создайте новый корневик для хранения html-контента для службы nginx.

mkdir -p /opt/nginx_data
echo "Testing nginx instance" >> /opt/nginx_data/fedunr.html
chown -R admin:admin /opt/nginx_data/
chmod -R 005 /opt/nginx_data/

Обновим nginx.conf, чтобы он указывал на новый путь, как показано ниже.

grep "root" /etc/nginx/nginx.conf
root         /opt/nginx_data;
sudo systemctl restart nginx.service

Сервисы Nginx перезапускаются без каких-либо проблем, и вы должны иметь доступ к html-содержимому, как показано ниже.

Независимо от права собственности на корневик  служба nginx сможет получить доступ к html-содержимому, не являющегося корневым каталогом по умолчанию, если будут установлены необходимые права доступа к файлам.

Контроль доступа работает исключительно на уровне прав, которые предоставляются этим файлам и процессам для любого пользователя, группы пользователей или других пользователей.

Система с поддержкой SELinux

Убедитесь, что SELinux включен

Утилита SELinux “sestatus” предоставляет нам статус SELinux, если он включен или отключен в операционной системе linux, как показано ниже.

/usr/sbin/sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      33

Установка и запуск Nginx

В конфигурации по умолчанию nginx прослушивает порт 80, который является привилегированным портом.

Для запуска любой службы на привилегированном порту нам необходимо запустить службу под пользователем с правами root.

sudo dnf install nginx
sudo systemctl start nginx.service
ps -efZ | grep nginx
system_u:system_r:httpd_t:s0    root        1298       1  0 20:19 ?        00:00:00 nginx: master process /usr/sbin/nginx
system_u:system_r:httpd_t:s0    nginx       1299    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1300    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1301    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1302    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1303    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1304    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1305    1298  0 20:19 ?        00:00:00 nginx: worker process
system_u:system_r:httpd_t:s0    nginx       1306    1298  0 20:19 ?        00:00:00 nginx: worker process

Давайте также остановим службу брандмауэра, чтобы увидеть эффект безопасности SELinux.

sudo systemctl stop firewalld.service

Обновление порта по умолчанию и перезапуск службы

Теперь давайте обновим наш сервис, чтобы он запускался не на стандартном порту “2222”, обновив nginx.conf, как показано ниже.

Также перезапустите службу и посмотрите, нет ли проблем с запуском службы.

grep 2222 /etc/nginx/nginx.conf
listen       2222;
listen       [::]:2222;
sudo systemctl restart nginx.service
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xeu nginx.service" for details.

Теперь давайте посмотрим на журналы службы nginx с помощью journalctl, как показано ниже.

journalctl -fxeu nginx
Jan 22 20:23:58 fedres.stack.com nginx[1408]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Jan 22 20:23:58 fedres.stack.com nginx[1408]: nginx: [emerg] bind() to 0.0.0.0:2222 failed (13: Permission denied)
Jan 22 20:23:58 fedres.stack.com nginx[1408]: nginx: configuration file /etc/nginx/nginx.conf test failed
Jan 22 20:23:58 fedres.stack.com systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ An ExecStartPre= process belonging to unit nginx.service has exited.
░░
░░ The process' exit code is 'exited' and its exit status is 1.
Jan 22 20:23:58 fedres.stack.com systemd[1]: nginx.service: Failed with result 'exit-code'.

Эта ошибка с отказом в разрешении в основном связана с ограничениями политики selinux, которые накладываются на ограниченный процесс с помощью целевой политики.

Для дальнейшего устранения этой ошибки нам необходимо просмотреть журналы аудита, как показано ниже.

tail -f /var/log/audit/audit.log | grep nginx
type=AVC msg=audit(1705935470.588:247): avc:  denied  { name_bind } for  pid=1521 comm="nginx" src=2222 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0

Проанализируем проблему с selinux

Убедимся, что в вашей системе установлены пакеты policycoreutils-python-utils и setroubleshoot-server.

sealert -l "*"
SELinux is preventing nginx from name_bind access on the tcp_socket port 2222.
*****  Plugin bind_ports (92.2 confidence) suggests   ************************
If you want to allow nginx to bind to network port 2222
Then you need to modify the port type.
Do
semanage port -a -t PORT_TYPE -p tcp 2222
where PORT_TYPE is one of the following: http_cache_port_t, http_port_t, jboss_management_port_t, jboss_messaging_port_t, ntop_port_t, puppet_port_t.
*****  Plugin catchall_boolean (7.83 confidence) suggests   ******************
If you want to allow nis to enabled
Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.
Do
setsebool -P nis_enabled 1
*****  Plugin catchall (1.41 confidence) suggests   **************************
If you believe that nginx should be allowed name_bind access on the port 2222 tcp_socket by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
ausearch -c 'nginx' --raw | audit2allow -M my-nginx
semodule -X 300 -i my-nginx.pp
Additional Information:
Source Context                system_u:system_r:httpd_t:s0
Target Context                system_u:object_r:unreserved_port_t:s0
Target Objects                port 2222 [ tcp_socket ]
Source                        nginx
Source Path                   nginx
Port                          2222
Host                          fedres.stack.com
Source RPM Packages
Target RPM Packages
SELinux Policy RPM            selinux-policy-targeted-39.3-1.fc39.noarch
Local Policy RPM              selinux-policy-targeted-39.3-1.fc39.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     fedres.stack.com
Platform                      Linux fedres.stack.com 6.6.8-200.fc39.x86_64 #1
SMP PREEMPT_DYNAMIC Thu Dec 21 04:01:49 UTC 2023
x86_64
Alert Count                   2
First Seen                    2024-01-22 20:23:58 IST
Last Seen                     2024-01-22 20:27:50 IST
Local ID                      5f40212e-a76a-477c-8710-15c935ee8183
Raw Audit Messages
type=AVC msg=audit(1705935470.588:247): avc:  denied  { name_bind } for  pid=1521 comm="nginx" src=2222 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0
Hash: nginx,httpd_t,unreserved_port_t,tcp_socket,name_bind

По умолчанию политика selinux разрешает http-сервису, т. е. nginx, связываться только с указанными ниже портами.

sudo semanage port --list | grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

Нам нужно изменить тип порта, как показано ниже, чтобы разрешить http связываться с портом 2222.

sudo semanage port -a -t http_port_t -p tcp 2222
sudo semanage port --list | grep http_port_t
http_port_t                    tcp      2222, 80, 81, 443, 488, 8008, 8009, 8443, 9000
sudo systemctl restart nginx.service
URL - http://fedres.stack.com:2222/

Перемаркировка содержимого

semanage fcontext -a -t public_content_t '/opt/nginx_data/fedunr.html'
restorecon -v '/opt/nginx_data/fedunr.html'
Relabeled /opt/nginx_data/fedunr.html from unconfined_u:object_r:usr_t:s0 to unconfined_u:object_r:public_content_t:s0

Теперь, если мы попытаемся получить доступ к html-контексту, он должен быть разрешен.

curl http://fedres.stack.com:2222/fedunr.html
Testing nginx instance

см. также:

 

Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий