tools/qvm-firewall: add 'expire' rule support

This commit is contained in:
Marek Marczykowski-Górecki 2018-04-30 04:13:45 +02:00
parent e69b4fb1bd
commit 7f79075088
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 38 additions and 3 deletions

View File

@ -7,8 +7,11 @@ Synopsis
--------
:command:`qvm-firewall` [-h] [--verbose] [--quiet] [--reload] *VMNAME* add *RULE*
:command:`qvm-firewall` [-h] [--verbose] [--quiet] [--reload] *VMNAME* del [--rule-no=*RULE_NUMBER*] [*RULE*]
:command:`qvm-firewall` [-h] [--verbose] [--quiet] [--reload] *VMNAME* list [--raw]
:command:`qvm-firewall` [-h] [--verbose] [--quiet] [--reload] *VMNAME* policy {accept,drop}
Options
@ -42,8 +45,7 @@ Available actions:
* add - add specified rule. See `Rule syntax` section below.
* del - delete specified rule. Can be selected either by rule number using
:option:`--rule-no`, or specifying rule itself.
* del - delete specified rule. Can be selected either by rule number using :option:`--rule-no`, or specifying rule itself.
* list - list all the rules for a given VM.
@ -78,6 +80,10 @@ Supported matches:
- ``specialtarget`` - predefined target. Currently the only supported value is
``dns``. This can be combined with other matches to narrow it down.
- ``expire`` - rule matches only until specified time and then is automatically
removed. The time can be given either as number of seconds since 1/1/1970, or
``+seconds`` as a relative time (``+300`` means 5 minutes from now).
Authors
-------

View File

@ -21,6 +21,7 @@
#
import argparse
import datetime
import qubesadmin.firewall
import qubesadmin.tests
@ -66,6 +67,25 @@ class TC_00_RuleAction(qubesadmin.tests.QubesTestCase):
None, action='accept', dsthost='127.0.0.1/32',
proto='tcp', dstports=443))
def test_004_expire_absolute(self):
ns = argparse.Namespace()
self.action(None, ns, ['dsthost=127.0.0.1', 'action=accept',
'expire=1525054180'])
self.assertEqual(ns.rule,
qubesadmin.firewall.Rule(
None, action='accept', dsthost='127.0.0.1/32',
expire=1525054180))
def test_005_expire_relative(self):
ns = argparse.Namespace()
now = int(datetime.datetime.now().strftime('%s'))
self.action(None, ns, ['dsthost=127.0.0.1', 'action=accept',
'expire=+100'])
self.assertEqual(ns.rule,
qubesadmin.firewall.Rule(
None, action='accept', dsthost='127.0.0.1/32',
expire=now+100))
class TC_10_qvm_firewall(qubesadmin.tests.QubesTestCase):
def setUp(self):

View File

@ -22,6 +22,7 @@
'''qvm-firewall tool'''
import argparse
import datetime
import sys
import itertools
@ -44,7 +45,7 @@ class RuleAction(argparse.Action):
setattr(namespace, self.dest, None)
return
assumed_order = ['action', 'dsthost', 'proto', 'dstports', 'icmptype']
allowed_opts = assumed_order + ['specialtarget', 'comment']
allowed_opts = assumed_order + ['specialtarget', 'comment', 'expire']
kwargs = {}
for opt in values:
opt_elements = opt.split('=')
@ -58,6 +59,10 @@ class RuleAction(argparse.Action):
if key not in allowed_opts:
raise argparse.ArgumentError(None,
'Invalid rule element: {}'.format(opt))
if key == 'expire' and value.startswith('+'):
value = (datetime.datetime.now() +
datetime.timedelta(seconds=int(value[1:]))).\
strftime('%s')
kwargs[key] = value
if key in assumed_order:
assumed_order.remove(key)
@ -75,6 +80,7 @@ Rules can be given as positional arguments:
And as keyword arguments:
action=<action> [specialtarget=dns] [dsthost=<dsthost>]
[proto=<proto>] [dstports=<dstports>] [icmptype=<icmptype>]
[expire=<expire>]
Both formats, positional and keyword arguments, can be used
interchangeably.
@ -91,6 +97,9 @@ Available rules:
specialtarget only the value dns is currently supported,
it matches the configured dns servers of
a VM
expire a rule is automatically removed at given time, given as
seconds since 1/1/1970, or +seconds (e.g. +300 for rule
expire in 5 minutes)
"""
parser = qubesadmin.tools.QubesArgumentParser(vmname_nargs=1, epilog=epilog,