firewall: use asyncio's call_later instead of systemd to reload rules
When some expiring rules are present, it is necessary to reload firewall when those rules expire. Previously systemd timer was used to trigger this action, but since we have own daemon now, it isn't necessary anymore - use this daemon for that. Additionally automatically removing expired rules was completely broken in R4.0. Fixes QubesOS/qubes-issues#1173
This commit is contained in:
parent
9b5256f002
commit
5e89b23288
@ -7,8 +7,6 @@ install:
|
||||
mkdir -p $(DESTDIR)$(UNITDIR)
|
||||
cp qubes-core.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 qubesd.service $(DESTDIR)$(UNITDIR)
|
||||
install -d $(DESTDIR)$(UNITDIR)/lvm2-pvscan@.service.d
|
||||
|
@ -22,11 +22,12 @@
|
||||
|
||||
import datetime
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
import itertools
|
||||
import os
|
||||
import socket
|
||||
|
||||
import asyncio
|
||||
import lxml.etree
|
||||
|
||||
import qubes
|
||||
@ -543,10 +544,19 @@ class Firewall(object):
|
||||
rule = Rule(xml_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):
|
||||
'''Save firewall rules to a file'''
|
||||
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))
|
||||
|
||||
@ -556,7 +566,9 @@ class Firewall(object):
|
||||
if rule.expire and rule.expire.expired:
|
||||
continue
|
||||
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.append(rule.xml_properties())
|
||||
xml_rules.append(xml_rule)
|
||||
@ -577,9 +589,13 @@ class Firewall(object):
|
||||
|
||||
self.vm.fire_event('firewall-changed')
|
||||
|
||||
if expiring_rules_present and not self.vm.app.vmm.offline_mode:
|
||||
subprocess.call(["sudo", "systemctl", "start",
|
||||
"qubes-reload-firewall@%s.timer" % self.vm.name])
|
||||
if nearest_expire and not self.vm.app.vmm.offline_mode:
|
||||
loop = asyncio.get_event_loop()
|
||||
# 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):
|
||||
'''Return firewall settings serialized for QubesDB entries
|
||||
|
@ -399,8 +399,6 @@ fi
|
||||
%{_unitdir}/qubes-qmemman.service
|
||||
%{_unitdir}/qubes-vm@.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/vm-templates
|
||||
%attr(2770,root,qubes) %dir /var/lib/qubes/appvms
|
||||
|
Loading…
Reference in New Issue
Block a user