qemu: implement knownHosts for ssh disks with nbdkit

For ssh disks that are served by nbdkit, use the configured value for
knownHosts and pass it to the nbdkit process.

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Jonathon Jongsma 2022-12-22 13:04:51 -06:00
parent e234fd5110
commit 21b377a31b
11 changed files with 46 additions and 13 deletions

View File

@ -7219,6 +7219,11 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
return -1; return -1;
} }
} }
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_SSH &&
(tmpnode = virXPathNode("./knownHosts", ctxt))) {
if (!(src->ssh_known_hosts_file = virXMLPropStringRequired(tmpnode, "path")))
return -1;
}
return 0; return 0;
} }
@ -22205,6 +22210,9 @@ virDomainDiskSourceFormatNetwork(virBuffer *attrBuf,
if (src->timeout) if (src->timeout)
virBufferAsprintf(childBuf, "<timeout seconds='%llu'/>\n", src->timeout); virBufferAsprintf(childBuf, "<timeout seconds='%llu'/>\n", src->timeout);
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_SSH && src->ssh_known_hosts_file)
virBufferEscapeString(childBuf, "<knownHosts path='%s'/>\n", src->ssh_known_hosts_file);
} }

View File

@ -897,6 +897,7 @@ virStorageSourceCopy(const virStorageSource *src,
/* ssh config passthrough for libguestfs */ /* ssh config passthrough for libguestfs */
def->ssh_host_key_check_disabled = src->ssh_host_key_check_disabled; def->ssh_host_key_check_disabled = src->ssh_host_key_check_disabled;
def->ssh_user = g_strdup(src->ssh_user); def->ssh_user = g_strdup(src->ssh_user);
def->ssh_known_hosts_file = g_strdup(src->ssh_known_hosts_file);
def->nfs_user = g_strdup(src->nfs_user); def->nfs_user = g_strdup(src->nfs_user);
def->nfs_group = g_strdup(src->nfs_group); def->nfs_group = g_strdup(src->nfs_group);
@ -1175,6 +1176,7 @@ virStorageSourceClear(virStorageSource *def)
VIR_FREE(def->tlsHostname); VIR_FREE(def->tlsHostname);
VIR_FREE(def->ssh_user); VIR_FREE(def->ssh_user);
VIR_FREE(def->ssh_known_hosts_file);
VIR_FREE(def->nfs_user); VIR_FREE(def->nfs_user);
VIR_FREE(def->nfs_group); VIR_FREE(def->nfs_group);

View File

@ -412,6 +412,8 @@ struct _virStorageSource {
/* these must not be used apart from formatting the output JSON in the qemu driver */ /* these must not be used apart from formatting the output JSON in the qemu driver */
char *ssh_user; char *ssh_user;
bool ssh_host_key_check_disabled; bool ssh_host_key_check_disabled;
/* additional ssh variables */
char *ssh_known_hosts_file;
/* nfs_user and nfs_group store the strings passed in by the user for NFS params. /* nfs_user and nfs_group store the strings passed in by the user for NFS params.
* nfs_uid and nfs_gid represent the converted/looked up ID numbers which are used * nfs_uid and nfs_gid represent the converted/looked up ID numbers which are used

View File

@ -297,11 +297,11 @@ qemuExtDevicesStop(virQEMUDriver *driver,
for (i = 0; i < def->ndisks; i++) { for (i = 0; i < def->ndisks; i++) {
virDomainDiskDef *disk = def->disks[i]; virDomainDiskDef *disk = def->disks[i];
qemuNbdkitStopStorageSource(disk->src); qemuNbdkitStopStorageSource(disk->src, vm);
} }
if (def->os.loader && def->os.loader->nvram) if (def->os.loader && def->os.loader->nvram)
qemuNbdkitStopStorageSource(def->os.loader->nvram); qemuNbdkitStopStorageSource(def->os.loader->nvram, vm);
} }

View File

@ -1036,7 +1036,7 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver,
if (virStorageSourceChainHasManagedPR(disk->src)) if (virStorageSourceChainHasManagedPR(disk->src))
ignore_value(qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE)); ignore_value(qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE));
qemuNbdkitStopStorageSource(disk->src); qemuNbdkitStopStorageSource(disk->src, vm);
} }
qemuDomainSecretDiskDestroy(disk); qemuDomainSecretDiskDestroy(disk);
qemuDomainCleanupStorageSourceFD(disk->src); qemuDomainCleanupStorageSourceFD(disk->src);
@ -4497,7 +4497,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE) < 0) qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE) < 0)
goto cleanup; goto cleanup;
qemuNbdkitStopStorageSource(disk->src); qemuNbdkitStopStorageSource(disk->src, vm);
if (disk->transient) { if (disk->transient) {
VIR_DEBUG("Removing transient overlay '%s' of disk '%s'", VIR_DEBUG("Removing transient overlay '%s' of disk '%s'",

View File

@ -630,7 +630,7 @@ qemuNbdkitProcessRestart(qemuNbdkitProcess *proc,
virQEMUDriver *driver = vmpriv->driver; virQEMUDriver *driver = vmpriv->driver;
/* clean up resources associated with process */ /* clean up resources associated with process */
qemuNbdkitProcessStop(proc); qemuNbdkitProcessStop(proc, vm);
return qemuNbdkitProcessStart(proc, vm, driver); return qemuNbdkitProcessStart(proc, vm, driver);
} }
@ -913,7 +913,8 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
void void
qemuNbdkitStopStorageSource(virStorageSource *src) qemuNbdkitStopStorageSource(virStorageSource *src,
virDomainObj *vm)
{ {
virStorageSource *backing; virStorageSource *backing;
@ -921,7 +922,7 @@ qemuNbdkitStopStorageSource(virStorageSource *src)
qemuDomainStorageSourcePrivate *priv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); qemuDomainStorageSourcePrivate *priv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
if (priv && priv->nbdkitProcess && if (priv && priv->nbdkitProcess &&
qemuNbdkitProcessStop(priv->nbdkitProcess) < 0) qemuNbdkitProcessStop(priv->nbdkitProcess, vm) < 0)
VIR_WARN("Unable to stop nbdkit for storage source '%s'", src->nodestorage); VIR_WARN("Unable to stop nbdkit for storage source '%s'", src->nodestorage);
} }
} }
@ -1055,6 +1056,9 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
if (proc->source->ssh_host_key_check_disabled) if (proc->source->ssh_host_key_check_disabled)
virCommandAddArgPair(cmd, "verify-remote-host", "false"); virCommandAddArgPair(cmd, "verify-remote-host", "false");
if (proc->source->ssh_known_hosts_file)
virCommandAddArgPair(cmd, "known-hosts", proc->source->ssh_known_hosts_file);
return 0; return 0;
} }
@ -1167,6 +1171,10 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
if (qemuExtDeviceLogCommand(driver, vm, cmd, "nbdkit") < 0) if (qemuExtDeviceLogCommand(driver, vm, cmd, "nbdkit") < 0)
goto error; goto error;
if (proc->source->ssh_known_hosts_file &&
qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_known_hosts_file, false) < 0)
goto error;
if (qemuSecurityCommandRun(driver, vm, cmd, proc->user, proc->group, true, &exitstatus) < 0) if (qemuSecurityCommandRun(driver, vm, cmd, proc->user, proc->group, true, &exitstatus) < 0)
goto error; goto error;
@ -1231,16 +1239,23 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
NULLSTR(uristring), NULLSTR(errbuf)); NULLSTR(uristring), NULLSTR(errbuf));
error: error:
qemuNbdkitProcessStop(proc); qemuNbdkitProcessStop(proc, vm);
return -1; return -1;
} }
int int
qemuNbdkitProcessStop(qemuNbdkitProcess *proc) qemuNbdkitProcessStop(qemuNbdkitProcess *proc,
virDomainObj *vm)
{ {
qemuDomainObjPrivate *vmpriv = vm->privateData;
virQEMUDriver *driver = vmpriv->driver;
qemuNbdkitProcessStopMonitor(proc); qemuNbdkitProcessStopMonitor(proc);
if (proc->source->ssh_known_hosts_file)
qemuSecurityDomainRestorePathLabel(driver, vm, proc->source->ssh_known_hosts_file);
if (proc->pid < 0) if (proc->pid < 0)
return 0; return 0;

View File

@ -66,7 +66,8 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
virStorageSource *src); virStorageSource *src);
void void
qemuNbdkitStopStorageSource(virStorageSource *src); qemuNbdkitStopStorageSource(virStorageSource *src,
virDomainObj *vm);
int int
qemuNbdkitStorageSourceManageProcess(virStorageSource *src, qemuNbdkitStorageSourceManageProcess(virStorageSource *src,
@ -105,7 +106,8 @@ qemuNbdkitProcessRestart(qemuNbdkitProcess *proc,
virDomainObj *vm); virDomainObj *vm);
int int
qemuNbdkitProcessStop(qemuNbdkitProcess *proc); qemuNbdkitProcessStop(qemuNbdkitProcess *proc,
virDomainObj *vm);
void void
qemuNbdkitProcessFree(qemuNbdkitProcess *proc); qemuNbdkitProcessFree(qemuNbdkitProcess *proc);

View File

@ -5,4 +5,5 @@ host=example.org \
port=2222 \ port=2222 \
path=test2.img \ path=test2.img \
user=testuser \ user=testuser \
password=-777 password=-777 \
known-hosts=/path/to/knownhosts

View File

@ -3,4 +3,5 @@ nbdkit \
--foreground ssh \ --foreground ssh \
host=example.org \ host=example.org \
port=2222 \ port=2222 \
path=test.img path=test.img \
known-hosts=/path/to/ssh_known_hosts

View File

@ -22,6 +22,7 @@
<auth username='testuser'> <auth username='testuser'>
<secret type='iscsi' usage='mycluster_myname'/> <secret type='iscsi' usage='mycluster_myname'/>
</auth> </auth>
<knownHosts path='/path/to/knownhosts'/>
</source> </source>
<target dev='vda' bus='virtio'/> <target dev='vda' bus='virtio'/>
</disk> </disk>

View File

@ -19,6 +19,7 @@
<host name='example.org' port='2222'/> <host name='example.org' port='2222'/>
<timeout seconds='1234'/> <timeout seconds='1234'/>
<readahead size='1024'/> <readahead size='1024'/>
<knownHosts path="/path/to/ssh_known_hosts"/>
</source> </source>
<target dev='vda' bus='virtio'/> <target dev='vda' bus='virtio'/>
</disk> </disk>