Add port forwarding and static nat to the convergence infrastructure

This commit is contained in:
Hugo Trippaers 2014-08-22 11:06:45 +02:00 committed by wilderrodrigues
parent 8c5dba31d0
commit 80a149abb7
3 changed files with 62 additions and 1 deletions

View File

@ -74,6 +74,7 @@ def get_hostname():
def execute(command):
""" Execute command """
logging.debug("Executing %s" % command)
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
result = p.communicate()[0]
return result.splitlines()

View File

@ -188,7 +188,8 @@ class CsNetfilter(object):
""" Convert the rule back into aynactically correct iptables command """
# Order is important
order = ['-A', '-s', '-d', '!_-d', '-i', '-m', '-m2', '--state',
'--dport', '-p', '-o', '-j', '--set-xmark', '--to-source']
'--dport', '--destination-port', '-p', '-o', '-j', '--set-xmark',
'--to-source', '--to-destination']
str = ''
for k in order:
if k in self.rule.keys():

View File

@ -778,6 +778,61 @@ class CsAddress(CsDataBag):
if CsDevice(dev).waitfordevice():
ip.configure()
class CsForwardingRules(CsDataBag):
def __init__(self, key):
super(CsForwardingRules, self).__init__(key)
global fw
def process(self):
for public_ip in self.dbag:
if public_ip == "id":
continue
for rule in self.dbag[public_ip]:
if rule["type"] == "forward":
self.processForwardRule(rule)
elif rule["type"] == "staticnat":
self.processStaticNatRule(rule)
def getDeviceByIp(self, ip):
ips = CsDataBag("ips")
dbag = ips.get_bag()
for device in dbag:
if device == "id":
continue
for addy in dbag[device]:
if addy["public_ip"] == ip:
return device
return None
def portsToString(self, ports, delimiter):
ports_parts = ports.split(":", 2)
if ports_parts[0] == ports_parts[1]:
return str(ports_parts[0])
else:
return "%s%s%s" % (port_parts, delimiter, port_parts[1])
def processForwardRule(self, rule):
# FIXME this seems to be different for regular VRs?
fwrule = "-A PREROUTING -d %s/32" % rule["public_ip"]
if not rule["protocol"] == "any":
fwrule += " -m %s -p %s" % (rule["protocol"], rule["protocol"])
if not rule["public_ports"] == "any":
fwrule += " --dport %s" % self.portsToString(rule["public_ports"], ":")
fwrule += " -j DNAT --to-destination %s" % rule["internal_ip"]
if not rule["internal_ports"] == "any":
fwrule += ":" + self.portsToString(rule["internal_ports"], "-")
fw.append(["nat","",fwrule])
def processStaticNatRule(self, rule):
# FIXME this needs ordering with the VPN no nat rule
device = self.getDeviceByIp(rule["public_ip"])
if device == None:
raise Exception("Ip address %s has no device in the ips databag" % rule["public_ip"])
fw.append(["nat","","-A PREROUTING -d %s/32 -j DNAT --to-destination %s" % ( rule["public_ip"], rule["internal_ip"]) ])
fw.append(["nat","","-A POSTROUTING -o %s -s %s/32 -j SNAT --to-source %s" % ( device, rule["internal_ip"], rule["public_ip"]) ])
def main(argv):
logging.basicConfig(filename='/var/log/cloud.log',
@ -799,6 +854,9 @@ def main(argv):
acls = CsAcl('networkacl')
acls.process()
fwd = CsForwardingRules("forwardingrules")
fwd.process()
nf = CsNetfilters()
nf.compare(fw)
@ -806,5 +864,6 @@ def main(argv):
dhcp = CsDhcp(dh.get_bag(), cl)
if __name__ == "__main__":
main(sys.argv)