我无法让 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 故障排除流程:
- 问题可以重现吗?如果是,则移至 2。
- 它可以在宽容模式下工作吗?如果是,则移至 3。
- SELinux 是否记录事件记录?
ausearch -m avc,user_avc,selinux_err -i
。如果是,请解释它们和/或让audit2why 为您解释它们。如果没有移动到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 例外。
- 确保 SELinux 正在
Permissive
模式下运行。 - 确保拒绝记录在 /var/log/audit.log 中。如果没有任何内容,请运行
semodule -DB
并再次运行有问题的程序;应该生成日志。一旦完成,运行semodule -B
以禁用详细日志记录。 - 运行
audit2allow -w -a
- 这将以人类可读的形式向您显示正在阻止的内容。 - 运行
audit2allow -a
以查看允许拒绝访问的类型强制规则 - 如果您同意上述输出,请运行
audit2allow -a -M newrules
以创建自定义模块。该选项在当前工作目录中-M
创建一个类型强制文件 (.te),其名称由 指定-M
- 要安装模块,请运行
semodule -i newrules.pp
- 将 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。