Merge remote-tracking branch 'qubesos/pr/193'
* qubesos/pr/193: tests: add a test for removing expired firewall rules firewall: use asyncio's call_later instead of systemd to reload rules
This commit is contained in:
commit
1562defd42
@ -7,8 +7,6 @@ install:
|
|||||||
mkdir -p $(DESTDIR)$(UNITDIR)
|
mkdir -p $(DESTDIR)$(UNITDIR)
|
||||||
cp qubes-core.service $(DESTDIR)$(UNITDIR)
|
cp qubes-core.service $(DESTDIR)$(UNITDIR)
|
||||||
cp qubes-vm@.service $(DESTDIR)$(UNITDIR)
|
cp qubes-vm@.service $(DESTDIR)$(UNITDIR)
|
||||||
cp qubes-reload-firewall@.service $(DESTDIR)$(UNITDIR)
|
|
||||||
cp qubes-reload-firewall@.timer $(DESTDIR)$(UNITDIR)
|
|
||||||
cp qubes-qmemman.service $(DESTDIR)$(UNITDIR)
|
cp qubes-qmemman.service $(DESTDIR)$(UNITDIR)
|
||||||
cp qubesd.service $(DESTDIR)$(UNITDIR)
|
cp qubesd.service $(DESTDIR)$(UNITDIR)
|
||||||
install -d $(DESTDIR)$(UNITDIR)/lvm2-pvscan@.service.d
|
install -d $(DESTDIR)$(UNITDIR)/lvm2-pvscan@.service.d
|
||||||
|
@ -22,11 +22,12 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import string
|
import string
|
||||||
import subprocess
|
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import lxml.etree
|
import lxml.etree
|
||||||
|
|
||||||
import qubes
|
import qubes
|
||||||
@ -543,10 +544,19 @@ class Firewall(object):
|
|||||||
rule = Rule(xml_rule)
|
rule = Rule(xml_rule)
|
||||||
self.rules.append(rule)
|
self.rules.append(rule)
|
||||||
|
|
||||||
|
def _expire_rules(self):
|
||||||
|
'''Function called to reload expired rules'''
|
||||||
|
old_rules = self.rules
|
||||||
|
self.load()
|
||||||
|
if self.rules != old_rules:
|
||||||
|
# this will both save rules skipping those expired and trigger
|
||||||
|
# QubesDB update; and possibly schedule another timer
|
||||||
|
self.save()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
'''Save firewall rules to a file'''
|
'''Save firewall rules to a file'''
|
||||||
firewall_conf = os.path.join(self.vm.dir_path, self.vm.firewall_conf)
|
firewall_conf = os.path.join(self.vm.dir_path, self.vm.firewall_conf)
|
||||||
expiring_rules_present = False
|
nearest_expire = False
|
||||||
|
|
||||||
xml_root = lxml.etree.Element('firewall', version=str(2))
|
xml_root = lxml.etree.Element('firewall', version=str(2))
|
||||||
|
|
||||||
@ -556,7 +566,9 @@ class Firewall(object):
|
|||||||
if rule.expire and rule.expire.expired:
|
if rule.expire and rule.expire.expired:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
expiring_rules_present = True
|
if nearest_expire is None or rule.expire.datetime < \
|
||||||
|
nearest_expire:
|
||||||
|
nearest_expire = rule.expire.datetime
|
||||||
xml_rule = lxml.etree.Element('rule')
|
xml_rule = lxml.etree.Element('rule')
|
||||||
xml_rule.append(rule.xml_properties())
|
xml_rule.append(rule.xml_properties())
|
||||||
xml_rules.append(xml_rule)
|
xml_rules.append(xml_rule)
|
||||||
@ -577,9 +589,13 @@ class Firewall(object):
|
|||||||
|
|
||||||
self.vm.fire_event('firewall-changed')
|
self.vm.fire_event('firewall-changed')
|
||||||
|
|
||||||
if expiring_rules_present and not self.vm.app.vmm.offline_mode:
|
if nearest_expire and not self.vm.app.vmm.offline_mode:
|
||||||
subprocess.call(["sudo", "systemctl", "start",
|
loop = asyncio.get_event_loop()
|
||||||
"qubes-reload-firewall@%s.timer" % self.vm.name])
|
# by documentation call_at use loop.time() clock, which not
|
||||||
|
# necessary must be the same as time module; calculate delay and
|
||||||
|
# use call_later instead
|
||||||
|
expire_when = nearest_expire - datetime.datetime.now()
|
||||||
|
loop.call_later(expire_when, self._expire_rules)
|
||||||
|
|
||||||
def qdb_entries(self, addr_family=None):
|
def qdb_entries(self, addr_family=None):
|
||||||
'''Return firewall settings serialized for QubesDB entries
|
'''Return firewall settings serialized for QubesDB entries
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import asyncio
|
||||||
import lxml.etree
|
import lxml.etree
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
@ -583,3 +584,24 @@ class TC_10_Firewall(qubes.tests.QubesTestCase):
|
|||||||
'0003': 'action=accept specialtarget=dns',
|
'0003': 'action=accept specialtarget=dns',
|
||||||
}
|
}
|
||||||
self.assertEqual(fw.qdb_entries(), expected_qdb_entries)
|
self.assertEqual(fw.qdb_entries(), expected_qdb_entries)
|
||||||
|
|
||||||
|
def test_006_auto_expire_rules(self):
|
||||||
|
fw = qubes.firewall.Firewall(self.vm, True)
|
||||||
|
rules = [
|
||||||
|
qubes.firewall.Rule(None, action='drop', proto='icmp'),
|
||||||
|
qubes.firewall.Rule(None, action='drop', proto='tcp', dstports=80),
|
||||||
|
qubes.firewall.Rule(None, action='accept', proto='udp',
|
||||||
|
dstports=67, expire=self.loop.time() + 5),
|
||||||
|
qubes.firewall.Rule(None, action='accept', specialtarget='dns'),
|
||||||
|
]
|
||||||
|
fw.rules = rules
|
||||||
|
fw.save()
|
||||||
|
self.assertEqual(fw.rules, rules)
|
||||||
|
self.loop.run_until_complete(asyncio.sleep(3))
|
||||||
|
# still old rules should be there
|
||||||
|
self.assertEqual(fw.rules, rules)
|
||||||
|
|
||||||
|
rules.pop(2)
|
||||||
|
self.loop.run_until_complete(asyncio.sleep(3))
|
||||||
|
# expect new rules
|
||||||
|
self.assertEqual(fw.rules, rules)
|
||||||
|
@ -400,8 +400,6 @@ fi
|
|||||||
%{_unitdir}/qubes-qmemman.service
|
%{_unitdir}/qubes-qmemman.service
|
||||||
%{_unitdir}/qubes-vm@.service
|
%{_unitdir}/qubes-vm@.service
|
||||||
%{_unitdir}/qubesd.service
|
%{_unitdir}/qubesd.service
|
||||||
%{_unitdir}/qubes-reload-firewall@.service
|
|
||||||
%{_unitdir}/qubes-reload-firewall@.timer
|
|
||||||
%attr(2770,root,qubes) %dir /var/lib/qubes
|
%attr(2770,root,qubes) %dir /var/lib/qubes
|
||||||
%attr(2770,root,qubes) %dir /var/lib/qubes/vm-templates
|
%attr(2770,root,qubes) %dir /var/lib/qubes/vm-templates
|
||||||
%attr(2770,root,qubes) %dir /var/lib/qubes/appvms
|
%attr(2770,root,qubes) %dir /var/lib/qubes/appvms
|
||||||
|
Loading…
Reference in New Issue
Block a user