---
func/minion/modules/iptables/__init__.py | 115 ++++++++++++++++++++++++++++++
func/minion/modules/iptables/common.py | 48 ++++++++++++
func/minion/modules/iptables/port.py | 106 +++++++++++++++++++++++++++
3 files changed, 269 insertions(+), 0 deletions(-)
create mode 100644 func/minion/modules/iptables/__init__.py
create mode 100644 func/minion/modules/iptables/common.py
create mode 100644 func/minion/modules/iptables/port.py
diff --git a/func/minion/modules/iptables/__init__.py b/func/minion/modules/iptables/__init__.py
new file mode 100644
index 0000000..9253080
--- /dev/null
+++ b/func/minion/modules/iptables/__init__.py
@@ -0,0 +1,115 @@
+#
+# Copyright 2008
+# Krzysztof A. Adamski <krzysztofa@xxxxxxxxx>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# our modules
+from func.minion.modules import func_module
+from func.minion.modules.iptables.common import *
+
+class Iptables(func_module.FuncModule):
+
+ # Update these if need be.
+ version = "0.0.1"
+ api_version = "0.0.1"
+ description = "iptables module"
+
+ def run(self, args):
+ """
+ Run 'iptables' command with arguments given. For example:
+ > func '*' call iptables run "-L INPUT"
+ """
+ return run_iptables(args)
+
+ def policy(self, chain="INPUT", policy=None):
+ """
+ Check/set default policy for the chain. Examples:
+ * Check default policy for INPUT chain:
+ > func '*' call iptables policy
+ or
+ > func '*' call iptables policy INPUT
+ * Set default policy for OUTPUT:
+ > func '*' call iptables policy OUTPUT DROP
+ """
+ if policy==None:
+ return check_policy(chain)
+ else:
+ return set_policy(chain, policy)
+
+ def flush(self, chain="INPUT"):
+ """
+ Flush the selected chain (or INPUT if none given).
+ """
+ return call_iptables("-F %s" % chain)
+
+ def zero(self, chain="INPUT"):
+ """
+ Zero counters in selected chain (or INPUT if none given).
+ """
+ return call_iptables("-Z %s" % chain)
+
+ def drop_from(self, ip):
+ """
+ Drop all incomming traffic from IP. Example:
+ > func '*' call iptables drop_from 192.168.0.10
+ """
+ while not call_iptables("-D INPUT -s %s -j ACCEPT" % ip): pass
+ if check_policy("INPUT") == "ACCEPT":
+ return call_iptables("-I INPUT -s %s -j DROP" % ip)
+ else:
+ return 0
+
+ def accept_from(self, ip):
+ """
+ Accept all incoming traffic from IP. Example:
+ > func '*' call iptables accept_from 192.168.0.10
+ """
+ while not call_iptables("-D INPUT -s %s -j DROP" % ip): pass
+ if check_policy("INPUT") == "DROP":
+ return call_iptables("-I INPUT -s %s -j ACCEPT" % ip)
+ else:
+ return 0
+
+ def drop_to(self, ip):
+ """
+ Drop all outgoing traffic to IP. Example:
+ > func '*' call iptables drop_to 192.168.0.10
+ """
+ while not call_iptables("-D OUTPUT -d %d -j ACCEPT"): pass
+ if check_policy("INPUT") == "ACCEPT":
+ return call_iptables("-I OUTPUT -d %s -j DROP" % ip)
+ else:
+ return 0
+
+ def accept_to(self, ip):
+ """
+ Accept all outgoing traffic to IP. Example:
+ > func '*' call iptables accept_to 192.168.0.10
+ """
+ while not call_iptables("-D OUTPUT -d %d -j DROP"): pass
+ if check_policy("INPUT") == "DROP":
+ return call_iptables("-I OUTPUT -d %s -j ACCEPT" % ip)
+ else:
+ return 0
+
+ def show(self, chain=""):
+ results = []
+ data=run_iptables("-v -x -n -L %s" % chain)
+ for tokens in data:
+ if len(tokens) == 0:
+ continue
+
+ if tokens[0] == "Chain":
+ #results.append([ tokens[3], tokens[4], tokens[6] ])
+ pass
+ elif tokens[0] != "pkts":
+ results.append(tokens)
+
+ return results
+
diff --git a/func/minion/modules/iptables/common.py b/func/minion/modules/iptables/common.py
new file mode 100644
index 0000000..08333fa
--- /dev/null
+++ b/func/minion/modules/iptables/common.py
@@ -0,0 +1,48 @@
+#
+# Copyright 2008
+# Krzysztof A. Adamski <krzysztofa@xxxxxxxxx>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# other modules
+import sub_process
+
+def run_iptables(args):
+ cmd = sub_process.Popen(["/sbin/iptables"] + args.split(),
+ executable="/sbin/iptables",
+ stdout=sub_process.PIPE,
+ stderr=sub_process.PIPE,
+ shell=False)
+
+ data, error = cmd.communicate()
+
+ results = []
+ for line in data.split("\n"):
+ tokens = line.split()
+ results.append(tokens)
+
+ return results
+
+def call_iptables(args):
+ return sub_process.call(["/sbin/iptables"] + args.split(),
+ executable="/sbin/iptables",
+ shell=False)
+
+def check_policy(chain):
+ ret = run_iptables("-L %s" % chain)
+ try:
+ if ret[0][2] == "(policy":
+ return ret[0][3][:-1]
+ else:
+ return False
+ except:
+ return False
+
+def set_policy(chain, policy):
+ return call_iptables("-P %s %s" % (chain, policy) )
+
diff --git a/func/minion/modules/iptables/port.py b/func/minion/modules/iptables/port.py
new file mode 100644
index 0000000..3f0d693
--- /dev/null
+++ b/func/minion/modules/iptables/port.py
@@ -0,0 +1,106 @@
+#
+# Copyright 2008
+# Krzysztof A. Adamski <krzysztofa@xxxxxxxxx>
+#
+# This software may be freely redistributed under the terms of the GNU
+# general public license.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# our modules
+from func.minion.modules import func_module
+from func.minion.modules.iptables.common import *
+
+class Port(func_module.FuncModule):
+
+ # Update these if need be.
+ version = "0.0.1"
+ api_version = "0.0.1"
+ description = "iptables 'port' submodule"
+
+ def drop_from(self, port, ip="0.0.0.0", prot="tcp", dir="dst"):
+ """
+ Drop all traffic comming from/to PORT. Arguments:
+ * port - destination/source port
+ * ip - source IP
+ * prot - protocol (e.g. tcp/udp)
+ * dir - direction, "dst" for matching destination port or "src" for matching source port
+ Examples:
+ * Drop all incoming traffic to local TCP port 80:
+ > func '*' call iptables.port drop_from 80
+ * Drop incomming traffic to local UDP port 53 from 192.168.0.0/24:
+ > func '*' call iptables.port drop_from 80 192.168.0.0/24 udp
+ """
+ dir=parse_dir(dir)
+ while not call_iptables("-D INPUT -p %s --%sport %s -s %s -j ACCEPT" % (prot, dir, port, ip) ): pass
+ if check_policy("INPUT") == "ACCEPT":
+ return call_iptables("-I INPUT -p %s --%sport %s -s %s -j DROP" % (prot, dir, port, ip) )
+ else:
+ return 0
+
+ def accept_from(self, port, ip="0.0.0.0", prot="tcp", dir="dst"):
+ """
+ Accept all traffic comming from/to PORT. Arguments:
+ * port - destination/source port
+ * ip - source IP
+ * prot - protocol (e.g. tcp/udp)
+ * dir - direction, "dst" for matching destination port or "src" for matching source port
+ Examples:
+ * Accept all incoming traffic to local TCP port 80:
+ > func '*' call iptables.port accept_from 80
+ * Accept incomming traffic to local UDP port 53 from 192.168.0.0/24:
+ > func '*' call iptables.port accept_from 80 192.168.0.0/24 udp
+ """
+ while not call_iptables("-D INPUT -p %s --%sport %s -s %s -j DROP" % (prot, dir, port, ip) ): pass
+ if check_policy("INPUT") == "DROP":
+ return call_iptables("-I INPUT -p %s --%sport %s -s %s -j ACCEPT" % (prot, dir, port, ip) )
+ else:
+ return 0
+
+ def drop_to(self, port, ip="0.0.0.0", prot="tcp", dir="dst"):
+ """
+ Drop all outgoing traffic going from/to PORT. Arguments:
+ * port - destination/source port
+ * ip - destination IP
+ * prot - protocol (e.g. tcp/udp)
+ * dir - direction, "dst" for matching destination port or "src" for matching source port
+ Examples:
+ * Drop outgoing traffic to TCP port 80 on 192.168.0.1:
+ > func '*' call iptables.port drop_to 80 192.168.0.1
+ * Drop outgoing traffic from UDP port 53 to 192.168.0.0/24:
+ > func '*' call iptables.port drop_to 53 192.168.0.0/24 udp src
+ """
+ while not call_iptables("-D OUTPUT -p %s --%sport %s -d %s -j ACCEPT" % (prot, dir, port, ip) ): pass
+ if check_policy("OUTPUT") == "ACCEPT":
+ return call_iptables("-I OUTPUT -p %s --%sport %s -d %s -j DROP" % (prot, dir, port, ip) )
+ else:
+ return 0
+
+ def accept_to(self, port, ip="0.0.0.0", prot="tcp", dir="dst"):
+ """
+ Accept all outgoing traffic going from/to PORT. Arguments:
+ * port - destination/source port
+ * ip - destination IP
+ * prot - protocol (e.g. tcp/udp)
+ * dir - direction, "dst" for matching destination port or "src" for matching source port
+ Examples:
+ * Accept outgoing traffic to TCP port 80 on 192.168.0.1:
+ > func '*' call iptables.port accept_to 80 192.168.0.1
+ * Accept outgoing traffic from UDP port 53 to 192.168.0.0/24:
+ > func '*' call iptables.port accept_to 53 192.168.0.0/24 udp src
+ """
+ while not call_iptables("-D OUTPUT -p %s --%sport %s -d %s -j DROP" % (prot, dir, port, ip) ): pass
+ if check_policy("OUTPUT") == "DROP":
+ return call_iptables("-I OUTPUT -p %s --%sport %s -d %s -j ACCEPT" % (prot, dir, port, ip) )
+ else:
+ return 0
+
+def parse_dir(dir):
+ if (dir == "dst"):
+ return "d"
+ elif (dir == "src"):
+ return "s"
+ else:
+ raise exceptions.Exception("Wrong direction!")