mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
qemu: implement ssh-agent auth for ssh disks with nbdkit
It's not possible to use password-protected ssh keys directly with libvirt because libvirt doesn't have any way to prompt a user for the password. To accomodate password-protected key files, an administrator can add these keys to an ssh agent and then configure the domain with the path to the ssh-agent socket. Note that this requires an administrator or management app to configure the ssh-agent with an appropriate socket path and add the necessary keys to it. In addition, it does not currently work with selinux enabled. The ssh-agent socket would need a label that libvirt would be allowed to access rather than unconfined_t. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
1195403c43
commit
3310b12d52
@ -7228,8 +7228,17 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
|
||||
if (!(src->ssh_user = virXMLPropStringRequired(tmpnode, "username")))
|
||||
return -1;
|
||||
|
||||
if (!(src->ssh_keyfile = virXMLPropStringRequired(tmpnode, "keyfile")))
|
||||
/* optional path to an ssh key file */
|
||||
src->ssh_keyfile = virXMLPropString(tmpnode, "keyfile");
|
||||
|
||||
/* optional ssh-agent socket location */
|
||||
src->ssh_agent = virXMLPropString(tmpnode, "agentsock");
|
||||
if (!src->ssh_keyfile && !src->ssh_agent) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("element '%1$s' requires either 'keyfile' or 'agentsock' attribute"),
|
||||
tmpnode->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22222,11 +22231,12 @@ virDomainDiskSourceFormatNetwork(virBuffer *attrBuf,
|
||||
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_SSH) {
|
||||
if (src->ssh_known_hosts_file)
|
||||
virBufferEscapeString(childBuf, "<knownHosts path='%s'/>\n", src->ssh_known_hosts_file);
|
||||
if (src->ssh_keyfile) {
|
||||
if (src->ssh_keyfile || src->ssh_agent) {
|
||||
virBufferAddLit(childBuf, "<identity");
|
||||
|
||||
virBufferEscapeString(childBuf, " username='%s'", src->ssh_user);
|
||||
virBufferEscapeString(childBuf, " keyfile='%s'", src->ssh_keyfile);
|
||||
virBufferEscapeString(childBuf, " agentsock='%s'", src->ssh_agent);
|
||||
|
||||
virBufferAddLit(childBuf, "/>\n");
|
||||
}
|
||||
|
@ -899,6 +899,7 @@ virStorageSourceCopy(const virStorageSource *src,
|
||||
def->ssh_user = g_strdup(src->ssh_user);
|
||||
def->ssh_known_hosts_file = g_strdup(src->ssh_known_hosts_file);
|
||||
def->ssh_keyfile = g_strdup(src->ssh_keyfile);
|
||||
def->ssh_agent = g_strdup(src->ssh_agent);
|
||||
|
||||
def->nfs_user = g_strdup(src->nfs_user);
|
||||
def->nfs_group = g_strdup(src->nfs_group);
|
||||
@ -1179,6 +1180,7 @@ virStorageSourceClear(virStorageSource *def)
|
||||
VIR_FREE(def->ssh_user);
|
||||
VIR_FREE(def->ssh_known_hosts_file);
|
||||
VIR_FREE(def->ssh_keyfile);
|
||||
VIR_FREE(def->ssh_agent);
|
||||
|
||||
VIR_FREE(def->nfs_user);
|
||||
VIR_FREE(def->nfs_group);
|
||||
|
@ -413,6 +413,7 @@ struct _virStorageSource {
|
||||
bool ssh_host_key_check_disabled;
|
||||
char *ssh_known_hosts_file;
|
||||
char *ssh_keyfile;
|
||||
char *ssh_agent;
|
||||
|
||||
/* 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
|
||||
|
@ -1057,6 +1057,9 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
|
||||
virCommandAddArgPair(cmd, "user", proc->source->ssh_user);
|
||||
}
|
||||
|
||||
if (proc->source->ssh_agent)
|
||||
virCommandAddEnvPair(cmd, "SSH_AUTH_SOCK", proc->source->ssh_agent);
|
||||
|
||||
if (proc->source->ssh_host_key_check_disabled)
|
||||
virCommandAddArgPair(cmd, "verify-remote-host", "false");
|
||||
|
||||
@ -1179,6 +1182,10 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
|
||||
qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_keyfile, false) < 0)
|
||||
goto error;
|
||||
|
||||
if (proc->source->ssh_agent &&
|
||||
qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_agent, false) < 0)
|
||||
goto error;
|
||||
|
||||
if (proc->source->ssh_known_hosts_file &&
|
||||
qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_known_hosts_file, false) < 0)
|
||||
goto error;
|
||||
@ -1267,6 +1274,9 @@ qemuNbdkitProcessStop(qemuNbdkitProcess *proc,
|
||||
if (proc->source->ssh_keyfile)
|
||||
qemuSecurityDomainRestorePathLabel(driver, vm, proc->source->ssh_keyfile);
|
||||
|
||||
if (proc->source->ssh_agent)
|
||||
qemuSecurityDomainRestorePathLabel(driver, vm, proc->source->ssh_agent);
|
||||
|
||||
if (proc->pid < 0)
|
||||
return 0;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
SSH_AUTH_SOCK=/path/to/agent/socket \
|
||||
nbdkit \
|
||||
--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
|
||||
--foreground ssh \
|
||||
host=example.org \
|
||||
port=2222 \
|
||||
path=test.img \
|
||||
identity=/path/to/id_rsa \
|
||||
path=test1.img \
|
||||
user=myuser \
|
||||
known-hosts=/path/to/ssh_known_hosts
|
||||
known-hosts=/path/to/ssh_known_hosts1
|
||||
|
9
tests/qemunbdkitdata/disk-network-ssh-key.args.disk1
Normal file
9
tests/qemunbdkitdata/disk-network-ssh-key.args.disk1
Normal file
@ -0,0 +1,9 @@
|
||||
nbdkit \
|
||||
--unix /tmp/statedir-1/nbdkit-test-disk-1.socket \
|
||||
--foreground ssh \
|
||||
host=example.org \
|
||||
port=2222 \
|
||||
path=test2.img \
|
||||
identity=/path/to/id_rsa \
|
||||
user=myuser2 \
|
||||
known-hosts=/path/to/ssh_known_hosts2
|
@ -15,12 +15,23 @@
|
||||
<devices>
|
||||
<disk type='network' device='disk'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source protocol='ssh' name='test.img'>
|
||||
<source protocol='ssh' name='test1.img'>
|
||||
<host name='example.org' port='2222'/>
|
||||
<timeout seconds='1234'/>
|
||||
<readahead size='1024'/>
|
||||
<identity username='myuser' keyfile='/path/to/id_rsa'/>
|
||||
<knownHosts path="/path/to/ssh_known_hosts"/>
|
||||
<identity username='myuser' agentsock='/path/to/agent/socket'/>
|
||||
<knownHosts path="/path/to/ssh_known_hosts1"/>
|
||||
</source>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
<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'/>
|
||||
<identity username='myuser2' keyfile='/path/to/id_rsa'/>
|
||||
<knownHosts path="/path/to/ssh_known_hosts2"/>
|
||||
</source>
|
||||
<target dev='vda' bus='virtio'/>
|
||||
</disk>
|
||||
|
Loading…
Reference in New Issue
Block a user