SELinux 阻止 qemu / libvirt 访问 ISO

SELinux 阻止 qemu / libvirt 访问 ISO

我无法让 selinux 允许 libvirt 访问默认 libvirt 目录之外的映像和 ISO 文件。更令人沮丧的是,即使我在audit.log中有一个失败条目,audit2allow和setroubleshooter也没有看到任何问题

type=VIRT_CONTROL msg=audit(1576848063.439:6601): pid=1265 uid=0 auid=4294967295 ses=4294967295 \
subj=system_u:system_r:virtd_t:s0-s0:c0.c1023 msg='virt=kvm op=start reason=booted vm="Unifi" uuid=37eed7bf-a37f-4d49-86c2-b9a6bb8682c3 \
vm-pid=-1 exe="/usr/sbin/libvirtd" hostname=? addr=? terminal=? res=failed'UID="root" AUID="unset"

图像

-rw-------+ 1 root root system_u:object_r:svirt_image_t:s0            53695545344 Dec 20 08:31 unifi.qcow2

国际标准化组织

-rw-rwxr--+  1 qemu    qemu system_u:object_r:virt_content_t:s0                   851443712 Sep 29  2018  ubuntu-18.04.1-live-server-amd64.iso

我的 file_contexts.local 文件包含以下条目,对于我未经训练的眼睛来说看起来不错。

/data/libvirt(/.*)?    system_u:object_r:svirt_image_t:s0
/data/archive/ISO(/.*)?    system_u:object_r:svirt_image_t:s0

想法?

编辑2(AB请求更新):

启用调试后的 SELinux 输出。

type=AVC msg=audit(1577807557.017:10195): avc:  denied  { search } for  pid=13605 comm="qemu-kvm" name="/" dev="dm-8" ino=2 scontext=system_u:system_r:svirt_t:s0:c682,c798 tcontext=system_u:object_r:container_file_t:s0:c132,c155 tclass=dir permissive=0
    Was caused by:

#Constraint rule:

#   mlsconstrain dir { ioctl read lock search } ((h1 dom h2 -Fail-)  or (t1 != mcs_constrained_type -Fail-) ); Constraint DENIED

#   Possible cause is the source level (s0:c682,c798) and target level (s0:c132,c155) are different.

Audit2allow -i /var/log/audit/audit.log -m qemu-kvm

module qemu-kvm 1.0;

require {
    type initrc_t;
    type container_file_t;
    type setroubleshootd_t;
    type NetworkManager_t;
    type svirt_t;
    type system_dbusd_t;
    class process { noatsecure rlimitinh siginh };
    class dir search;
    class capability net_admin;
}

#============= NetworkManager_t ==============
allow NetworkManager_t initrc_t:process { noatsecure rlimitinh siginh };

#============= svirt_t ==============

#!!!! This avc is a constraint violation.  You would need to modify the attributes of either the source or target types to allow this access.
#Constraint rule: 
#   mlsconstrain dir { ioctl read lock search } ((h1 dom h2 -Fail-)  or (t1 != mcs_constrained_type -Fail-) ); Constraint DENIED

#   Possible cause is the source level (s0:c682,c798) and target level (s0:c132,c155) are different.
allow svirt_t container_file_t:dir search;

#============= system_dbusd_t ==============
allow system_dbusd_t self:capability net_admin;
allow system_dbusd_t setroubleshootd_t:process { noatsecure rlimitinh siginh };

编辑:这是我收到的错误。标签看起来正确,并且 qemu 的文件权限设置为 rwx

Error starting domain: internal error: process exited while connecting to monitor: 2019-12-20T15:34:53.600905Z qemu-kvm: -drive file=/data/archive/ISO/ubuntu-18.04.1-live-server-amd64.iso,format=raw,if=none,id=drive-sata0-0-0,media=cdrom,readonly=on: Could not open '/data/archive/ISO/ubuntu-18.04.1-live-server-amd64.iso': Permission denied

Traceback (most recent call last):
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 75, in cb_wrapper
    callback(asyncjob, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/asyncjob.py", line 111, in tmpcb
    callback(*args, **kwargs)
  File "/usr/share/virt-manager/virtManager/object/libvirtobject.py", line 66, in newfn
    ret = fn(self, *args, **kwargs)
  File "/usr/share/virt-manager/virtManager/object/domain.py", line 1279, in startup
    self._backend.create()
  File "/usr/lib/python3/dist-packages/libvirt.py", line 1080, in create
    if ret == -1: raise libvirtError ('virDomainCreate() failed', dom=self)
libvirt.libvirtError: internal error: process exited while connecting to monitor: 2019-12-20T15:34:53.600905Z qemu-kvm: -drive file=/data/archive/ISO/ubuntu-18.04.1-live-server-amd64.iso,format=raw,if=none,id=drive-sata0-0-0,media=cdrom,readonly=on: Could not open '/data/archive/ISO/ubuntu-18.04.1-live-server-amd64.iso': Permission denied

文件权限

getfacl /data/libvirt/images
getfacl: Removing leading '/' from absolute path names
# file: data/libvirt/images
# owner: qemu
# group: qemu
# flags: ss-
user::rwx
group::rwx
other::--x
default:user::rwx
default:user:qemu:rwx
default:group::rwx
default:group:qemu:rwx
default:mask::rwx
default:other::--x

答案1

标准 SELinux 故障排除流程:

  1. 问题可以重现吗?如果是,则移至 2。
  2. 它可以在宽容模式下工作吗?如果是,则移至 3。
  3. SELinux 是否记录事件记录?ausearch -m avc,user_avc,selinux_err -i。如果是,请解释它们和/或让audit2why 为您解释它们。如果没有移动到4。
  4. 运行semodule -DB以使 SELinux 详细,然后重现问题并返回到 3。

如果 SELinux 阻塞,则 SELinux 记录。您需要事件记录,以便在实施解决方案之前可以解释问题。

您尚未提供任何 SELinux 事件日志,因此我目前只能推测。它可能与您的自定义安装点的标签有关/data。如果 libvirt 无法遍历,/data那么它永远无法到达图像。

答案2

非常感谢 dac.override 和 AB 为我提供了找到此内容所需的信息。

检查顶级目录“/data”会显示一个标签

system_u:object_r:container_file_t:s0:c132,c155

这也显示在子目录中,包括“/data/libvirt”目录。这是由每天运行的用于备份“/data”目录的容器引起的。容器使用以下命令挂载此目录

-v /data:/data:ro,Z

这是我在使用生产容器时养成的习惯。更改为

-v /data:/data:ro,z

允许备份运行而不会阻止 libvirt。现在我们得到以下标签

system_u:object_r:container_file_t:s0

请注意,这很可能不是最佳实践。不过,对于我的个人服务器来说就足够了。所有其他容器和服务都将从单独的虚拟机运行,而主机只是一个主机。

答案3

对于那些在 中确实有相关错误的人audit.log,如果这是全新安装,您可以使用audit2allow自动为您生成正确的 SELinux 配置。我个人只在全新安装时运行它,因为如果您不小心,您可能会允许未经授权的软件 SELinux 例外。

  1. 确保 SELinux 正在Permissive模式下运行。
  2. 确保拒绝记录在 /var/log/audit.log 中。如果没有任何内容,请运行semodule -DB并再次运行有问题的程序;应该生成日志。一旦完成,运行semodule -B以禁用详细日志记录。
  3. 运行audit2allow -w -a- 这将以人类可读的形式向您显示正在阻止的内容。
  4. 运行audit2allow -a以查看允许拒绝访问的类型强制规则
  5. 如果您同意上述输出,请运行audit2allow -a -M newrules以创建自定义模块。该选项在当前工作目录中-M创建一个类型强制文件 (.te),其名称由 指定-M
  6. 要安装模块,请运行semodule -i newrules.pp
  7. 将 SELinux 设置为Enforcing模式;测试功能。

我建议only在正在构建的新服务器上运行它,因为您可能会允许应用程序绕过不需要的 SELinux。这在生产服务器中可能很危险。如果您有多个提到的内容,您可以按照 Red Hat 文档中提到的方式audit2allow使用。grep官方文档请参考audit2allow链接。

答案4

您需要为图像文件夹提供适当的标签,以允许虚拟机共享读/写内容。该标签需要有类型svirt_image_t:s0

semanage fcontext -a -t svirt_image_t "/data/libvirt/images(/.*)?"
restorecon -vR /data/libvirt/images

如果安装,添加context为选项:

mount ... /data/libvirt/images -o context="system_u:object_r:svirt_image_t:s0"
// keep default for user and role, but type is important:    ^--------------^ 

SELinux 现在允许从 VM/QEMU/virt-manager 访问 ISO。

相关内容