guxh

配置解析,是将不同品牌防火墙,将关键信息提取出来,解析到统一的表格中。

这样,即可开展后续的ACL策略分析,以及自动生成配置。

 

同时,这些表格数据,还可以用于其他途径,例如:

1)返回NAT信息,不用再逐一登录防火墙查询NAT信息

2)服务器下线时,提取所有关联ACL,NAT配置

3)网络运维,经常会遇到被要求查询某个地址/某个网段开过的所有策略,涉及到异构防火墙,靠人工几乎无法实现,有了统一的防火墙表格数据,就可以轻松实现

 

1,防火墙解析表格设计

分为四个表格:

address:地址表,记录每个地址组,以及其成员地址

port:端口表,记录每个端口组,以及其成员

nat:NAT表,记录防火墙映射关系

acl:策略表,记录防火墙每条acl信息,需要从address表/port表获取其成员

表格采用json格式存储

 

每张表的column字段设计如下:

address:  [\'FwName\', \'FwIP\', \'ID\', \'Zone\', \'Type\', \'Name\', \'Members\', \'Conf\']

port:  [\'FwName\', \'FwIP\', \'ID\', \'Type\', \'Name\', \'Protocol\', \'Members1\', \'Members2\', \'Conf\']

nat:  [\'FwName\', \'FwIP\', \'ID\', \'Type\', \'SrcZone\', \'DstZone\', \'SrcName\', \'SrcMembers\', \'SrcTransName\', \'SrcTransMembers\', \'DstName\', \'DstMembers\', \'DstTransName\', \'DstTransMembers\', \'Conf\']

acl:   [\'FwName\', \'FwIP\', \'ID\', \'PolicyName\', \'Action\', \'Protocol\', \'SrcArea\', \'DstArea\', \'SrcName\', \'SrcMembers\', \'DstName\', \'DstMembers\', \'PortName\', \'PortMembers1\', \'PortMembers2\', \'Conf\']

 

2,防火墙解析 - 基类

每个品牌防火墙一个类,继承自基类,目标是从不同品牌防火墙中提取基类中公共字段(四张表)。

有些内容不支持解析,对以后的防火墙配置自动化可能产生的后果:1)漏开通策略(有deny acl未被解析) 2)多开通策略(已有permit acl未被解析)

但是,如果后续都是按照自动化脚本去生成配置,那就不会存在没法解析的内容

 

不支持解析的内容有:

1)思科

address(object-network):成员是range的,没有成员的

address(object-group network):没有成员的

待补充

 

防火墙基类:

 

class BaseFw:

    ADDRESS_COLUMNS = [\'FwName\', \'FwIP\', \'ID\', \'Zone\', \'Type\', \'Name\', \'Members\', \'Conf\']

    PORT_COLUMNS = [\'FwName\', \'FwIP\', \'ID\', \'Type\', \'Name\', \'Protocol\', \'Members1\', \'Members2\', \'Conf\']

    NAT_COLUMNS = [\'FwName\', \'FwIP\', \'ID\', \'Type\', \'SrcZone\', \'DstZone\', \'SrcName\', \'SrcMembers\', \'SrcTransName\',
                   \'SrcTransMembers\', \'DstName\', \'DstMembers\', \'DstTransName\', \'DstTransMembers\', \'Conf\']

    ACL_COLUMNS = [\'FwName\', \'FwIP\', \'ID\', \'PolicyName\', \'Action\', \'Protocol\', \'SrcArea\', \'DstArea\', \'SrcName\',
                   \'SrcMembers\', \'DstName\', \'DstMembers\', \'PortName\', \'PortMembers1\', \'PortMembers2\', \'Conf\']

    def __init__(self, fw_name, fw_ip, buff, port_pres):
        self.fw_name = fw_name           # 防火墙名称
        self.fw_ip = fw_ip               # 防火墙IP
        self.buff = buff                 # 防火墙配置
        self.port_pres = []              # 防火墙的端口预配置,是个字典列表,可以从json转换而来
        for port in port_pres:
            self.port_pres.append({
                "FwName": self.fw_name,
                "FwIP": self.fw_ip,
                "ID": "",
                "Type": "",
                "Name": port.get("name"),
                "Protocol": port.get("protocol"),
                "Members1": str(port.get("port")),  # int -> string
                "members2": str(port.get("port")),
                "Conf": port.get("conf")
            })

思科端口预配置(截取部分)

[
    {
        "name": "aol",
        "protocol": "tcp",
        "port": 5190,
        "conf": "思科预配置端口:aol"
    },
    {
        "name": "bgp",
        "protocol": "tcp",
        "port": 179,
        "conf": "思科预配置端口:bgp"
    },
    {
        "name": "biff",
        "protocol": "tcp",
        "port": 512,
        "conf": "思科预配置端口:biff"
    },
    {
        "name": "bootpc",
        "protocol": "tcp",
        "port": 68,
        "conf": "思科预配置端口:bootpc"
    },
    {
        "name": "bootps",
        "protocol": "tcp",
        "port": 67,
        "conf": "思科预配置端口:bootps"
    }
]

 

 

3,防火墙解析 - 地址组解析

以思科地址组为例,解析所有地址组成员

class FwCisco(BaseFw):

    def __init__(self, fw_name, fw_ip, buff, port_pres):
        super().__init__(fw_name, fw_ip, buff, port_pres)
        self.port_pres_map = {port_pre.get("name"): port_pre.get("port") for port_pre in self.port_pres}

    @LazyProperty
    def address(self):
        items = []

        # object network
        configs = re.findall(r\'^(object network (.*?)\n (?:host|subnet) (.*?)\n)\', self.buff, re.M)
        # configs = re.findall(r\'^(object network (.*?)\n (?:host|subnet|range) (.*?))$\', self.buff, re.M)  # 支持range
        for conf, name, member in configs:
            item = [self.fw_name, self.fw_ip, \'\', \'\', \'object\', name.strip(), member.strip(), conf.strip()]
            items.append({column: value for column, value in zip(self.ADDRESS_COLUMNS, item)})

        # object-group network
        configs = re.finditer(r\'^object-group network .*?\n(?=\S)\', self.buff, re.M | re.S)
        for conf in configs:
            conf = conf.group()
            members = re.findall(r\'network-object (?:host )?(.*?)\n\', conf)
            group_objs = re.findall(r\'group-object (.*?)\s*$\', conf, re.M)
            if group_objs:  # 如果有地址组嵌套地址组, 从被嵌套的地址组中获取成员
                for group_obj in [i for i in items if i.get("Name") in group_objs]:
                    members += [i for i in group_obj.get("Members").split(",") if i not in members]
            members = \',\'.join(members)
            if not members:
                continue
            name = re.search(r\'object-group network (.*?)\n\', conf).group(1)
            item = [self.fw_name, self.fw_ip, \'\', \'\', \'object-group\', name.strip(), members.strip(), conf.strip()]
            items.append({column: value for column, value in zip(self.ADDRESS_COLUMNS, item)})
        return items

  

 

未完待续

 

分类:

技术点:

相关文章:

  • 2021-09-21
  • 2021-07-04
  • 2021-11-01
  • 2022-01-09
  • 2022-01-31
  • 2021-12-16
猜你喜欢
  • 2021-11-18
  • 2021-07-30
  • 2022-01-04
  • 2021-12-16
  • 2021-07-17
  • 2021-12-05
相关资源
相似解决方案