[QEMU]通用对象创建(2)

-object cryptodev-vhost-user,id=id,chardev=chardevid[,queues=queues]
创建一个 vhost-user cryptodev 后端,由 chardev chardevid 提供支持。id 参数是一个唯一的 ID,将用于从设备引用此 cryptodev 后端。chardev 应该是一个 unix 域套接字支持的。vhost 用户使用专门定义的协议将 vhost ioctl 替换消息传递到套接字另一端的应用程序。queues 参数是可选的,用于指定多队列 vhost-user 的 cryptodev 后端的队列编号,队列的默认值为 1。
virtio-crypto
# qemu-system-x86_64 \ [...] \ -chardev socket,id=chardev0,path=/path/to/socket \ -object cryptodev-vhost-user,id=cryptodev0,chardev=chardev0 \ -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \ [...]
-object secret,id=id,data=string,format=raw|base64[,keyid=secretid,iv=string]
-object secret,id=id,file=filename,format=raw|base64[,keyid=secretid,iv=string]
定义用于存储密码、加密密钥或某些其他敏感数据的机密。敏感数据可以通过 data 参数直接传递,也可以通过 file 参数间接传递。除非对敏感数据进行加密,否则使用 data 参数是不安全的。
敏感数据可以以原始格式(默认值)或 base64 提供。编码为 JSON 时,原始格式仅支持有效的 UTF-8 字符,因此建议使用 base64 发送二进制数据。QEMU将从提供的任何格式转换为内部所需的格式。例如,RBD密码可以原始格式提供,即使它在传递到RBD服务器时将被base64编码。
为了增加保护,可以使用AES-256-CBC密码加密与密钥关联的数据。通过提供 keyid 和 iv 参数来指示加密的使用。keyid 参数提供以前定义的包含 AES-256 解密密钥的机密的 ID。此密钥的长度应为 32 个字节,并采用 base64 编码。iv 参数提供用于加密此特定机密的随机初始化向量,并且应该是 16 字节 IV 的 base64 加密字符串。
最简单的(不安全的)用法是提供秘密内联
# qemu-system-x86_64 -object secret,id=sec0,data=letmein,format=raw
最简单的安全用法是通过文件提供密钥
# printf “letmein” > mypasswd.txt # QEMU_SYSTEM_MACRO -object secret,id=sec0,file=mypasswd.txt,format=raw
为了提高安全性,应使用 AES-256-CBC。为了说明用法,请考虑可以加密数据的openssl命令行工具。请注意,加密时,必须使用标准 PKCS#5/6 兼容填充算法将纯文本填充到密码块大小(32 个字节)。
首先,需要以 base64 编码创建主密钥:
# openssl rand -base64 32 > key.b64# KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"')
每个要加密的密钥都需要生成一个随机初始化向量。这些不需要保密
# openssl rand -base64 16 > iv.b64# IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"')
要定义的秘密现在可以加密,在这种情况下,我们告诉openssl对结果进行base64编码,但如果需要,它可以保留为原始字节。
# SECRET=$(printf "letmein" | openssl enc -aes-256-cbc -a -K $KEY -iv $IV)
启动 QEMU 时,创建指向的主密钥并指定用于解密用户密码的主密钥。将 的内容传递给第二个密钥
key.b64
iv.b64
# qemu-system-x86_64 \ -object secret,id=secmaster0,format=base64,file=key.b64 \ -object secret,id=sec0,keyid=secmaster0,format=base64,\ data=$SECRET,iv=$(<iv.b64)
-object sev-guest,id=id,cbitpos=cbitpos,reduced-phys-bits=val,[sev-device=string,policy=policy,handle=handle,dh-cert-file=file,session-file=file,kernel-hashes=on|off]
创建安全加密虚拟化 (SEV) 来宾对象,该对象可用于在 AMD 处理器上提供来宾内存加密支持。
启用内存加密后,将使用其中一个物理地址位(也称为 C 位)来标记内存页是否受到保护。用于提供 C 位位置。C 位位置取决于主机系列,因此用户必须提供此值。在 EPYC 上,该值应为 47。
cbitpos
启用内存加密后,我们会丢失物理地址空间中的某些位。用于提供我们在物理地址空间中丢失的位数。与 C 位类似,该值取决于主机系列。在 EPYC 上,该值应为 5。
reduced-phys-bits
提供用于与 AMD 安全处理器内运行的 SEV 固件进行通信的设备文件。默认设备为“/dev/sev”。如果硬件支持内存加密,则 /dev/sev 设备由 CCP 驱动程序创建。
sev-device
提供要由 SEV 固件强制执行的来宾策略,并限制虚拟机管理程序可以对此来宾执行的配置和操作命令。该政策应由客人所有者提供,并绑定到客人,并且在客人的整个生命周期内不得更改。默认值为 0。
policy
如果来宾允许与另一个 SEV 来宾共享密钥,则可以使用该来宾提供从中共享密钥的来宾的句柄。
policy
handle
和 提供在 SEV 规范中定义的来宾所有者的公共 Diffie-Hillman 密钥。PDH 和会话参数用于与客户机所有者建立加密会话,以协商用于证明的密钥。该文件必须以 base64 编码。
dh-cert-file
session-file
将给定内核/initrd/cmdline 的哈希值添加到指定的来宾固件页面,以便使用 -kernel 进行测量 Linux 引导。默认值为关闭。(自 6.2 起)
kernel-hashes
例如,启动SEV访客
# qemu-system-x86_64 \ ...... \ -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=5 \ -machine ...,memory-encryption=sev0 \ .....
-object authz-simple,id=id,identity=string
创建将控制对网络服务的访问的授权对象。
该参数标识用户,其格式取决于与授权对象关联的网络服务。对于基于 TLS x509 证书的授权,标识必须是 x509 可分辨名称。请注意,必须注意对可分辨名称中的任何逗号进行转义。
identity
用于验证 x509 可分辨名称的示例授权对象如下所示:
# qemu-system-x86_64 \ ... \ -object 'authz-simple,id=auth0,identity=CN=laptop.example.com,,O=Example Org,,L=London,,ST=London,,C=GB' \ ...
请注意,由于 x509 可分辨名称包含空格,并且转义了 ',',,因此使用引号。
-object authz-listfile,id=id,filename=path,refresh=on|off
创建将控制对网络服务的访问的授权对象。
该参数是包含 JSON 格式的访问控制列表规则的文件的完全限定路径。
filename
与 SASL 用户名匹配的一组规则示例可能如下所示:
{ "rules": [ { "match": "fred", "policy": "allow", "format": "exact" }, { "match": "bob", "policy": "allow", "format": "exact" }, { "match": "danb", "policy": "deny", "format": "glob" }, { "match": "dan*", "policy": "allow", "format": "exact" }, ], "policy": "deny"}
选中访问权限时,对象将循环访问所有规则,并且要匹配的第一个规则将返回其值作为结果。如果没有匹配的规则,则返回默认值。
policy
policy
这些规则可以是完全字符串匹配,也可以使用简单的 UNIX glob 模式匹配来允许使用通配符。
如果设置为 true,则将监视文件,并在其内容更改时自动重新加载。
refresh
与对象一样,要匹配的标识字符串的格式取决于网络服务,但通常是 TLS x509 可分辨名称或 SASL 用户名。
authz-simple
用于验证 SASL 用户名的示例授权对象如下所示:
# qemu-system-x86_64 \ ... \ -object authz-simple,id=auth0,filename=/etc/qemu/vnc-sasl.acl,refresh=on \ ...
-object authz-pam,id=id,service=string
创建将控制对网络服务的访问的授权对象。
该参数提供用于授权的 PAM 服务的名称。它要求存在一个文件来提供子系统的配置。
service
/etc/pam.d/service
account
用于验证 TLS x509 可分辨名称的示例授权对象如下所示:
# qemu-system-x86_64 \ ... \ -object authz-pam,id=auth0,service=qemu-vnc \ ...
然后会有一个相应的 PAM 配置文件,其中包含:
/etc/pam.d/qemu-vnc
account requisite pam_listfile.so item=user sense=allow \ file=/etc/qemu/vnc.allow
最后,该文件将包含允许访问的 x509 分离名称的列表
/etc/qemu/vnc.allow
CN=laptop.example.com,O=Example Home,L=London,ST=London,C=GB
-object iothread,id=id,poll-max-ns=poll-max-ns,poll-grow=poll-grow,poll-shrink=poll-shrink,aio-max-batch=aio-max-batch
创建可将设备分配到的专用事件循环线程。这称为 IOThread。默认情况下,设备仿真发生在 vCPU 线程或主事件循环线程中。这可能会成为可伸缩性瓶颈。IOThread 允许设备仿真和 I/O 在其他主机 CPU 上运行。
该参数是一个唯一的 ID,将用于从 中引用此 IOThread。可以将多个设备分配给一个 IOThread。请注意,并非所有设备都支持某个参数。
id
-device ...,iothread=id
iothread
QMP 命令列出 IOThread 并报告其线程 ID,以便用户可以配置主机 CPU 固定/关联。
query-iothreads
IOThreads 使用自适应轮询算法来减少事件循环延迟。轮询算法不是输入阻塞系统调用来监视文件描述符,然后在事件发生时支付被唤醒的成本,而是在短时间内等待事件。该算法的默认参数适用于许多情况,但可以根据工作负载和/或主机设备延迟的了解进行调整。
该参数是忙于等待事件的最大纳秒数。可以通过将此值设置为 0 来禁用轮询。
poll-max-ns
该参数是用于在算法检测到由于轮询时间不够长而缺少事件时增加轮询时间的乘数。
poll-grow
该参数是除数,用于在算法检测到轮询时间过长而没有遇到事件时减少轮询时间。
poll-shrink
该参数是 AIO 引擎批处理中的最大请求数,0 表示引擎将使用其默认值。
aio-max-batch
可以在运行时使用以下命令修改 IOThread 参数(其中 IOThread 的参数为):
qom-set
iothread1
id
(qemu) qom-set /objects/iothread1 poll-max-ns 100000