diff --git a/systemvm/patches/debian/config/opt/cloud/bin/CsNetfilter.py b/systemvm/patches/debian/config/opt/cloud/bin/CsNetfilter.py index d31ee0dc2f8..6866733f5f8 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/CsNetfilter.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/CsNetfilter.py @@ -1,20 +1,26 @@ import CsHelper from pprint import pprint +import logging class CsChain(object): def __init__(self): self.chain = {} + self.last_added = '' def add(self, table, chain): if not table in self.chain.keys(): self.chain.setdefault(table, []).append( chain ) else: self.chain[table].append(chain) + self.last_added = chain def get(self, table): return self.chain[table] + def last(self): + return self.last_added + class CsTable(object): def __init__(self): @@ -49,6 +55,7 @@ class CsNetfilters(object): if i.startswith('-A'): # Rule rule = CsNetfilter() rule.parse(i) + rule.set_table(self.table.last()) self.save(rule) def save(self,rule): @@ -63,15 +70,75 @@ class CsNetfilters(object): def hasChain(self, table, chain): return chain in self.chain.get(table) + def has_rule(self, new_rule): + for r in self.get(): + if new_rule.equals(r): + return True + return False + + def compare(self, list): + """ Compare reality with what is needed """ + for fw in list: + new_rule = CsNetfilter() + new_rule.parse(fw[2]) + new_rule.set_table(fw[0]) + if self.has_rule(new_rule): + logging.debug("rule %s exists in table %s", fw[2], new_rule.get_table()) + else: + logging.info("Add rule %s in table %s", fw[2], new_rule.get_table()) + print "Add rule %s in table %s" % (fw[2], new_rule.get_table()) + + CsHelper.execute("iptables -t %s %s" % (new_rule.get_table(), fw[2])) + class CsNetfilter(object): + + def __intt(self): + self.rule = {} + self.table = '' + self.chain = '' def parse(self, rule): - rule.replace('! -', '!_-') + self.rule = self.__convert_to_dict(rule) + + def __convert_to_dict(self, rule): + rule = rule.replace('! -', '!_-') + # -m can appear twice in a string + rule = rule.replace('-m state', '-m2 state') bits = rule.split(' ') - self.rule = dict(zip(bits[0::2], bits[1::2])).iteritems() + rule = dict(zip(bits[0::2], bits[1::2])) + if "-A" in rule.keys(): + self.chain = rule["-A"] + return rule -if __name__ == "__main__": + def set_table(self, table): + if table == '': + table = "filter" + self.table = table + + def get_table(self): + return self.table + + def set_chain(self, chain): + self.chain = chain + + def get_chain(self): + return self.chain + + def get_rule(self): + return self.rule + + def to_str(self): + return ', '.join("%s=%r" % (key,val) for (key,val) in self.rule.iteritems()) + + def equals(self, rule): + if rule.get_table() != self.get_table(): + return False + if rule.get_chain() != self.get_chain(): + return False + for r in rule.get_rule(): + if not r in self.get_rule().keys(): + return False + if rule.get_rule()[r] != self.get_rule()[r]: + return False + return True - t = CsNetfilters() - print t.hasTable('mangle'); - print t.hasChain('mangle', 'PREROUTING'); diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index d727a2da92b..cc9a4a91b75 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -27,7 +27,7 @@ import shutil import os.path from cs_ip import merge import CsHelper -import CsNetfilter +from CsNetfilter import CsNetfilters fw = [] @@ -219,7 +219,7 @@ class CsPasswdSvc(CsApp): def setup(self): fw.append(["", "front", - "-A INPUT -i %s -d %s -p tcp -m tcp --state NEW --dport 8080 -j ACCEPT" % (self.dev, self.ip) + "-A INPUT -i %s -d %s/32 -p tcp -m tcp -m state --state NEW --dport 8080 -j ACCEPT" % (self.dev, self.ip) ]) proc = CsProcess(['/opt/cloud/bin/vpc_passwd_server', self.ip]) @@ -252,7 +252,7 @@ class CsApache(CsApp): CsHelper.service("apache2", "restart") fw.append(["", "front", - "-A INPUT -i %s -d %s -p tcp -m state --state NEW --dport 80 -j ACCEPT" % (self.dev, self.ip) + "-A INPUT -i %s -d %s/32 -p tcp -m state -m tcp --state NEW --dport 80 -j ACCEPT" % (self.dev, self.ip) ]) class CsDnsmasq(CsApp): @@ -261,16 +261,16 @@ class CsDnsmasq(CsApp): def add_firewall_rules(self): """ Add the necessary firewall rules """ - fw.append(["", "front" + fw.append(["", "front", "-A INPUT -i %s -p udp -m udp --dport 67 -j ACCEPT" % self.dev ]) - fw.append(["", "front" - "-A INPUT -i %s -d %s -p udp -m udp --dport 53 -j ACCEPT" % (self.dev, self.ip) + fw.append(["", "front", + "-A INPUT -i %s -d %s/32 -p udp -m udp --dport 53 -j ACCEPT" % (self.dev, self.ip) ]) - fw.append(["", "front" - "-A INPUT -i %s -d %s -p tcp -m tcp --dport 53 -j ACCEPT" % ( self.dev, self.ip ) + fw.append(["", "front", + "-A INPUT -i %s -d %s/32 -p tcp -m tcp --dport 53 -j ACCEPT" % ( self.dev, self.ip ) ]) def configure_server(self, method = "add"): @@ -360,8 +360,8 @@ class CsDevice: if " DOWN " in i: cmd2 = "ip link set %s up" % self.dev CsHelper.execute(cmd2) - cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-mark 0x%s" % \ - (self.dev, "Table_%s" % self.tableNo) + cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-xmark 0x%s/0xffffffff" % \ + (self.dev, self.dev[3]) fw.append(["mangle", "", cmd]) @@ -428,16 +428,14 @@ class CsIP: "-A POSTROUTING -s %s -o %s -j SNAT --to-source %s" % \ (self.address['network'], self.dev, self.address['public_ip']) ]) - fw.append(["", "", "-N %s" % devChain ]) - fw.append(["mangle", "", "-N %s" % devChain ]) fw.append(["mangle", "", "-A %s -j ACCEPT" % devChain]) fw.append(["", "", "-A FORWARD -o %s -d %s -j %s" % (self.dev, self.address['network'], devChain) ]) - fw.append(["", "", "-A DROP -j %s" % devChain]) + fw.append(["", "", "-A %s -j DROP" % devChain]) fw.append(["mangle", "", - "-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s -j %s" % \ + "-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s/32 -j %s" % \ (self.dev, self.address['network'], self.address['public_ip'], devChain) ]) dns = CsDnsmasq(self) @@ -752,7 +750,8 @@ def main(argv): acls = CsAcl('networkacl') acls.process() - pprint(fw) + nf = CsNetfilters() + nf.compare(fw) if __name__ == "__main__": main(sys.argv)