Лабораторная работа "Изучение SELinux" - efanov/mephi GitHub Wiki

Цель

Изучить систему мандатного управления доступом SELinux (Security Enhanced Linux).

Задачи

  • Изучить назначение, состав и возможности политики безопасности SELinux.
  • Изучить средства администрирования SELinux.
  • Изучить связь SELinux с системой аудита.
  • Изучить технику изменения контекстов файлов на примере работы web-сервера Apache.

Обзор

Расположение файлов:

  • Конфигурационные файлы: /etc/selinux/config, /etc/selinux/targeted/setrans.conf.
  • Политика безопасности: /etc/selinux/targeted/policy/policy.29.
  • Расположение модулей: /etc/selinux/targeted/modules/.

Команды, изучаемые в работе: setenforce, getenforce, getsebool, seinfo, semanage fcontext, restorecon, sesearch, sestatus.

Вспомогательные команды: readelf, ldd, getfattr, ausearch, curl.

Задание

Определение SELinux-aware программ

Все программы можно условно поделить на те, которые используют SELinux (т.н. SELinux-aware), и те, которые даже не подозревают, что выполняются в системе с работающим SELinux.

Чтобы понять, использует ли данная программа систему SELinux, или нет, нужно определить, была ли программа динамически слинкована с библиотекой libselinux. Это можно сделать двумя способами:

$ readelf -d /bin/ls | grep selinux
 0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
$ ldd /bin/ls | grep selinux
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f67344c5000)

Расположение в файловой системе

  1. Изучите содержимое каталогов, в которых хранятся библиотеки и модули:

     $ ls -l /etc/selinux/
     $ ls -l /etc/selinux/targeted/
    

Контексты безопасности

  1. Изучите контекст безопасности пользователя:

     $ id -Z
     unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    
  2. Изучите контексты безопасности некоторых важных программ и конфигурационных файлов:

     $ ls -Z /etc/passwd /etc/group /etc/shadow
     system_u:object_r:passwd_file_t:s0 /etc/group
     system_u:object_r:passwd_file_t:s0 /etc/passwd
          system_u:object_r:shadow_t:s0 /etc/shadow
     $ ls -Z /etc/login.defs /etc/sudoers
     system_u:object_r:etc_t:s0 /etc/login.defs
     system_u:object_r:etc_t:s0 /etc/sudoers
     $ ls -Z /usr/bin/passwd 
     system_u:object_r:passwd_exec_t:s0 /usr/bin/passwd
     $ ls -Z /usr/sbin/useradd 
     system_u:object_r:useradd_exec_t:s0 /usr/sbin/useradd
    

Обратите внимание на то, что файлам /etc/passwd и /etc/shadow присвоены разные типы!

  1. Контексты безопасности файлов хранятся в расширенных атрибутах (extended attributes) (структура struct ext4_xattr_entry) файловой системы ext4 в пространстве security.selinux:

     $ getfattr -n security.selinux /etc/passwd
     getfattr: Removing leading '/' from absolute path names
     # file: etc/passwd
     security.selinux="system_u:object_r:passwd_file_t:s0"
    
  2. Изучите контексты безопасности некоторых системных процессов:

     $ ps Zaux
     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 194328  5300 ?        Ss   апр19   0:06 /usr/lib/systemd/systemd --switched-root --sys
     ...
     system_u:system_r:auditd_t:s0   root      4566  0.0  0.0  55520   536 ?        S<sl апр19   0:00 /sbin/auditd
     ...
     system_u:system_r:systemd_logind_t:s0 root 4640 0.0  0.0  26452  1700 ?        Ss   апр19   0:01 /usr/lib/systemd/systemd-logind
     ...
    
  3. Изучите информацию, которую предоставляет файловая система /proc:

     $ ls /proc/$$/attr
    
  4. Изучите контекст безопасности процесса, в котором выполняется программа смены пароля пользователя. Для этого в одном терминале запустите программу passwd, а в другом выполните:

     $ ps Z $(pgrep passwd)
     LABEL                               PID TTY      STAT   TIME COMMAND
     unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 76307 pts/2 S+   0:00 passwd
    
  5. Изучите контексты безопасности некоторых сетевых портов:

     # netstat -tnlpZ
     Active Internet connections (only servers)
     Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name     Security Context                                 
     tcp6       0      0 :::80                   :::*                    LISTEN      717/httpd            system_u:system_r:httpd_t:s0
    

Состояние SELinux

Информацию о состоянии SELinux можно получить различными способами.

Утилита sestatus выводит информацию о состоянии SELinux и текущей политике безопасности.

  1. Выведите информацию о состоянии системы с помощью команд getenforce и sestatus.

     $ 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
     Max kernel policy version:      28
     $ getenforce
     Enforcing
     $ cat /sys/fs/selinux/enforce
     1
    
  2. Изучите два режима работы SELinux: permissive и enforcing. Для этого изменяйте конфигурационный файл /etc/selinux/config, перезагружайте систему и наблюдайте изменения.

  3. Изучите способы изменения режима работы SELinux: setenforce 1, echo 1 > /sys/fs/selinux/enforce.

  4. Изучите параметры сборки ядра (CONFIG_SECURITY_SELINUX_DEVELOP, CONFIG_SECURITY_SELINUX_BOOTPARAM).

Переключатели (booleans)

  1. Изучите переключатели web-сервера:

     $ getsebool -a | grep httpd
     ...
     httpd_enable_homedirs --> off
     httpd_read_user_content --> off
     ...
    

Политика безопасности и классы объектов

Утилита seinfo выводит информацию об элементах политики безопасности, о классах объектов и видах доступа.

  1. Выведите общую информацию о политике безопасности.

     # seinfo 
     
     Statistics for policy file: /sys/fs/selinux/policy
     Policy Version & Type: v.28 (binary, mls)
     
     Classes:            85    Permissions:       257
     Sensitivities:       1    Categories:       1024
     Types:            4634    Attributes:        364
     Users:               8    Roles:              15
     Booleans:          302    Cond. Expr.:       353
     Allow:           97434    Neverallow:          0
     Auditallow:        152    Dontaudit:        8522
     Type_trans:      18473    Type_change:        74
     Type_member:        47    Role allow:         31
     Role_trans:        416    Range_trans:      5669
     Constraints:       103    Validatetrans:       0
     Initial SIDs:       27    Fs_use:             28
     Genfscon:          101    Portcon:           579
     Netifcon:            0    Nodecon:             0
     Permissives:         1    Polcap:              2
    
  2. Изучите классы объектов файловой системы. Выведите информацию о классе file и поддерживаемых видах доступа.

Сколько видов доступа?

для старых версий

    # seinfo -cfile -x
    file
       append
    ...

для Fedora 31

# seinfo --class | grep file
   blk_file
   chr_file
   fifo_file
   file
   filesystem
   lnk_file
   sock_file
# seinfo --class file -x

Classes: 1
   class file
inherits file
{
	execute_no_trans
	execmod
	open
	audit_access
	entrypoint
}
# seinfo --common file -x

Commons: 1
   common file
{
	setattr
	append
	swapon
	execute
	lock
	quotaon
	unlink
	write
	read
	getattr
	rename
	relabelto
	mounton
	map
	ioctl
	link
	relabelfrom
	create
}
  1. Изучите виды доступа для других классов: dir, blk_file, chr_file, lnk_file, fifo_file, sock_file, filesystem.

  2. Сравните виды доступа классов file и dir.

$ seinfo | grep 'Policy Version'
Policy Version:             32 (MLS enabled)
$ seinfo -c file -x

Classes: 1
   class file
inherits file
{
	entrypoint
	execute_no_trans
}
$ seinfo -c dir -x

Classes: 1
   class dir
inherits file
{
	add_name
	search
	remove_name
	reparent
	rmdir
}
$ seinfo --common file -x

Commons: 1
   common file
{
	swapon
	relabelto
	map
	quotaon
	execmod
	lock
	append
	audit_access
	setattr
	ioctl
	mounton
	link
	execute
	rename
	relabelfrom
	read
	create
	write
	unlink
	getattr
	open
}

Управление контекстами безопасности файлов

Утилита semanage предназначена для управления политикой безопасности (контекстами файлов и сетевых портов, буленами, пользователями и ролями и др.).

  1. Определение контекстов с помощью регулярных выражений. Файлы /etc/selinux/targeted/contexts/files/file_contexts.*. Изучите список регулярных выражений, задающих контесты безопасности файлов.

     $ grep 'httpd_.*_t' /etc/selinux/targeted/contexts/files/file_contexts
    
  2. Выведите список регулярных выражений:

     # semanage fcontext -l
     Контекст файла SELinux                     тип                Контекст
     
     /.*                                        all files          system_u:object_r:default_t:s0 
     /[^/]+                                     regular file       system_u:object_r:etc_runtime_t:s0 
     /a?quota\.(user|group)                     regular file       system_u:object_r:quota_db_t:s0 
     /mnt(/[^/]*)?                              symbolic link      system_u:object_r:mnt_t:s0 
     /mnt(/[^/]*)?                              directory          system_u:object_r:mnt_t:s0 
     ...
    
  3. Изучите назначение контекста файлам. Наследование по умолчанию. Создайте новый файл. Определите его контекст. Определите контекст каталога, в котором был создан файл.

  4. Копирование и перемещение файла внутри и за пределы файловой системы.

  5. Контекст файловой системы. Назначение контекста при монтировании файловой системы. Опции команды mount: context и defcontext.

  6. Изменение контекста файла. Временное изменение контекста файла. Команда chcon.

  7. Резервные копии. Сохранение и восстановление расширенных атрибутов.

  8. Изменение контекста файла (постоянное). Команда semanage fcontext.

Ограничение web-сервера Apache с помощью политики безопасности SELinux

Подготовка

Установите web-сервер Apache и запустите его.

# yum install httpd -y
...
=====================================================================================
 Package                   Architecture  Version                Repository      Size
=====================================================================================
Installing:
 httpd                     x86_64        2.4.46-1.fc32          updates        1.4 M
...
# systemctl start httpd.service
# systemctl enable httpd.service
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.

Для доступа к серверу из сети нужно узнать IP-адрес с помощью команды ip addr. Также дополнительно может понадобиться настроить файервол (иногда его еще называют брандмауэр) следующим образом:

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

Содержимое сайта располагается в директории /var/www/html/. Создайте файл index.html. Изучите типы созданного файла и директории.

# echo 'Здравствуй, МИФИ!' > /var/www/html/index.html
# ls -dZ /var/www/html/
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/
# ls -Z /var/www/html/index.html 
unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html

Проверьте работоспособность web-сервера Apache. Это можно сделать, обратившись в браузере по локальному адресу 127.0.0.1, или в командной строке с помощью утилиты curl, предназначенной для передачи данных по разным протоколам (в т.ч. HTTP).

$ curl 127.0.0.1/
Здравствуй, МИФИ!

Изменение корневой директории сайта

Предположим, что нужно развернуть сайт в новой директории /www/. Для настройки web-сервера Apache предназначен конфигурационный файл /etc/httpd/conf/httpd.conf. Измените DocumentRoot "/var/www/html" на DocumentRoot "/www", а также соответствующие <Directory "/www">.

Создайте новую директорию и файл index.html в ней. Изучите типы созданных файла и директории.

# mkdir /www
# echo 'Новый сайт' > /www/index.html 
# ls -dZ /www/
unconfined_u:object_r:default_t:s0 /www/
# ls -Z /www/index.html 
unconfined_u:object_r:default_t:s0 /www/index.html

Обратите внимание на тип default_t.

Перезапустите web-сервер Apache.

systemctl restart httpd.service

Поиск причины

Права доступа субъектов к объектам кодируются в виде т.н. векторов доступа, которые для повышения производительности кэшируются. Поэтому сообщения системы аудита, которые генерятся системой SELinux имеют тип AVC (Access Vector Cache).

Проверьте работоспособность web-сервера Apache. Так как новая страница не появилась, выполните поиск недавних событий аудита с типом AVC.

# ausearch -m avc -ts recent -i
----
type=PROCTITLE msg=audit(03/15/2024 00:40:22.084:98407) : proctitle=/usr/sbin/httpd -DFOREGROUND 
type=PATH msg=audit(03/15/2024 00:40:22.084:98407) : item=0 name=/www/index.html inode=393218 dev=103:03 mode=file,644 ouid=root ogid=root rdev=00:00 obj=unconfined_u:object_r:default_t:s0 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0 cap_frootid=0 
type=CWD msg=audit(03/15/2024 00:40:22.084:98407) : cwd=/ 
type=SYSCALL msg=audit(03/15/2024 00:40:22.084:98407) : arch=x86_64 syscall=stat success=no exit=EACCES(Permission denied) a0=0x7f21f000a408 a1=0x7f21f7ffe800 a2=0x7f21f7ffe800 a3=0x2 items=1 ppid=116731 pid=116734 auid=unset uid=apache gid=apache euid=apache suid=apache fsuid=apache egid=apache sgid=apache fsgid=apache tty=(none) ses=unset comm=httpd exe=/usr/sbin/httpd subj=system_u:system_r:httpd_t:s0 key=(null) 
type=AVC msg=audit(03/15/2024 00:40:22.084:98407) : avc:  denied  { getattr } for  pid=116734 comm=httpd path=/www/index.html dev="nvme0n1p3" ino=393218 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0 

Воспользуйтесь системой помощи SELinux - утилитой audit2why.

# ausearch -m avc -ts recent | audit2why

Также посмотрите, что предлагает вторая утилита помощи audit2allow.

# ausearch -m avc -ts recent | audit2allow 


#============= httpd_t ==============
allow httpd_t default_t:file getattr;

Что является причиной запрета доступа?

Восстановление работы web-сервера Apache

Добавьте правильный тип для новой директории сайта:

# semanage fcontext -a -t httpd_sys_content_t "/www(/.*)?"
# semanage fcontext -l | grep '^/www'
/www(/.*)?                                         all files          system_u:object_r:httpd_sys_content_t:s0 

Обратите внимание, что команда semanage fcontext с ключом добавления -a только создаёт новую запись, но не изменяет типа директории!

Восстановите правильные контексты.

# restorecon -Rv /www/
Relabeled /www from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
Relabeled /www/index.html from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
# ls -Z /www/index.html 
unconfined_u:object_r:httpd_sys_content_t:s0 /www/index.html

Снова проверьте работоспособность web-сервера Apache.

$ curl 127.0.0.1/
Новый сайт

Работоспособность web-сервера Apache восстановлена.

Переходы

Утилита sesearch позволяет искать правила в политике безопасности по заданным критериям.

Переход типа

  1. Изучите правила перехода типа для файлов на примере web-сервера.

     $ sesearch -T -s httpd_t -t var_log_t
     Found 1 semantic te rules:
        type_transition httpd_t var_log_t : file httpd_log_t; 
     $ sesearch -T -s httpd_t -t tmp_t
     Found 4 semantic te rules:
        type_transition httpd_t tmp_t : file httpd_tmp_t; 
        type_transition httpd_t tmp_t : dir httpd_tmp_t; 
        type_transition httpd_t tmp_t : lnk_file httpd_tmp_t; 
        type_transition httpd_t tmp_t : sock_file httpd_tmp_t; 
    

Переход домена

Рассмотрим механизм перехода (изменения) домена на примере смены пользователем своего пароля с помощью команды passwd.

Разрешение процессу в домене passwd_t изменить файл с типом shadow_t

$ sesearch --allow --source passwd_t --target shadow_t --class file
allow passwd_t shadow_t:file { append create getattr ioctl link lock map open read relabelfrom relabelto rename setattr unlink write };

Условия для выполнения перехода домена

  1. Новый домен процесса имеет право entrypoint к типу исполняемого файла (запускаемой программы). Пример:

     # sesearch -A -s passwd_t -t passwd_exec_t -c file
        allow passwd_t passwd_exec_t:file { entrypoint execute getattr ioctl lock map open read };
    
  2. Текущий домен процесса имеет право execute к типу файла, который является точкой входа (entry point). Пример:

     # sesearch -A -s unconfined_t -t passwd_exec_t -c file
        allow unconfined_t passwd_exec_t:file { execute execute_no_trans getattr ioctl map open read };
    
  3. Текущий домен процесса имеет право transition к новому домену. Пример:

     # sesearch -A -s unconfined_t -t passwd_t -c process
        allow unconfined_t passwd_t:process transition;
    

Инициирование перехода домена по умолчанию

    $ sesearch --type_trans -s unconfined_t -t passwd_exec_t
    type_transition unconfined_t passwd_exec_t:process passwd_t;

Аудит

$ seinfo | grep -E '(dontaudit|allow)'.
# ausearch -m avc,user_avc,selinux_err -ts recent

Источники

  1. Документация по SELinux на русском языке
  2. Видеолекция по SELinux
  3. Официальный сайт SELinux
  4. SELinux HowTos
  5. SECURITY ENHANCED LINUX FOR MERE MORTALS видео
  6. Demystifying SELinux, видео
  7. SELinux Sandbox
  8. SELinux Coloring Book (в виде статьи)
  9. http://man7.org/linux/man-pages/man8/selinux.8.html
  10. http://man7.org/linux/man-pages/man8/sestatus.8.html
  11. http://man7.org/linux/man-pages/man8/setenforce.8.html
  12. http://man7.org/linux/man-pages/man8/getenforce.8.html
  13. http://man7.org/linux/man-pages/man8/semanage-fcontext.8.html
  14. http://man7.org/linux/man-pages/man8/restorecon.8.html
  15. http://man7.org/linux/man-pages/man1/chcon.1.html
  16. http://man7.org/linux/man-pages/man8/booleans.8.html
  17. http://man7.org/linux/man-pages/man8/getsebool.8.html
  18. http://man7.org/linux/man-pages/man8/setsebool.8.html
  19. http://man7.org/linux/man-pages/man8/semanage-boolean.8.html
  20. http://man7.org/linux/man-pages/man8/semanage-login.8.html
  21. http://man7.org/linux/man-pages/man8/semanage-user.8.html
  22. http://man7.org/linux/man-pages/man1/audit2why.1.html
  23. http://man7.org/linux/man-pages/man8/ausearch.8.html