qemu: implement password auth for ssh disks with nbdkit

For ssh disks that are served by nbdkit, lookup the password from the
configured secret and securely pass it to the nbdkit process using fd
passing.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Jonathon Jongsma 2022-12-21 15:42:02 -06:00
parent cf88b13090
commit 36f591402f
9 changed files with 134 additions and 39 deletions

View File

@ -950,6 +950,43 @@ qemuNbdkitCommandPassDataByPipe(virCommand *cmd,
}
static int
qemuNbdkitProcessBuildCommandAuth(virStorageAuthDef *authdef,
virCommand *cmd)
{
g_autoptr(virConnect) conn = NULL;
g_autofree uint8_t *secret = NULL;
size_t secretlen = 0;
int secrettype;
if (!authdef)
return 0;
if ((secrettype = virSecretUsageTypeFromString(authdef->secrettype)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid secret type %1$s"),
authdef->secrettype);
return -1;
}
conn = virGetConnectSecret();
if (virSecretGetSecretString(conn,
&authdef->seclookupdef,
secrettype,
&secret,
&secretlen) < 0)
return -1;
virCommandAddArgPair(cmd, "user", authdef->username);
if (qemuNbdkitCommandPassDataByPipe(cmd, "password",
&secret, secretlen) < 0)
return -1;
return 0;
}
static int
qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
virCommand *cmd)
@ -968,37 +1005,8 @@ qemuNbdkitProcessBuildCommandCurl(qemuNbdkitProcess *proc,
}
virCommandAddArgPair(cmd, "url", uristring);
if (proc->source->auth) {
g_autoptr(virConnect) conn = virGetConnectSecret();
g_autofree uint8_t *secret = NULL;
size_t secretlen = 0;
int secrettype;
virStorageAuthDef *authdef = proc->source->auth;
virCommandAddArgPair(cmd, "user",
proc->source->auth->username);
if ((secrettype = virSecretUsageTypeFromString(proc->source->auth->secrettype)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid secret type %1$s"),
proc->source->auth->secrettype);
return -1;
}
if (virSecretGetSecretString(conn,
&authdef->seclookupdef,
secrettype,
&secret,
&secretlen) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to get auth secret for storage"));
return -1;
}
if (qemuNbdkitCommandPassDataByPipe(cmd, "password",
&secret, secretlen) < 0)
return -1;
}
if (proc->source->auth && qemuNbdkitProcessBuildCommandAuth(proc->source->auth, cmd) < 0)
return -1;
/* Create a pipe to send the cookies to the nbdkit process. */
if (proc->source->ncookies) {
@ -1027,7 +1035,6 @@ static int
qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
virCommand *cmd)
{
const char *user = NULL;
virStorageNetHostDef *host = &proc->source->hosts[0];
g_autofree char *portstr = g_strdup_printf("%u", host->port);
@ -1038,13 +1045,12 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
virCommandAddArgPair(cmd, "port", portstr);
virCommandAddArgPair(cmd, "path", proc->source->path);
if (proc->source->auth)
user = proc->source->auth->username;
else if (proc->source->ssh_user)
user = proc->source->ssh_user;
if (user)
virCommandAddArgPair(cmd, "user", user);
if (proc->source->auth) {
if (qemuNbdkitProcessBuildCommandAuth(proc->source->auth, cmd) < 0)
return -1;
} else if (proc->source->ssh_user) {
virCommandAddArgPair(cmd, "user", proc->source->ssh_user);
}
if (proc->source->ssh_host_key_check_disabled)
virCommandAddArgPair(cmd, "verify-remote-host", "false");

View File

@ -0,0 +1,8 @@
nbdkit \
--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
--foreground ssh \
host=example.org \
port=2222 \
path=test2.img \
user=testuser \
password=-777

View File

@ -0,0 +1 @@
iscsi-mycluster_myname-secret

View File

@ -0,0 +1,8 @@
nbdkit \
--unix /tmp/statedir-1/nbdkit-test-disk-1.socket \
--foreground ssh \
host=example.org \
port=2222 \
path=test2.img \
user=testuser \
password=-777

View File

@ -0,0 +1 @@
iscsi-mycluster_myname-secret

View File

@ -298,6 +298,7 @@ mymain(void)
DO_TEST("disk-network-source-curl-nbdkit-backing", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
DO_TEST("disk-network-source-curl", QEMU_NBDKIT_CAPS_PLUGIN_CURL);
DO_TEST("disk-network-ssh", QEMU_NBDKIT_CAPS_PLUGIN_SSH);
DO_TEST("disk-network-ssh-password", QEMU_NBDKIT_CAPS_PLUGIN_SSH);
cleanup:
qemuTestDriverFree(&driver);

View File

@ -0,0 +1,35 @@
LC_ALL=C \
PATH=/bin \
HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \
USER=test \
LOGNAME=test \
XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \
XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \
XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
/usr/bin/qemu-system-x86_64 \
-name guest=QEMUGuest1,debug-threads=on \
-S \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
-accel kvm \
-cpu qemu64 \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
-smp 1,sockets=1,cores=1,threads=1 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
-display none \
-no-user-config \
-nodefaults \
-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
-mon chardev=charmonitor,id=monitor,mode=control \
-rtc base=utc \
-no-shutdown \
-boot strict=on \
-device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \
-blockdev '{"driver":"nbd","server":{"type":"unix","path":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/nbdkit-libvirt-1-storage.socket"},"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \
-device '{"driver":"virtio-blk-pci","bus":"pci.0","addr":"0x2","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1}' \
-audiodev '{"id":"audio1","driver":"none"}' \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on

View File

@ -0,0 +1,34 @@
<domain type='kvm'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<disk type='network' device='disk'>
<driver name='qemu' type='raw'/>
<source protocol='ssh' name='test2.img'>
<host name='example.org' port='2222'/>
<timeout seconds='1234'/>
<readahead size='1024'/>
<auth username='testuser'>
<secret type='iscsi' usage='mycluster_myname'/>
</auth>
</source>
<target dev='vda' bus='virtio'/>
</disk>
<controller type='usb' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='none'/>
</devices>
</domain>

View File

@ -1178,6 +1178,7 @@ mymain(void)
driver.config->vxhsTLS = 0;
DO_TEST_CAPS_LATEST("disk-network-ssh");
DO_TEST_CAPS_LATEST_NBDKIT("disk-network-ssh-nbdkit", QEMU_NBDKIT_CAPS_PLUGIN_SSH);
DO_TEST_CAPS_LATEST_NBDKIT("disk-network-ssh-password", QEMU_NBDKIT_CAPS_PLUGIN_SSH);
DO_TEST_CAPS_LATEST("disk-no-boot");
DO_TEST_CAPS_LATEST("disk-nvme");
DO_TEST_CAPS_VER("disk-vhostuser-numa", "4.2.0");