commit 8c850fc26023b189ea564395b60d25e480ec2a47
Author: Marios Kogias <marioskogias@grnet.gr>
Date:   Wed Sep 11 16:38:07 2013 +0300

    Add the config file and logger

diff --git a/snf-router/file.conf b/snf-router/file.conf
new file mode 100644
index 0000000..675d792
--- /dev/null
+++ b/snf-router/file.conf
@@ -0,0 +1,16 @@
+[log]
+host = ''
+url = ''
+method = ''
+
+[policy]
+INPUT = DROP
+OUTPUT = DROP
+FORWARD = DROP
+
+[private-network]
+cidr = 192.168.0.0/24
+ports = 22,80,3389
+start_port = 10000 
+step = 10000
+iface = eth1 
diff --git a/snf-router/router.py b/snf-router/router.py
index 2cf4893..62d767c 100644
--- a/snf-router/router.py
+++ b/snf-router/router.py
@@ -38,17 +38,20 @@ one subnet and one public IP.
 
 Logic:
 Whenever this script is called, one of our nics changed, so flush everything.
-If nic has a public IP AND a private nic is up, create rules for that private
-nic.
-elif nic is private and there is a public nic, create rules for the specific
-nic
-else do nothing
+If the nic is public create the rules for the private net given in the config
+file
+Else do nothing
 '''
 
 import iptc
 import netifaces
 import sys
 import IPy
+import ConfigParser
+import logging
+import logging.handlers
+
+CONFIG_FILE = 'file.conf'
 
 
 def flush(table_name='', chain_name=''):
@@ -60,13 +63,32 @@ def flush(table_name='', chain_name=''):
     table.flush_entries(chain_name)
 
 
-def create_dnat():
-    placeholder
-
-
-def create_snat(public_ip, private_net, public_iface, private_iface):
+def create_dnat(cidr, ports, start_port, step, pub_ip):
+    i = 0
+    for ip in IPy.IP(cidr):
+        j = 1
+        for sport in ports:
+            rule = iptc.Rule()
+            rule.dst = pub_ip
+            rule.protocol = "tcp"
+            match = iptc.Match(rule, "tcp")
+            port = int(start_port) + j*int(step) + i
+            match.dport = str(port)
+            rule.add_match(match)
+            target = iptc.Target(rule, "DNAT")
+            rule.target = target
+            rule.target.to_destination = "%s:%s" % (ip, sport)
+            chain = iptc.Chain(iptc.Table(iptc.Table.NAT), "PREROUTING")
+            chain.insert_rule(rule)
+            j = j + 1
+
+        i = i + 1
+
+
+def create_snat(public_ip, private_net, public_iface):
     chain = iptc.Chain(iptc.Table(iptc.Table.NAT), "POSTROUTING")
     rule = iptc.Rule()
+    private_net = "%s/%s" % (str(IPy.IP(private_net).net()), str(IPy.IP(private_net).netmask()))
     rule.src = private_net
     rule.dst = "!%s" % private_net
     rule.out_interface = public_iface
@@ -79,6 +101,7 @@ def create_snat(public_ip, private_net, public_iface, private_iface):
 def create_states(private_net, public_iface, private_iface):
     chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "FORWARD")
     rule = iptc.Rule()
+    private_net = "%s/%s" % (str(IPy.IP(private_net).net()), str(IPy.IP(private_net).netmask()))
     rule.src = "!%s" % private_net
     rule.dst = private_net
     rule.out_interface = private_iface
@@ -95,31 +118,102 @@ def nic_info(interface):
     '''
     Returns the IP and ip type (PUBLIC/PRIVATE) of interface
     '''
+    nic = dict()
     nic['ip'] = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
     nic['ip_type'] = IPy.IP(nic['ip']).iptype()
     return nic
 
 
-def parse_config():
-    placeholder
+def parse_config(filename):
+    config = ConfigParser.ConfigParser()
+    config.read(filename)
+    return config
+
+
+def create_remote_logger(host, url, method):
+    logger = logging.getLogger('snf-router')
+    logger.setLevel(logging.INFO)
+    #http_handler = logging.handlers.HTTPHandler(host, url, method)
+    http_handler = logging.handlers.WatchedFileHandler("test.log")
+    formatter = logging.Formatter("%(asctime)s - %(message)s")
+    http_handler.setFormatter(formatter)
+    logger.addHandler(http_handler)
+    return logger
 
 
 def allow_ssh():
-    placeholder
+    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "INPUT")
+    rule = iptc.Rule()
+    rule.protocol = "tcp"
+    match = iptc.Match(rule, "tcp")
+    match.dport = "22"
+    rule.add_match(match)
+    target = iptc.Target(rule, "ACCEPT")
+    rule.target = target
+    chain.insert_rule(rule)
+    
+    chain = iptc.Chain(iptc.Table(iptc.Table.FILTER), "OUTPUT")
+    rule = iptc.Rule()
+    rule.protocol = "tcp"
+    match = iptc.Match(rule, "tcp")
+    match.sport = "22"
+    rule.add_match(match)
+    target = iptc.Target(rule, "ACCEPT")
+    rule.target = target
+    chain.insert_rule(rule)
+
+def set_policy(table, chain, policy):
+    cur_table = iptc.Table(getattr(iptc.Table, table))
+    cur_chain = iptc.Chain(cur_table, chain)
+    cur_chain.set_policy(policy)
 
 
-def deny_all():
-    placeholder
+def get_public_iface():
+    public_iface = ''
+    for iface in netifaces.interfaces():
+        nic = nic_info(iface)
+        if nic['ip_type'] == 'PUBLIC':
+            public_iface = iface
+            break
+    return public_iface
 
 
 def main():
-    #log
-    flush("NAT", "PREROUTING")
-    flush("NAT", "POSTROUTING")
-    flush("FILTER", "FORWARD")
-
-    if sys.argv[2] == 'up':
-        #log
-        nic = nic_info(sys.argv[1])
-        if nic['ip_type'] == "PUBLIC":
-            placeholder
+    #read config file
+    config = parse_config(CONFIG_FILE)
+
+    #create logger
+    logger = create_remote_logger(config.get('log', 'host'),
+                    config.get('log', 'url'),
+                    config.get('log', 'method'))
+    
+    nic = nic_info(sys.argv[1])
+    logger.info(nic['ip_type'] + " " + sys.argv[1] + " " + sys.argv[2])
+
+    if sys.argv[2] == 'up' and nic['ip_type'] == "PUBLIC":
+        #flush the old rules
+        flush("NAT", "PREROUTING")
+        flush("NAT", "POSTROUTING")
+        flush("FILTER", "FORWARD")
+
+        #set policy
+        #set_policy("FILTER", "FORWARD", config.get('policy', 'FORWARD'))
+        #set_policy("FILTER", "OUTPUT", config.get('policy', 'OUTPUT'))
+        #set_policy("FILTER", "INPUT", config.get('policy', 'INPUT'))
+
+        # create dnat
+        create_dnat(config.get("private-network", "cidr"),
+                    config.get("private-network", "ports").split(","),
+                    config.get("private-network", "start_port"),
+                    config.get("private-network", "step"),
+                    nic["ip"])
+
+        # create snat
+        create_snat(nic['ip'], config.get("private-network","cidr"),
+                sys.argv[1])
+
+        create_states(config.get("private-network","cidr"), sys.argv[1],
+             config.get("private-network","iface"))
+
+if __name__ == "__main__":
+    main()
