core: Add "dispvm_netvm" property - NetVM for DispVMs started from a VM
This allows to specify tight network isolation for a VM, and finally close one remaining way for leaking traffic around TorVM. Now when VM is connected to for example TorVM, its DispVMs will be also connected there. The new property can be set to: - default (uses_default_dispvm_netvm=True) - use the same NetVM/ProxyVM as the calling VM itself - including none it that's the case - None - DispVMs will be network-isolated - some NetVM/ProxyVM - will be used, even if calling VM is network-isolated Closes qubesos/qubes-issues#862
This commit is contained in:
parent
a6448e073c
commit
7516737fae
@ -156,6 +156,8 @@ class QubesVm(object):
|
||||
"default_user": { "default": "user", "attr": "_default_user" },
|
||||
"qrexec_timeout": { "default": 60 },
|
||||
"autostart": { "default": False, "attr": "_autostart" },
|
||||
"uses_default_dispvm_netvm": {"default": True, "order": 30},
|
||||
"dispvm_netvm": {"attr": "_dispvm_netvm", "default": None},
|
||||
"backup_content" : { 'default': False },
|
||||
"backup_size" : {
|
||||
"default": 0,
|
||||
@ -218,6 +220,11 @@ class QubesVm(object):
|
||||
attrs['netvm']['save'] = \
|
||||
lambda: str(self.netvm.qid) if self.netvm is not None else "none"
|
||||
attrs['netvm']['save_attr'] = "netvm_qid"
|
||||
attrs['dispvm_netvm']['save'] = \
|
||||
lambda: str(self.dispvm_netvm.qid) \
|
||||
if self.dispvm_netvm is not None \
|
||||
else "none"
|
||||
attrs['dispvm_netvm']['save_attr'] = "dispvm_netvm_qid"
|
||||
attrs['template']['save'] = \
|
||||
lambda: str(self.template.qid) if self.template else "none"
|
||||
attrs['template']['save_attr'] = "template_qid"
|
||||
@ -602,6 +609,20 @@ class QubesVm(object):
|
||||
self._internal = value
|
||||
self.post_set_attr('internal', value, oldvalue)
|
||||
|
||||
@property
|
||||
def dispvm_netvm(self):
|
||||
if self.uses_default_dispvm_netvm:
|
||||
return self.netvm
|
||||
else:
|
||||
if isinstance(self._dispvm_netvm, int):
|
||||
return self._collection[self._dispvm_netvm]
|
||||
else:
|
||||
return self._dispvm_netvm
|
||||
|
||||
@dispvm_netvm.setter
|
||||
def dispvm_netvm(self, value):
|
||||
self._dispvm_netvm = value
|
||||
|
||||
@property
|
||||
def autostart(self):
|
||||
return self._autostart
|
||||
|
@ -81,6 +81,8 @@ class QfileDaemonDvm:
|
||||
if len(sys.argv) > 5 and len(sys.argv[5]) > 0:
|
||||
assert os.path.exists(sys.argv[5]), "Invalid firewall.conf location"
|
||||
dispvm.firewall_conf = sys.argv[5]
|
||||
if vm.qid != 0:
|
||||
dispvm.netvm = vm.dispvm_netvm
|
||||
# Wait for tar to finish
|
||||
if tar_process.wait() != 0:
|
||||
sys.stderr.write('Failed to unpack saved-cows.tar')
|
||||
|
@ -46,6 +46,11 @@ netvm
|
||||
|
||||
*Notice:* when setting to ``none``, firewall will be set to block all traffic - it will be used by DispVM started from this VM. Setting back to some NetVM will _NOT_ restore previous firewall settings.
|
||||
|
||||
dispvm_netvm
|
||||
Accepted values: netvm name, ``default``, ``none``
|
||||
|
||||
Which NetVM should be used for Disposable VMs started by this one. ``default`` is to use the same NetVM as the VM itself.
|
||||
|
||||
maxmem
|
||||
Accepted values: memory size in MB
|
||||
|
||||
|
@ -42,6 +42,11 @@ def do_list(vm):
|
||||
print fmt.format ("template", vm.template.name)
|
||||
if vm.netvm is not None:
|
||||
print fmt.format ("netvm", vm.netvm.name)
|
||||
if vm.qid != 0:
|
||||
print fmt.format("dispvm_netvm", "%s%s" % (
|
||||
vm.dispvm_netvm.name if vm.dispvm_netvm
|
||||
else "none",
|
||||
" (default)" if vm.uses_default_dispvm_netvm else ""))
|
||||
print fmt.format ("updateable", vm.updateable)
|
||||
print fmt.format ("autostart", vm.autostart)
|
||||
print fmt.format ("installed_by_rpm", vm.installed_by_rpm)
|
||||
@ -219,6 +224,33 @@ def set_netvm(vms, vm, args):
|
||||
vm.netvm = netvm
|
||||
return True
|
||||
|
||||
def set_dispvm_netvm(vms, vm, args):
|
||||
if len (args) != 1:
|
||||
print >> sys.stderr, "Missing netvm name argument!"
|
||||
print >> sys.stderr, "Possible values:"
|
||||
print >> sys.stderr, "1) default (the same as VM own netvm)"
|
||||
print >> sys.stderr, "2) none"
|
||||
print >> sys.stderr, "3) <vmaname>"
|
||||
return
|
||||
|
||||
netvm = args[0]
|
||||
if netvm == "none":
|
||||
vm.netvm = None
|
||||
vm.uses_default_dispvm_netvm = False
|
||||
elif netvm == "default":
|
||||
vm.uses_default_dispvm_netvm = True
|
||||
else:
|
||||
netvm = vms.get_vm_by_name (netvm)
|
||||
if netvm is None:
|
||||
print >> sys.stderr, "A VM with the name '{0}' does not exist in the system.".format(netvm)
|
||||
return False
|
||||
if not netvm.is_netvm():
|
||||
print >> sys.stderr, "VM '{0}' is not a NetVM".format(netvm)
|
||||
return False
|
||||
vm.dispvm_netvm = netvm
|
||||
vm.uses_default_dispvm_netvm = False
|
||||
return True
|
||||
|
||||
def set_kernel(vms, vm, args):
|
||||
if len (args) != 1:
|
||||
print >> sys.stderr, "Missing kernel version argument!"
|
||||
@ -423,6 +455,7 @@ properties = {
|
||||
"pcidevs": set_pcidevs,
|
||||
"label" : set_label,
|
||||
"netvm" : set_netvm,
|
||||
"dispvm_netvm" : set_dispvm_netvm,
|
||||
"maxmem" : set_maxmem,
|
||||
"memory" : set_memory,
|
||||
"kernel" : set_kernel,
|
||||
|
Loading…
Reference in New Issue
Block a user