管理多个 VM 主机服务器,每个服务器托管多个 VM 访客,很快就会变得困难。 libvirt 的一个好处是能够同时连接到多个 VM 主机服务器,从而提供一个用于管理所有 VM 访客并连接到其图形控制台的单一界面。
为了确保只有授权用户才能连接,libvirt 提供了几种连接类型(通过 TLS、SSH、Unix 套接字和 TCP),可以与不同的授权机制(套接字、Polkit、SASL 和 Kerberos)结合使用。
管理 VM 客户机和访问其图形控制台的权限应该限制在明确定义的范围内。为了实现这个目标,您可以在 VM 主机服务器上使用以下身份验证技术
使用权限和组所有权控制 Unix 套接字的访问。此方法仅适用于 libvirtd 连接。
使用 Polkit 控制 Unix 套接字的访问。此方法仅适用于本地 libvirtd 连接。
使用 SASL(简单身份验证和安全层)进行用户名和密码身份验证。此方法适用于 libvirtd 和 VNC 连接。使用 SASL 不需要服务器上的真实用户帐户,因为它使用自己的数据库来存储用户名和密码。使用 SASL 身份验证的连接是加密的。
Kerberos 身份验证。此方法仅适用于 libvirtd 连接,本手册不介绍。有关详细信息,请参阅 https://libvirt.org/auth.html#ACL_server_kerberos。
单密码身份验证。此方法仅适用于 VNC 连接。
libvirtd 和 VNC 的身份验证需要单独配置访问 VM 客户机的管理功能(通过 libvirtd)和其图形控制台始终需要单独配置。在限制对管理工具的访问时,这些限制不会自动应用于 VNC 连接!
当通过 TLS/SSL 连接从远程访问 VM 客户机时,可以通过将证书密钥文件的读取权限限制为特定组来间接控制每个客户端的访问。有关详细信息,请参阅 第 11.3.2.5 节,“限制访问(安全注意事项)”。
libvirtd 身份验证在 /etc/libvirt/libvirtd.conf 中配置。此处进行的配置适用于所有 libvirt 工具,例如虚拟机管理器或 virsh。
libvirt 提供了两个套接字:一个只读套接字用于监控目的,一个读写套接字用于管理操作。可以独立配置对两个套接字的访问。默认情况下,两个套接字都由 root.root 拥有。只读套接字的默认访问权限是完全开放的(0777),读写套接字的默认访问权限是限制为用户 root(0700)。
以下说明介绍了如何配置读写套接字的访问权限。相同的说明也适用于只读套接字。所有配置步骤都需要在 VM 主机服务器上执行。
在 openSUSE Leap 上,默认身份验证方法是 Unix 套接字的访问控制。只有用户 root 才能进行身份验证。当直接在 VM 主机服务器上以非 root 用户身份访问 libvirt 工具时,您需要通过 Polkit 提供 root 密码一次。然后,您将获得当前会话和未来会话的访问权限。
或者,您可以配置 libvirt 允许非特权用户使用“system”访问。有关详细信息,请参阅 第 11.2.1 节,“非特权用户的“system”访问”。
| 第 11.1.1.2 节,“使用 Polkit 进行 Unix 套接字的本地访问控制” |
| 第 11.1.1.1 节,“使用权限和组所有权进行 Unix 套接字的访问控制” |
| 第 11.1.1.1 节,“使用权限和组所有权进行 Unix 套接字的访问控制” |
| 第 11.1.1.3 节,“使用 SASL 进行用户名和密码身份验证” |
| 无(通过限制对证书的访问在客户端侧控制访问) |
要授予非 root 帐户的访问权限,请配置套接字由特定组(在以下示例中为 libvirt)拥有并可访问。此身份验证方法可用于本地和远程 SSH 连接。
如果它不存在,请创建应拥有套接字的组
>sudogroupadd libvirt
在重新启动 libvirtd 之前,该组必须存在。否则,重启将失败。
将所需的用户添加到该组
>sudousermod --append --groups libvirt tux
按照以下方式更改 /etc/libvirt/libvirtd.conf 中的配置
unix_sock_group = "libvirt"1 unix_sock_rw_perms = "0770"2 auth_unix_rw = "none"3
重新启动 libvirtd
>sudosystemctl start libvirtd
使用 Polkit 控制 Unix 套接字是 openSUSE Leap 上非远程连接的默认身份验证方法。因此,不需要对 libvirt 进行任何配置更改。启用 Polkit 授权后,两个套接字的权限默认设置为 0777,并且每个尝试访问套接字的应用程序都需要通过 Polkit 进行身份验证。
由于 Polkit 不处理远程身份验证,因此只能在 VM 主机服务器本身上使用 Polkit 进行本地连接的身份验证。
存在两个用于访问 libvirt 套接字的策略
org.libvirt.unix.monitor:访问只读套接字
org.libvirt.unix.manage:访问读写套接字
默认情况下,访问读写套接字的策略是使用 root 密码进行身份验证一次,并授予当前会话和未来会话的权限。
要授予用户访问套接字的权限而无需提供 root 密码,您需要在 /etc/polkit-1/rules.d 中创建一个规则。使用以下内容创建文件 /etc/polkit-1/rules.d/10-grant-libvirt,以授予组 libvirt 的所有成员访问读写套接字的权限
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.unix.manage" && subject.isInGroup("libvirt")) {
return polkit.Result.YES;
}
});SASL 提供用户名和密码身份验证以及数据加密(默认情况下为 digest-md5)。由于 SASL 维护自己的用户数据库,因此用户不需要存在于 VM 主机服务器上。SASL 需要 TCP 连接,并且在 TLS/SSL 连接之上。
在未加密的 TCP 连接上使用 digest-md5 加密对于生产环境提供的安全性不足。建议仅在测试环境中使用它。
通过限制对证书密钥文件的访问来间接控制从远程 TLS/SSL 连接的访问 客户端侧。但是,在处理许多客户端时,这可能会容易出错。在服务器端添加 SASL 和 TLS 可以提高安全性。
要配置 SASL 身份验证,请按以下步骤操作
按照以下方式更改 /etc/libvirt/libvirtd.conf 中的配置
要为 TCP 连接启用 SASL
auth_tcp = "sasl"
要为 TLS/SSL 连接启用 SASL
auth_tls = "sasl"
重新启动 libvirtd
>sudosystemctl restart libvirtd
libvirt SASL 配置文件位于 /etc/sasl2/libvirtd.conf。通常,不需要更改默认设置。但是,如果在使用 SASL 在 TLS/SSL 之上,可以通过注释设置 mech_list 参数来关闭会话加密(TLS 连接已经加密)。仅对 TLS/SASL 执行此操作。对于 TCP 连接,必须将此参数设置为 digest-md5。
#mech_list: digest-md5
默认情况下,未配置任何 SASL 用户,因此无法进行任何登录。使用以下命令管理用户
tuxsaslpasswd2 -a libvirt tux
tuxsaslpasswd2 -a libvirt -d tux
sasldblistusers2 -f /etc/libvirt/passwd.db
virsh 和 SASL 身份验证在使用 SASL 身份验证时,每次发出 virsh 命令时,系统都会提示您输入用户名和密码。避免这种情况,请使用 shell 模式下的 virsh。
由于对 VM 客户机的图形控制台的访问不由 libvirt 控制,而是由特定的 hypervisor 控制,因此始终需要另外配置 VNC 身份验证。主配置文件是 /etc/libvirt/<hypervisor>.conf。本节描述 QEMU/KVM hypervisor,因此目标配置文件是 /etc/libvirt/qemu.conf。
与 KVM 相比,Xen 尚未提供比在每个 VM 的基础上设置密码更复杂的 VNC 身份验证。有关详细信息,请参阅 <graphics type='vnc'... libvirt 配置选项。
有两种身份验证类型可用:SASL 和单密码身份验证。如果您正在使用 SASL 进行 libvirt 身份验证,强烈建议也将其用于 VNC 身份验证——可以共享相同的数据库。
第三种限制对 VM 客户机访问的方法是在 VNC 服务器上启用 TLS 加密。这要求 VNC 客户端能够访问 x509 客户端证书。通过限制对这些证书的访问,可以间接在客户端侧控制访问。有关详细信息,请参阅 第 11.3.2.4.2 节,“VNC over TLS/SSL:客户端配置”。
SASL 提供用户名和密码身份验证以及数据加密。由于 SASL 维护自己的用户数据库,因此用户不需要存在于 VM 主机服务器上。与 SASL 身份验证 libvirt 类似,您可以在 TLS/SSL 之上使用 SASL。有关配置这些连接的详细信息,请参阅 第 11.3.2.4.2 节,“VNC over TLS/SSL:客户端配置”。
要配置 VNC 的 SASL 身份验证,请按以下步骤操作
创建一个 SASL 配置文件。建议使用现有的 libvirt 文件。如果您已经为 libvirt 配置了 SASL,并且计划使用相同的设置,包括相同的用户名和密码数据库,那么简单的链接就足够了
>sudoln -s /etc/sasl2/libvirt.conf /etc/sasl2/qemu.conf
如果仅为 VNC 设置 SASL,或者计划使用与 libvirt 不同的配置,请复制现有文件作为模板
>sudocp /etc/sasl2/libvirt.conf /etc/sasl2/qemu.conf
然后根据您的需要进行编辑。
按照以下方式更改 /etc/libvirt/qemu.conf 中的配置
vnc_listen = "0.0.0.0" vnc_sasl = 1 sasldb_path: /etc/libvirt/qemu_passwd.db
第一个参数启用 VNC 侦听所有公共接口(而不是仅侦听本地主机),第二个参数启用 SASL 身份验证。
默认情况下,未配置任何 SASL 用户,因此无法进行任何登录。使用以下命令管理用户
tux> saslpasswd2 -f /etc/libvirt/qemu_passwd.db -a qemu tuxtux> saslpasswd2 -f /etc/libvirt/qemu_passwd.db -a qemu -d tux> sasldblistusers2 -f /etc/libvirt/qemu_passwd.db重新启动 libvirtd
>sudosystemctl restart libvirtd
在更改配置后,重新启动所有已运行的虚拟机。未重新启动的虚拟机无法使用 SASL 身份验证进行 VNC 连接。
Virtual Machine Manager 和 virt-viewer 目前支持 SASL 身份验证。这两个查看器也支持 TLS/SSL 连接。
可以通过设置 VNC 密码来控制对 VNC 服务器的访问。您可以为所有虚拟机设置全局密码,也可以为每个虚拟机设置单独的密码。后者需要编辑虚拟机配置文件的内容。
如果您使用单密码身份验证,即使为每个虚拟机设置密码,也建议设置全局密码。如果忘记设置每台机器的密码,这将使用一个““备用””密码来保护您的虚拟机。全局密码仅在未为机器设置其他密码时才使用。
按照以下方式更改 /etc/libvirt/qemu.conf 中的配置
vnc_listen = "0.0.0.0" vnc_password = "PASSWORD"
第一个参数启用 VNC 侦听所有公共接口(而不是仅侦听本地主机),第二个参数设置密码。密码的最大长度为八个字符。
重新启动 libvirtd
>sudosystemctl restart libvirtd
在更改配置后,重新启动所有已运行的虚拟机。未重新启动的虚拟机无法使用密码身份验证进行 VNC 连接。
按照以下方式更改 /etc/libvirt/qemu.conf 中的配置,以启用 VNC 侦听所有公共接口(而不是仅侦听本地主机)。
vnc_listen = "0.0.0.0"
在编辑器中打开虚拟机的 XML 配置文件。将 VM_NAME 替换为虚拟机名称。使用的编辑器默认为 $EDITOR。如果未设置该变量,则使用 vi。
> virsh edit VM_NAME搜索具有属性 type='vnc' 的元素 <graphics>,例如
<graphics type='vnc' port='-1' autoport='yes'/>
添加 passwd=PASSWORD 属性,保存文件并退出编辑器。密码的最大长度为八个字符。
<graphics type='vnc' port='-1' autoport='yes' passwd='PASSWORD'/>
重新启动 libvirtd
>sudosystemctl restart libvirtd
在更改配置后,重新启动所有已运行的虚拟机。未重新启动的虚拟机无法使用密码身份验证进行 VNC 连接。
VNC 协议被认为是不安全的。虽然密码是加密传输的,但如果攻击者可以嗅探加密的密码和加密密钥,则可能存在漏洞。因此,建议使用 TLS/SSL 或通过 SSH 隧道使用 VNC。 virt-viewer、Virtual Machine Manager 和 Remmina(请参阅 Book “Reference”, Chapter 4 “Remote graphical sessions with VNC”, Section 4.2 “Remmina: the remote desktop client”)都支持这两种方法。
要使用 libvirt 连接到 hypervisor,您需要指定统一资源标识符 (URI)。此 URI 需要在 virsh 和 virt-viewer(在 VM 主机服务器上以 root 身份工作时除外)中使用,并且对于 Virtual Machine Manager 是可选的。虽然后者可以使用连接参数调用(例如,virt-manager -c qemu:///system),但它还提供了一个图形界面来创建连接 URI。有关详细信息,请参阅 第 11.2.2 节,“使用 Virtual Machine Manager 管理连接”。
HYPERVISOR1+PROTOCOL2://USER@REMOTE3/CONNECTION_TYPE4
指定 hypervisor。 openSUSE Leap 目前支持以下 hypervisor: | |
当连接到远程主机时,在此处指定协议。它可以是以下之一: | |
当连接到远程主机时,指定用户名和远程主机名。如果未指定用户名,则调用命令的用户名 ( | |
当连接到 |
test:///default连接到本地虚拟 hypervisor。用于测试。
qemu:///system 或 xen:///system连接到本地主机上的 QEMU/Xen hypervisor,具有完全访问权限(类型 system)。
qemu+ssh://tux@mercury.example.com/system 或 xen+ssh://tux@mercury.example.com/system连接到远程主机 mercury.example.com 上的 QEMU/Xen hypervisor。通过 SSH 隧道建立连接。
qemu+tls://saturn.example.com/system 或 xen+tls://saturn.example.com/system连接到远程主机 mercury.example.com 上的 QEMU/Xen hypervisor。使用 TLS/SSL 建立连接。
有关更多详细信息和示例,请参阅 libvirt 文档,网址为 https://libvirt.org/uri.html。
在使用 Unix 套接字身份验证时(无论使用用户/密码身份验证方案还是 Polkit),都需要指定用户名。这适用于所有 SSH 和本地连接。
在使用 SASL 身份验证(对于 TCP 或 TLS 连接)或对 TLS 连接不进行其他服务器端身份验证时,无需指定用户名。使用 SASL 时,用户名不会被评估 - 无论如何都会提示您输入 SASL 用户名/密码组合。
如上所述,可以使用两种不同的协议建立到 QEMU hypervisor 的连接:session 和 system。““session””连接以与客户端程序相同的权限生成。这种连接适用于桌面虚拟化,因为它受到限制(例如,没有 USB/PCI 设备分配,没有虚拟网络设置,对 libvirtd 的远程访问有限)。
““system””连接用于服务器虚拟化,没有功能限制,但默认情况下只能由 root 访问。但是,通过将 DAC(自主访问控制)驱动程序添加到 libvirt,现在可以授予非特权用户““system””访问权限。要授予用户 tux ““system””访问权限,请按以下步骤操作
启用通过 Unix 套接字访问,如 第 11.1.1.1 节,“使用权限和组所有权进行 Unix 套接字访问控制” 中所述。在该示例中,授予组 libvirt 的所有成员访问权限,并将 tux 添加到此组。这确保了 tux 可以使用 virsh 或 Virtual Machine Manager 连接。
编辑 /etc/libvirt/qemu.conf 并更改配置,如下所示
user = "tux" group = "libvirt" dynamic_ownership = 1
这确保了虚拟机由 tux 启动,并且与虚拟机关联的资源(例如虚拟磁盘)可以被 tux 访问和修改。
将 tux 添加到组 kvm
>sudousermod --append --groups kvm tux
此步骤是必要的,以授予对 /dev/kvm 的访问权限,这是启动虚拟机所必需的。
重新启动 libvirtd
>sudosystemctl restart libvirtd
Virtual Machine Manager 为其管理的每个 VM 主机服务器使用一个 Connection。每个连接包含相应主机上的所有虚拟机。默认情况下,已配置并连接到本地主机的连接。
所有配置的连接都显示在 Virtual Machine Manager 主窗口中。活动的连接用一个小三角形标记,您可以单击该三角形来折叠或展开该连接的虚拟机列表。
不活动的连接以灰色显示,并标记为 Not Connected。双击它或右键单击它并从上下文菜单中选择 。您还可以从此菜单 现有连接。
无法编辑现有连接。要更改连接,请创建一个具有所需参数的新连接,并删除““旧””连接。
要在 Virtual Machine Manager 中添加新连接,请按以下步骤操作
选择 ›
选择主机的 ( 或 )
(可选) 要设置远程连接,请选择 。有关更多信息,请参阅 第 11.3 节,“配置远程连接”。
在远程连接的情况下,在格式为 USERNAME@REMOTE _HOST 的格式中指定 。
对于 TCP 和 TLS 连接,无需指定用户名:在这些情况下,它不会被评估。但是,对于 SSH 连接,如果您想以其他于 root 的用户身份连接,则指定用户名是必要的。
如果您不希望在启动 Virtual Machine Manager 时自动启动连接,请停用 。
通过单击 完成配置。
libvirt 的主要优点是能够从中心位置管理不同远程主机上的虚拟机。本节提供了有关如何配置服务器和客户端以允许远程连接的详细说明。
在 VM 主机服务器上启用通过 SSH 隧道进行远程连接,只需要能够接受 SSH 连接。确保 SSH 守护程序已启动 (systemctl status sshd),并且防火墙中已打开服务 SSH 的端口。
可以使用如 第 11.1.1.1 节,“使用权限和组所有权进行 Unix 套接字访问控制” 中所述的传统文件用户/组所有权和权限进行 SSH 连接的用户身份验证。连接为用户 tux (qemu+ssh://tuxsIVname;/system 或 xen+ssh://tuxsIVname;/system) 即可开箱即用,无需在 libvirt 端进行其他配置。
当通过 SSH qemu+ssh://USER@SYSTEM 或 xen+ssh://USER@SYSTEM 连接时,您需要提供用户 USER 的密码。可以通过将您的公钥复制到 VM 主机服务器上的 ~USER/.ssh/authorized_keys 来避免这种情况,如 Book “Security and Hardening Guide”, Chapter 22 “Securing network operations with OpenSSH”, Section 22.6 “Public key authentication” 中所述。使用机器上的 gnome-keyring 可以增加便利性。有关更多信息,请参阅 Book “Security and Hardening Guide”, Chapter 22 “Securing network operations with OpenSSH”, Section 22.9 “Automated public key logins with gnome-keyring”。
使用带有 TLS/SSL 加密和通过 x509 证书进行身份验证的 TCP 连接比 SSH 设置要复杂得多,但可扩展性更高。如果需要管理具有不同数量管理员的多个 VM 主机服务器,请使用此方法。
TLS(传输层安全协议)通过使用证书来加密两个计算机之间的通信。启动连接的计算机始终被视为“客户端”,使用“客户端证书”,而接收计算机始终被视为“服务器”,使用“服务器证书”。例如,如果您从中央桌面管理您的 VM 主机服务器,则适用此场景。
如果从两台计算机启动连接,则每台计算机都需要具有客户端和服务器证书。例如,如果您将 VM 客户机从一台主机迁移到另一台主机,则会发生这种情况。
每个 x509 证书都有一个匹配的私钥文件。只有证书和私钥文件的组合才能正确识别自身。为了确保证书是由假定的所有者颁发的,它由中央证书颁发机构 (CA) 签名和颁发。客户端和服务器证书都必须由相同的 CA 颁发。
使用远程 TLS/SSL 连接仅确保允许两个计算机在某个方向上进行通信。可以通过在客户端限制对证书的访问来间接限制对某些用户的访问。有关更多信息,请参阅第 11.3.2.5 节,“限制访问(安全注意事项)”。
libvirt 还支持使用 SASL 在服务器上进行用户身份验证。有关更多信息,请参阅第 11.3.2.6 节,“使用 SASL 进行 TLS 套接字的集中用户身份验证”。
VM 主机服务器是接收连接的机器。因此,需要安装服务器证书。还需要安装 CA 证书。证书就位后,可以为 libvirt 启用 TLS 支持。
创建服务器证书并将其与相应的 CA 证书一起导出。
在 VM 主机服务器上创建以下目录
>sudomkdir -p /etc/pki/CA/ /etc/pki/libvirt/private/
按如下方式安装证书
>sudo/etc/pki/CA/cacert.pem>sudo/etc/pki/libvirt/servercert.pem>sudo/etc/pki/libvirt/private/serverkey.pem
通过启用相关套接字并重新启动 libvirtd 来启用 TLS 支持
>sudosystemctl stop libvirtd.service>sudosystemctl enable --now libvirtd-tls.socket>sudosystemctl start libvirtd.service
默认情况下,libvirt 使用 TCP 端口 16514 来接受安全的 TLS 连接。在防火墙中打开此端口。
libvirtd如果您为 libvirt 启用 TLS,则服务器证书需要就位,否则重新启动 libvirtd 将失败。如果您更改了证书,也需要重新启动 libvirtd。
客户端是启动连接的机器。因此,需要安装客户端证书。还需要安装 CA 证书。
创建客户端证书并将其与相应的 CA 证书一起导出。
在客户端上创建以下目录
>sudomkdir -p /etc/pki/CA/ /etc/pki/libvirt/private/
按如下方式安装证书
>sudo/etc/pki/CA/cacert.pem>sudo/etc/pki/libvirt/clientcert.pem>sudo/etc/pki/libvirt/private/clientkey.pem
通过发出以下命令来测试客户端/服务器设置。将 mercury.example.com 替换为您的 VM 主机服务器的名称。指定在创建服务器证书时使用的完全限定主机名。
#QEMU/KVM virsh -c qemu+tls://mercury.example.com/system list --all #Xen virsh -c xen+tls://mercury.example.com/system list --all
如果您的设置正确,您将看到注册到 VM 主机服务器上的 libvirt 的所有 VM 客户机的列表。
目前,只有少数工具支持通过 TLS 进行 VNC 通信。诸如 tightvnc 或 tigervnc 之类的常用 VNC 查看器不支持 TLS/SSL。支持的替代方案只有 Virtual Machine Manager 和 virt-viewer,以及 remmina(请参阅“参考”手册,第 4 章“使用 VNC 进行远程图形会话”,第 4.2 节“Remmina:远程桌面客户端”)。
要通过 VNC over TLS/SSL 访问图形控制台,需要按如下方式配置 VM 主机服务器
在防火墙中为服务 VNC 打开端口。
创建目录 /etc/pki/libvirt-vnc 并按如下方式将证书链接到此目录
>sudomkdir -p /etc/pki/libvirt-vnc && cd /etc/pki/libvirt-vnc>sudoln -s /etc/pki/CA/cacert.pem ca-cert.pem>sudoln -s /etc/pki/libvirt/servercert.pem server-cert.pem>sudoln -s /etc/pki/libvirt/private/serverkey.pem server-key.pem
编辑 /etc/libvirt/qemu.conf 并设置以下参数
vnc_listen = "0.0.0.0"
vnc_tls = 1
vnc_tls_x509_verify = 1重新启动 libvirtd
>sudosystemctl restart libvirtd
仅在启动 VM 客户机时才设置 VNC TLS 设置。因此,您需要重新启动所有在进行配置更改之前一直在运行的机器。
客户端唯一需要执行的操作是将 x509 客户端证书放置在客户端所选客户端识别的位置。但是,Virtual Machine Manager 和 virt-viewer 期望证书位于不同的位置。Virtual Machine Manager 可以从适用于所有用户的系统范围位置读取,也可以从每个用户的特定位置读取。Remmina(请参阅“参考”手册,第 4 章“使用 VNC 进行远程图形会话”,第 4.2 节“Remmina:远程桌面客户端”)在初始化到远程 VNC 会话的连接时会询问证书的位置。
virt-manager)要连接到远程主机,Virtual Machine Manager 需要在第 11.3.2.3 节,“配置客户端并测试设置”中解释的设置。要能够通过 VNC 连接,客户端证书也需要放置在以下位置
/etc/pki/CA/cacert.pem |
/etc/pki/libvirt-vnc/clientcert.pem |
/etc/pki/libvirt-vnc/private/clientkey.pem |
/etc/pki/CA/cacert.pem |
~/.pki/libvirt-vnc/clientcert.pem |
~/.pki/libvirt-vnc/private/clientkey.pem |
virt-viewer
virt-viewer 仅接受来自系统范围位置的证书
/etc/pki/CA/cacert.pem |
/etc/pki/libvirt-vnc/clientcert.pem |
/etc/pki/libvirt-vnc/private/clientkey.pem |
每个 x509 证书由两部分组成:公共证书和私钥。客户端只能使用这两部分进行身份验证。因此,任何具有客户端证书及其私钥读取权限的用户都可以访问您的 VM 主机服务器。另一方面,配备完整服务器证书的任意机器可以假装是 VM 主机服务器。由于这不可取,因此至少需要尽可能地限制对私钥文件的访问。控制密钥文件访问的最简单方法是使用访问权限。
服务器证书需要可被 QEMU 进程读取。在 openSUSE Leap 上,由 libvirt 工具启动的 QEMU 进程由 root 拥有,因此如果 root 可以读取证书就足够了
>chmod 700 /etc/pki/libvirt/private/>chmod 600 /etc/pki/libvirt/private/serverkey.pem
如果您在 /etc/libvirt/qemu.conf 中更改了 QEMU 进程的所有权,则还需要调整密钥文件的所有权。
要控制对系统范围内可用的密钥文件的访问,请限制对特定组的读取访问权限,以便只有该组的成员才能读取密钥文件。在以下示例中,创建了一个组 libvirt,并将 clientkey.pem 文件及其父目录的所有权设置为 libvirt。之后,将访问权限限制为所有者和组。最后,将用户 tux 添加到组 libvirt,从而可以访问密钥文件。
CERTPATH="/etc/pki/libvirt/" # create group libvirt groupadd libvirt # change ownership to user root and group libvirt chown root.libvirt $CERTPATH/private $CERTPATH/clientkey.pem # restrict permissions chmod 750 $CERTPATH/private chmod 640 $CERTPATH/private/clientkey.pem # add user tux to group libvirt usermod --append --groups libvirt tux
用于通过 VNC 访问 VM 客户机图形控制台的用户特定客户端证书需要放置在用户的主目录中的 ~/.pki 中。与 SSH 不同,例如,使用这些证书的 VNC 查看器不会检查私钥文件的访问权限。因此,用户有责任确保其他人无法读取密钥文件。
默认情况下,配备了适当客户端证书的每个客户端都可以连接到接受 TLS 连接的 VM 主机服务器。因此,可以使用 SASL 进行额外的服务器端身份验证,如第 11.1.1.3 节,“使用 SASL 进行用户名和密码身份验证”中所述。
也可以使用 DN(专有名称)的允许列表来限制访问,以便只有证书与列表中的 DN 匹配的客户端才能连接。
将允许的 DN 列表添加到 /etc/libvirt/libvirtd.conf 中的 tls_allowed_dn_list。此列表可以包含通配符。不要指定空列表,因为这会导致拒绝所有连接。
tls_allowed_dn_list = [ "C=US,L=Provo,O=SUSE Linux Products GmbH,OU=*,CN=venus.example.com,EMAIL=*", "C=DE,L=Nuremberg,O=SUSE Linux Products GmbH,OU=Documentation,CN=*"]
使用以下命令获取证书的专有名称
> certtool -i --infile /etc/pki/libvirt/clientcert.pem | grep "Subject:"更改配置后重新启动 libvirtd
>sudosystemctl restart libvirtd
无法通过 TLS 进行直接用户身份验证——这间接通过证书的读取权限在每个客户端上处理,如第 11.3.2.5 节,“限制访问(安全注意事项)”中所述。但是,如果需要基于服务器的集中用户身份验证,libvirt 还允许在 TLS 之上使用 SASL(简单身份验证和安全层)进行直接用户身份验证。有关配置详细信息,请参阅第 11.1.1.3 节,“使用 SASL 进行用户名和密码身份验证”。
请按以下顺序检查以下内容
| 是防火墙问题吗(服务器上需要打开 TCP 端口 16514)? |
启动 Virtual Machine Manager/virsh 的用户是否可以读取客户端证书(证书和密钥)? |
| 连接中是否指定了服务器证书中的完全限定主机名? |
服务器上是否启用了 TLS(listen_tls = 1)? |
服务器上的 libvirtd 是否已重新启动? |