Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Virtual DNS for IPv6 #558

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions qubes/tests/api_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,27 +243,63 @@ def test_027_vm_property_get_all(self):
self.assertEqual(value, expected)

def test_028_vm_property_get_list(self):
self.vm.features['ipv6'] = '1'
self.vm.provides_network = True
value = self.call_mgmt_func(
b'admin.vm.property.Get',
b'test-vm1',
b'dns')
self.assertEqual(value, 'default=True type=str 10.139.1.1 10.139.1.2')
value = self.call_mgmt_func(
b'admin.vm.property.Get',
b'test-vm1',
b'dns6')
self.assertEqual(value, 'default=True type=str ')
self.vm.features['supported-feature.ipv6dns'] = '1'
value = self.call_mgmt_func(
b'admin.vm.property.Get',
b'test-vm1',
b'dns6')
self.assertEqual(value, 'default=True type=str fd09:24ef:4179::a8b:1 fd09:24ef:4179::a8b:2')

def test_029_vm_property_get_list_none(self):
self.vm.features['ipv6'] = '1'
value = self.call_mgmt_func(
b'admin.vm.property.Get',
b'test-vm1',
b'dns')
self.assertEqual(value, 'default=True type=str ')
value = self.call_mgmt_func(
b'admin.vm.property.Get',
b'test-vm1',
b'dns6')
self.assertEqual(value, 'default=True type=str ')
self.vm.features['supported-feature.ipv6dns'] = '1'
value = self.call_mgmt_func(
b'admin.vm.property.Get',
b'test-vm1',
b'dns6')
self.assertEqual(value, 'default=True type=str ')

def test_029_vm_property_get_list_default(self):
self.vm.features['ipv6'] = '1'
self.vm.provides_network = True
value = self.call_mgmt_func(
b'admin.vm.property.GetDefault',
b'test-vm1',
b'dns')
self.assertEqual(value, 'type=str 10.139.1.1 10.139.1.2')
value = self.call_mgmt_func(
b'admin.vm.property.GetDefault',
b'test-vm1',
b'dns6')
self.assertEqual(value, 'type=str ')
self.vm.features['supported-feature.ipv6dns'] = '1'
value = self.call_mgmt_func(
b'admin.vm.property.GetDefault',
b'test-vm1',
b'dns6')
self.assertEqual(value, 'type=str fd09:24ef:4179::a8b:1 fd09:24ef:4179::a8b:2')

def test_030_vm_property_set_vm(self):
netvm = self.app.add_new_vm('AppVM', label='red', name='test-net',
Expand Down
25 changes: 25 additions & 0 deletions qubes/tests/vm/qubesvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1797,19 +1797,32 @@ def test_621_qdb_vm_with_network(self, mock_qubesdb, mock_urandom,
vm.create_qdb_entries()
self.assertEqual(test_qubesdb.data, expected)

test_qubesdb.data.clear()
with self.subTest('ipv6_dns'):
template.features['supported-feature.ipv6dns'] = '1'
netvm.features['ipv6'] = True
expected['/qubes-primary-dns6'] = 'fd09:24ef:4179::a8b:1'
expected['/qubes-secondary-dns6'] = 'fd09:24ef:4179::a8b:2'
vm.create_qdb_entries()
self.assertEqual(test_qubesdb.data, expected)

test_qubesdb.data.clear()
with self.subTest('ipv6_just_appvm'):
template.features['supported-feature.ipv6dns'] = '1'
del netvm.features['ipv6']
vm.features['ipv6'] = True
expected['/qubes-ip6'] = \
qubes.config.qubes_ipv6_prefix.replace(':0000', '') + \
'::a89:3'
del expected['/qubes-gateway6']
del expected['/qubes-primary-dns6']
del expected['/qubes-secondary-dns6']
vm.create_qdb_entries()
self.assertEqual(test_qubesdb.data, expected)

test_qubesdb.data.clear()
with self.subTest('proxy_ipv4'):
del template.features['supported-feature.ipv6dns']
del vm.features['ipv6']
expected['/name'] = 'test-inst-netvm'
expected['/qubes-vm-type'] = 'NetVM'
Expand Down Expand Up @@ -1858,6 +1871,18 @@ def test_621_qdb_vm_with_network(self, mock_qubesdb, mock_urandom,
netvm.create_qdb_entries()
self.assertEqual(test_qubesdb.data, expected)

test_qubesdb.data.clear()
with self.subTest('proxy_ipv6_dns'):
template.features['supported-feature.ipv6dns'] = '1'
netvm.features['ipv6'] = True
expected['/qubes-netvm-primary-dns6'] = 'fd09:24ef:4179::a8b:1'
expected['/qubes-netvm-secondary-dns6'] = 'fd09:24ef:4179::a8b:2'

with unittest.mock.patch('qubes.vm.qubesvm.QubesVM.is_running',
lambda _: True):
netvm.create_qdb_entries()
self.assertEqual(test_qubesdb.data, expected)

@unittest.mock.patch('qubes.utils.get_timezone')
@unittest.mock.patch('qubes.utils.urandom')
@unittest.mock.patch('qubes.vm.qubesvm.QubesVM.untrusted_qdb')
Expand Down
15 changes: 14 additions & 1 deletion qubes/vm/mix/net.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,19 @@ def dns(self):

return None

@qubes.stateless_property
def dns6(self):
'''IPv6 DNS servers set up for this domain.'''
if self.features.check_with_netvm('ipv6', False) and \
self.features.check_with_template("supported-feature.ipv6dns", \
False) and (self.netvm is not None or self.provides_network):
return StrSerializableTuple((
'fd09:24ef:4179::a8b:1',
'fd09:24ef:4179::a8b:2',
))

return None

def __init__(self, *args, **kwargs):
self._firewall = None
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -506,7 +519,7 @@ def on_property_set_ip(self, _event, name, newvalue=None, oldvalue=None):
vm.fire_event(
'property-reset:visible_gateway', name='visible_gateway')

@qubes.events.handler('property-set:ip6', 'property-reset:ipv6')
@qubes.events.handler('property-set:ip6', 'property-reset:ip6')
def on_property_set_ip6(self, _event, name, newvalue=None, oldvalue=None):
# pylint: disable=unused-argument
if newvalue == oldvalue:
Expand Down
12 changes: 11 additions & 1 deletion qubes/vm/qubesvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2252,7 +2252,12 @@ def create_qdb_entries(self):
self.untrusted_qdb.write('/qubes-netvm-netmask', str(self.netmask))

for i, addr in zip(('primary', 'secondary'), self.dns):
self.untrusted_qdb.write('/qubes-netvm-{}-dns'.format(i), addr)
self.untrusted_qdb.write('/qubes-netvm-{}-dns'.format(i), \
str(addr))
if self.dns6: # pylint: disable=using-constant-test
for i, addr in zip(('primary', 'secondary'), self.dns6):
self.untrusted_qdb.write('/qubes-netvm-{}-dns6'.format(i), \
str(addr))

if self.netvm is not None:
self.untrusted_qdb.write('/qubes-mac', str(self.mac))
Expand All @@ -2270,6 +2275,11 @@ def create_qdb_entries(self):
if self.visible_gateway6: # pylint: disable=using-constant-test
self.untrusted_qdb.write('/qubes-gateway6',
str(self.visible_gateway6))
if self.dns6 and self.netvm.features.check_with_netvm('ipv6', \
False): # pylint: disable=using-constant-test
for i, addr in zip(('primary', 'secondary'), self.dns6):
self.untrusted_qdb.write('/qubes-{}-dns6'.format(i), \
str(addr))

tzname = qubes.utils.get_timezone()
if tzname:
Expand Down