Если где-то появилась надпись “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).