diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py index 93be03ac95a..1a076967e9e 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py @@ -65,6 +65,80 @@ class CsAcl(CsDataBag): Deal with Network acls """ + class AclIP(): + """ For type Virtual Router """ + + def __init__(self, obj, fw): + self.fw = fw + self.direction = 'egress' + if obj['traffic_type'] == 'Ingress': + self.direction = 'ingress' + self.device = '' + self.ip = obj['src_ip'] + self.rule = obj + self.rule['type'] = obj['protocol'] + # src_port_range + if 'src_port_range' in obj: + self.rule['first_port'] = obj['src_port_range'][0] + self.rule['last_port'] = obj['src_port_range'][1] + self.rule['allowed'] = True + self.rule['cidr'] = obj['source_cidr_list'] + self.rule['action'] = "ACCEPT" + + def create(self): + for cidr in self.rule['cidr']: + self.add_rule() + if self.ip != '': + # Always append default drop + self.fw.append(["mangle", "", "-A FIREWALL_%s -j DROP" % self.ip]) + + def add_rule(self, cidr): + icmp_type = '' + rule = self.rule + icmp_type = "any" + if "icmp_type" in self.rule.keys() and self.rule['icmp_type'] != -1: + icmp_type = self.rule['icmp_type'] + if "icmp_code" in self.rule.keys() and rule['icmp_code'] != -1: + icmp_type = "%s/%s" % (self.rule['icmp_type'], self.rule['icmp_code']) + rnge = '' + if "first_port" in self.rule.keys() and \ + self.rule['first_port'] == self.rule['last_port']: + rnge = self.rule['first_port'] + if "first_port" in self.rule.keys() and \ + self.rule['first_port'] != self.rule['last_port']: + rnge = "%s:%s" % (rule['first_port'], rule['last_port']) + if self.direction == 'ingress': + if rule['protocol'] == "icmp": + self.fw.append(["mangle", "front", + " -A FIREWALL_%s" % self.ip + + " -s %s " % cidr + + " -p %s " % rule['protocol'] + + " -m %s " % rule['protocol'] + + " --icmp-type %s -j %s" % (icmp_type, self.rule['action'])]) + else: + self.fw.append(["mangle", "front", + " -A FIREWALL_%s" % self.ip + + " -s %s " % cidr + + " -p %s " % rule['protocol'] + + " -m %s " % rule['protocol'] + + " --dport %s -j RETURN" % rnge]) + if self.direction == 'egress': + if rule['protocol'] == "icmp": + self.fw.append(["filter", "front", + " -A FIREWALL_EGRESS_RULES" + + " -s %s " % cidr + + " -p %s " % rule['protocol'] + + " -m %s " % rule['protocol'] + + " --icmp-type %s -j %s" % (icmp_type, self.rule['action'])]) + else: + fwr = " -A FIREWALL_EGRESS_RULES" + \ + " -s %s " % cidr + if rule['protocol'] != "all": + fwr += "-p %s " % rule['protocol'] + \ + " -m %s " % rule['protocol'] + \ + " --dport %s" % rnge + self.fw.append(["filter", "front", "%s -j %s" % (fwr, rule['action'])]) + class AclDevice(): """ A little class for each list of acls per device """ @@ -93,13 +167,20 @@ class CsAcl(CsDataBag): class AclRule(): def __init__(self, direction, acl, rule, config): + if config_is_vpc(): + self.init_vpc(self, direction, acl, rule, config) + else: + self.init_vr(self, direction, acl, rule, config) + + + def init_vpc(self, direction, acl, rule, config): self.table = "" self.device = acl.device self.fw = acl.fw self.chain = config.get_ingress_chain(self.device, acl.ip) self.dest = "-s %s" % rule['cidr'] if direction == "egress": - self.table = config.get_efress_table() + self.table = config.get_egress_table() self.chain = config.get_egress_chain(self.device, ip) self.dest = "-d %s" % rule['cidr'] self.type = "" @@ -137,7 +218,10 @@ class CsAcl(CsDataBag): for item in self.dbag: if item == "id": continue - dev_obj = self.AclDevice(self.dbag[item], self.fw).create() + if self.config.is_vpc(): + dev_obj = self.AclDevice(self.dbag[item], self.fw).create() + else: + self.AclIP(self.dbag[item], self.fw).create() class CsVmMetadata(CsDataBag): @@ -469,6 +553,9 @@ def main(argv): acls = CsAcl('networkacl', config) acls.process() + acls = CsAcl('firewallrules', config) + acls.process() + fwd = CsForwardingRules("forwardingrules", config) fwd.process() diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs_firewallrules.py b/systemvm/patches/debian/config/opt/cloud/bin/cs_firewallrules.py new file mode 100644 index 00000000000..4c7a14c0136 --- /dev/null +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs_firewallrules.py @@ -0,0 +1,31 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from pprint import pprint +import copy + +def merge(dbag, data): + dbagc = copy.deepcopy(dbag) + if "rules" not in data: + return dbagc + for rule in data['rules']: + id = str(rule['id']) + if rule['revoked']: + del(dbagc[id]) + if id not in dbagc.keys(): + dbagc[id] = rule + return dbagc diff --git a/systemvm/patches/debian/config/opt/cloud/bin/merge.py b/systemvm/patches/debian/config/opt/cloud/bin/merge.py index f5ae3ef1ee8..510c58e26ac 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/merge.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/merge.py @@ -25,6 +25,7 @@ import cs_guestnetwork import cs_cmdline import cs_vmp import cs_network_acl +import cs_firewallrules import cs_vmdata import cs_dhcp import cs_forwardingrules @@ -102,6 +103,8 @@ class updateDataBag: dbag = self.processVMpassword(self.db.getDataBag()) elif self.qFile.type == 'networkacl': dbag = self.process_network_acl(self.db.getDataBag()) + elif self.qFile.type == 'firewallrules': + dbag = self.process_firewallrules(self.db.getDataBag()) elif self.qFile.type == 'vmdata': dbag = self.processVmData(self.db.getDataBag()) elif self.qFile.type == 'dhcpentry': @@ -141,6 +144,9 @@ class updateDataBag: def process_network_acl(self, dbag): return cs_network_acl.merge(dbag, self.qFile.data) + def process_firewallrules(self, dbag): + return cs_firewallrules.merge(dbag, self.qFile.data) + def processVMpassword(self, dbag): return cs_vmp.merge(dbag, self.qFile.data)