Если где-то появилась надпись “Permission denied” или “В разрешении отказано” – это оно, SELinux.
В MicroOS почти все в контейнерах. Так что можно поразбираться немного, не отключая SELinux.
Посмотреть сообщения об ошибках:
ausearch -m AVC,USER_AVC
Затем скопировать их в audit2allow для подсказки как написать правила:
audit2allow -M local << EOF
type=AVC msg=audit(1234.332:155): avc: denied { read } for pid=1 comm="systemd" name="poweroff.timer" dev="overlay" ino=14326 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
type=AVC msg=audit(1235.916:182): avc: denied { execute } for pid=1481 comm="(t_run.sh)" name="first_run.sh" dev="sda1" ino=390 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=file permissive=0
type=AVC msg=audit(1236.103:208): avc: denied { open } for pid=1 comm="systemd" path="/etc/systemd/system/poweroff.timer" dev="overlay" ino=14326 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
type=AVC msg=audit(1237.700:45): avc: denied { execute_no_trans } for pid=1232 comm="(t_run.sh)" path="/cloud/system/first_run.sh" dev="sda1" ino=390 scontext=system_u:system_r:init_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=file permissive=0
type=AVC msg=audit(1238.028:1018): avc: denied { connectto } for pid=9419 comm="go-avahi-cname" path="/run/dbus/system_bus_socket" scontext=system_u:system_r:container_t:s0:c620,c905 tcontext=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0
type=USER_AVC msg=audit(1239.616:1869): pid=867 uid=499 auid=4294967295 ses=4294967295 subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc: denied { send_msg } for msgtype=method_call interface=org.freedesktop.DBus member=Hello dest=org.freedesktop.DBus spid=15063 scontext=system_u:system_r:container_t:s0:c620,c905 tcontext=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 tclass=dbus permissive=0 exe="/usr/bin/dbus-daemon" sauid=499 hostname=? addr=? terminal=?'
type=USER_AVC msg=audit(1240.455:3529): pid=867 uid=499 auid=4294967295 ses=4294967295 subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc: denied { send_msg } for msgtype=method_call interface=org.freedesktop.Avahi.Server member=GetHostNameFqdn dest=org.freedesktop.Avahi spid=26468 tpid=865 scontext=system_u:system_r:container_t:s0:c620,c905 tcontext=system_u:system_r:avahi_t:s0 tclass=dbus permissive=0 exe="/usr/bin/dbus-daemon" sauid=499 hostname=? addr=? terminal=?'
type=USER_AVC msg=audit(1241.936:4020): pid=867 uid=499 auid=4294967295 ses=4294967295 subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc: denied { send_msg } for msgtype=method_return dest=:1.6155 spid=865 tpid=29848 scontext=system_u:system_r:avahi_t:s0 tcontext=system_u:system_r:container_t:s0:c620,c905 tclass=dbus permissive=0 exe="/usr/bin/dbus-daemon" sauid=499 hostname=? addr=? terminal=?'
type=USER_AVC msg=audit(1242.396:4015): pid=867 uid=499 auid=4294967295 ses=4294967295 subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc: denied { send_msg } for msgtype=method_call interface=org.freedesktop.Avahi.Server member=GetHostNameFqdn dest=org.freedesktop.Avahi spid=29827 tpid=865 scontext=system_u:system_r:container_t:s0:c620,c905 tcontext=system_u:system_r:avahi_t:s0 tclass=dbus permissive=0 exe="/usr/bin/dbus-daemon" sauid=499 hostname=? addr=? terminal=?'
type=AVC msg=audit(1703137871.316:156): avc: denied { ioctl } for pid=1 comm="systemd" path="/etc/systemd/system/poweroff.timer" dev="overlay" ino=35184 ioctlcmd=0x5401 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file permissive=0
type=AVC msg=audit(1703372068.827:2596): avc: denied { write } for pid=20749 comm="systemd-helper" name="system_bus_socket" dev="tmpfs" ino=1475 scontext=system_u:system_r:snapperd_t:s0 tcontext=system_u:object_r:container_file_t:s0 tclass=sock_file permissive=0
EOF
Сгенерированный файл local.te можно подправить по желанию. Тогда нужно его компилировать:
checkmodule -M -m -o local.mod local.te
semodule_package -o local.pp -m local.mod
И установить (применяется постоянно):
semodule -i local.pp
Только еще audit2allow поставить надо:
transactional-update pkg install policycoreutils-python-utils
reboot
В целом, понятно, что такой подход немного лучше полного отключения SELinux, но хуже “правильной” задачи прав. Сейчас права выглядят как unconfined_u:object_r:unlabeled_t:s0
. По идее нужно будет разобраться с текущими политиками, а исходя из этого понять добавить новые файлы в какие-то готовые сущности или нужно свои заводить.
В итоге
А когда все это после множества итераций надоест просто отключаем:
echo > /etc/selinux/config <<EOF
SELINUX=permissive
SELINUXTYPE=targeted
EOF
reboot
Почему? Практически на каждый докер-контейнер нужно дорабатывать правила. Плюс, cockpit есть в пакетах, но правил на него нет (даже залогиниться нельзя). А в последней установке вообще что-то сломалось (в самой системе?) и свои правила не применялись:
# semodule -i local.pp
libsemanage.semanage_module_info_set_lang_ext: Language extensions = is invalid.
libsemanage.semanage_module_info_set_lang_ext: Language extensions = is invalid.
libsemanage.semanage_module_info_set_lang_ext: Language extensions = is invalid.
semodule: Failed on local.pp!
Так что SELinux пока что не для дома, даже если пользовательские приложения собираемся только в контейнерах запускать.
И это тоже может не помочь, если в файле etc/default/grub
прописано enforcing=1
(нужно поменять на 0 и перегененировать командой sudo transactional-update grub.cfg; reboot
).