Kaynağa Gözat

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

Marek Marczykowski-Górecki 6 yıl önce
ebeveyn
işleme
7f79075088

+ 8 - 2
doc/manpages/qvm-firewall.rst

@@ -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
 -------
 

+ 20 - 0
qubesadmin/tests/tools/qvm_firewall.py

@@ -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):

+ 10 - 1
qubesadmin/tools/qvm_firewall.py

@@ -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,