From f149f1c6f3c878de788896902fad291b617f4e93 Mon Sep 17 00:00:00 2001 From: Michael Harrity Date: Thu, 2 Sep 2021 10:42:15 -0700 Subject: [PATCH 1/3] Engine Allows Port Ranges/Lists Updated the Geneva engine to allow for port ranges and lists specifying which ports to monitor to modify packets. This works using either a range like port 5000 to port 6000 => --server-port 5000:6000 or a list like port 5000, 5500, and 6000 => --server-port 5000,5500,6000. Any error checking on the port variable will be handled by the iptables command. --- engine.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/engine.py b/engine.py index cbffe03..6fda11d 100644 --- a/engine.py +++ b/engine.py @@ -47,7 +47,7 @@ class Engine(): demo_mode=False): """ Args: - server_port (int): The port the engine will monitor + server_port (int): The port(s) the engine will monitor string_strategy (str): String representation of strategy DNA to apply to the network environment_id (str, None): ID of the given strategy server_side (bool, False): Whether or not the engine is running on the server side of the connection @@ -221,17 +221,24 @@ class Engine(): add_or_remove = "D" cmds = [] for proto in ["tcp", "udp"]: - cmds += ["iptables -%s %s -p %s --%s %d -j NFQUEUE --queue-num %d" % - (add_or_remove, out_chain, proto, port1, self.server_port, self.out_queue_num), - "iptables -%s %s -p %s --%s %d -j NFQUEUE --queue-num %d" % - (add_or_remove, in_chain, proto, port2, self.server_port, self.in_queue_num)] + # Need to change the match rule if multiple ports are specified + # Don't need to do any checking on the port since the iptables command can error, closing the engine + # Default match policy is the protocol + match_policy = proto + if any(x in self.server_port for x in [":", ","]): + match_policy = "multiport" + + cmds += ["iptables -%s %s -p %s --match %s --%s %s -j NFQUEUE --queue-num %d" % + (add_or_remove, out_chain, proto, match_policy, port1, self.server_port, self.out_queue_num), + "iptables -%s %s -p %s --match %s --%s %s -j NFQUEUE --queue-num %d" % + (add_or_remove, in_chain, proto, match_policy, port2, self.server_port, self.in_queue_num)] # If this machine is acting as a middlebox, we need to add the same rules again # in the opposite direction so that we can pass packets back and forth if self.forwarder: - cmds += ["iptables -%s %s -p %s --%s %d -j NFQUEUE --queue-num %d" % - (add_or_remove, out_chain, proto, port2, self.server_port, self.out_queue_num), - "iptables -%s %s -p %s --%s %d -j NFQUEUE --queue-num %d" % - (add_or_remove, in_chain, proto, port1, self.server_port, self.in_queue_num)] + cmds += ["iptables -%s %s -p %s --match %s --%s %s -j NFQUEUE --queue-num %d" % + (add_or_remove, out_chain, proto, match_policy, port2, self.server_port, self.out_queue_num), + "iptables -%s %s -p %s --match %s --%s %s -j NFQUEUE --queue-num %d" % + (add_or_remove, in_chain, proto, match_policy, port1, self.server_port, self.in_queue_num)] for cmd in cmds: self.logger.debug(cmd) @@ -409,7 +416,8 @@ def get_args(): Sets up argparse and collects arguments. """ parser = argparse.ArgumentParser(description='The engine that runs a given strategy.') - parser.add_argument('--server-port', type=int, action='store', required=True) + # Store a string, not int, in case of port ranges/lists. The iptables command checks the port var + parser.add_argument('--server-port', action='store', required=True) parser.add_argument('--environment-id', action='store', help="ID of the current strategy under test") parser.add_argument('--sender-ip', action='store', help="IP address of sending machine, used for NAT") parser.add_argument('--routing-ip', action='store', help="Public IP of this machine, used for NAT") From 00b2e0e5bed8e14ccc001a3e304eb53d302b9d51 Mon Sep 17 00:00:00 2001 From: Michael Harrity Date: Thu, 2 Sep 2021 14:07:05 -0700 Subject: [PATCH 2/3] Added Multiple Port Monitoring into README Added a note to the README to talk about how to run Geneva on many ports at once. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a8ba56d..fe999a4 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,9 @@ code, it is a description that tells the engine how it should operate over traff ``` Note that if you have stale `iptables` rules or other rules that rely on Geneva's default queues, -this will fail. To fix this, remove those rules. +this will fail. To fix this, remove those rules. + +Also note that if you want to specify multiple ports for Geneva to monitor, you can specify a port range using `--server-port 4000:5000` to monitor all ports in the range 4000-5000, or you can specify a list like `--server-port 80,443,4444` to only monitor the explicit ports given. ## Strategy Library From b7bd667ac7b3c30eba967bf549d6c736b1c28161 Mon Sep 17 00:00:00 2001 From: Michael Harrity Date: Sun, 5 Sep 2021 07:58:38 -0700 Subject: [PATCH 3/3] Updated Engine Docstring Updated the server_port arg in engine docstring to be a string. --- engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine.py b/engine.py index 6fda11d..7eab106 100644 --- a/engine.py +++ b/engine.py @@ -47,7 +47,7 @@ class Engine(): demo_mode=False): """ Args: - server_port (int): The port(s) the engine will monitor + server_port (str): The port(s) the engine will monitor string_strategy (str): String representation of strategy DNA to apply to the network environment_id (str, None): ID of the given strategy server_side (bool, False): Whether or not the engine is running on the server side of the connection