LINUX.ORG.RU

SELinux. Нерегистрируемые блокировки при загрузке.

 , ,


0

1

Прикрутил SELinux к Archlinux. Политики брал с https://github.com/TresysTechnology/refpolicy. Загрузился в permissive режиме, внес поправки в политики с учетом системы инициализации systemd. То есть сам systemd у меня загружается в домене init_t, а дальше я прописал для него цепочки переходов в новые домены для остальных сервисов. Вот список модулей политик, которые у меня на данный момент загружены:

  • base.pp
  • init.pp
  • libraries.pp
  • logging.pp
  • selinuxutil.pp
  • modutils.pp
  • userdomain.pp
  • miscfiles.pp
  • sysadm.pp
  • authlogin.pp
  • sysnetwork.pp
  • storage.pp
  • application.pp
  • locallogin.pp
  • getty.pp
  • xserver.pp
  • mount.pp
  • unconfined.pp
  • udev.pp
  • avahi.pp
  • cups.pp
  • dbus.pp
  • alsa.pp
  • dhcp.pp
  • networkmanager.pp
  • ssh.pp
  • policykit.pp
  • ntp.pp

Перезагрузился, пофиксил все блокировки, которые выводятся при «journalctl -b | grep -i avc». Все, теперь после перезагрузки лог чистый. Отменил правила dontaudit («semodule -DB»). Возникло еще несколько запрещений, которые я тоже разрешил. Прописал в конфиге режим «enforcing», перезагрузился. При загрузке выводятся несколько красных сообщений об ошибках, успеваю прочесть только, что «failed» и «journalctl». Грепнул лог:

$ journalctl -b | grep -i denied 
июл 28 12:19:44 localhost journalctl[191]: Failed to kill journal service: Access denied
июл 28 12:19:46 localhost systemd-update-utmp[263]: Failed to get timestamp: Access denied
июл 28 12:19:47 localhost systemd-logind[309]: Failed to enable subscription: Access denied
июл 28 12:19:47 localhost systemd-logind[309]: Failed to fully start up daemon: Permission denied
июл 28 12:19:47 localhost systemd-logind[324]: Failed to enable subscription: Access denied
июл 28 12:19:47 localhost systemd-logind[324]: Failed to fully start up daemon: Permission denied
И так далее, много подобных сообщений. При «permissive» режиме такого поведения не наблюдается, поэтому предполагаю, что виноват все-же SELinux. Нашел в логе такое интересное место:
июл 28 13:34:43 localhost unknown[1]: <audit-1130> pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='unit=systemd-journald comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
июл 28 13:34:43 localhost kernel: audit: type=1130 audit(1438079683.186:10): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='unit=systemd-journald comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
июл 28 13:34:43 localhost journalctl[189]: Failed to kill journal service: Access denied
июл 28 13:34:43 localhost unknown[1]: <audit-1130> pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='unit=systemd-udevd comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
июл 28 13:34:43 localhost kernel: audit: type=1130 audit(1438079683.290:11): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='unit=systemd-udevd comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
июл 28 13:34:43 localhost systemd[1]: systemd-journal-flush.service: main process exited, code=exited, status=1/FAILURE
июл 28 13:34:43 localhost systemd[1]: Failed to start Flush Journal to Persistent Storage.
июл 28 13:34:43 localhost systemd[1]: Unit systemd-journal-flush.service entered failed state.
июл 28 13:34:43 localhost systemd[1]: systemd-journal-flush.service failed.
июл 28 13:34:43 localhost unknown[1]: <audit-1130> pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='unit=systemd-journal-flush comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=failed'
июл 28 13:34:43 localhost unknown[1]: <audit-1130> pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='unit=systemd-vconsole-setup comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
Из него сделал вывод, что косячит «systemd-journal-flush.service». Решил посмотреть, что же он делает. Делает вещь он весьма нехитрую:
[Service]
ExecStart=/usr/bin/journalctl --flush
Перевел свой shell в домен init_t, попытался сделать flush вручную:
/bin/journalctl --flush
Failed to kill journal service: Access denied
То же самое. Фигня. Полез в исходники journalctl, дабы понять, что конкретно он не смог. Нашел нужный кусок кода:
if (access("/run/systemd/journal/flushed", F_OK) >= 0)
                return 0;

        /* OK, let's actually do the full logic, send SIGUSR1 to the
         * daemon and set up inotify to wait for the flushed file to appear */
        r = bus_open_system_systemd(&bus);
        if (r < 0)
                return log_error_errno(r, "Failed to get D-Bus connection: %m");

        r = sd_bus_call_method(
                        bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "KillUnit",
                        &error,
                        NULL,
                        "ssi", "systemd-journald.service", "main", SIGUSR1);
        if (r < 0) {
                log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
                return r;
        }
Ага, вот и до D-Bus добрался. Пробую достучаться вручную до этого метода:
$ qdbus-qt4 --system org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.KillUnit
Error: org.freedesktop.DBus.Error.InvalidArgs
Invalid arguments '' to call org.freedesktop.systemd1.Manager.KillUnit(), expecting 'ssi'.
Ошибка, не передал аргументы. А теперь фокус:
$ qdbus-qt4 --system org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.KillUnit "systemd-journald.service" "main" SIGUSR1
Cannot find 'org.freedesktop.systemd1.Manager.KillUnit' in object /org/freedesktop/systemd1 at org.freedesktop.systemd1
Вот. При переданных аргументах оно вообще этот метод не видит. Я не понимаю, как такое возможно. Замечу, что даже после всех вышеприведенных действий сообщений о блокировках SELinux в лог journalctl не поступало. /var/log/audit/audit.log тоже молчит. Может, подскажете, куда дальше копать можно? А то я уже демон dbus начал трассировать в надежде информацию какую-нибудь добыть. Да, и еще. dbus у меня собран с поддержкой SELinux, и systemd тоже. Потому как я прочел, что некоторые блокировки могут происходить в юзерспейсе. Но сообщений user_avc в логе так же нет. Помогите советом, пожалуйста.

Была ещё команда ″semodule -DB″, так как есть правила, для которых указано dontaudit.

Про qdbus особо не знаю, но, вроде как для ″dbus-send″ нужно указывать типы аргументов, как-то так:

s:systemd-journald.service s:main i:SIGUSR1

может для qdbus достаточно кавычек, но в вашей командной строке они не дойдут до qdbus, их «съест» bash.

mky ★★★★★ ()
Ответ на: комментарий от mky

Я во втором абзаце написал, что «semodule -DB» я сразу сделал((( Про dbus-send спасибо, сейчас попробую через него. И да, просто команда «systemctl» у меня тоже блокируется((( Она по идее тоже обращается к systemd по DBus, чтобы получить список сервисов.

esvstn ()
Ответ на: комментарий от mky
$ dbus-send --system --dest=org.freedesktop.systemd1 --type=method_call --print-reply /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager.KillUnit string:systemd-journald.service string:main int32:SIGUSR1
Error org.freedesktop.DBus.Error.AccessDenied: SELinux policy denies access.

Тоже запрещает. Но:

$ cat /var/log/audit/audit.log | grep -i avc
продолжает молчать(

esvstn ()
Ответ на: комментарий от esvstn

Тоже запрещает.

Запрещает, но по строке «Error org.freedesktop.DBus.Error.AccessDenied: SELinux policy denies access.» что-то гуглится.

У меня по строке ″SELinux policy denies access″ гуглится код ″mac_selinux_generic_access_check()″ из файла ″selinux-access.c″. И, если я не путаю, то там в функции сначала проверяется, что прав не хватает, но ошибка выводится только в случае enforce-режима. Может быть там в функции ошибка и на самом деле прав хватает... не знаю, на вашем месте я бы попробовал насовать отладочной печати и перекомпилировать, но из скомпилированного использовать только dbus-send, чтобы от остального лишнего не лезло.

mky ★★★★★ ()
Ответ на: комментарий от mky

Ну ошибки я там не нашел. Вроде, все верно. Я врезал ручную запись в лог в фунции «log_dispatch» файла «log.c». После перезагрузки обнаружил там несколько интересных юзерспейсных запрещений. Долго, скорее всего, разбирать их буду, так как эталонные политики на systemd не рассчитаны, там пару классов вручную прописать придется. Но все же мне очень интересно, почему же systemd из коробки не пишет в лог USER_AVC?

esvstn ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.