zoukankan      html  css  js  c++  java
  • 防火墙ACL配置自动化

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

    这样,即可开展后续的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 (.*?)
     (?:host|subnet) (.*?)
    )', self.buff, re.M)
            # configs = re.findall(r'^(object network (.*?)
     (?: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 .*?
    (?=S)', self.buff, re.M | re.S)
            for conf in configs:
                conf = conf.group()
                members = re.findall(r'network-object (?:host )?(.*?)
    ', 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 (.*?)
    ', 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
    

      

    未完待续

  • 相关阅读:
    【html】页面制作规范文档
    【jquery】blockUI 弹出层
    前端攻城师所要掌握的知识和技能
    【html】edm 邮件制作指南
    【css】教你如何写出高效整洁的 css 代码——css优化
    前端开发神器notepad++以及zen coding神级插件
    百度统计流量研究院——了解互联网行业基本数据分布和趋势
    【css】我的 css 框架——base.css
    通过扩展方法 链式方法 为MVC 3 视图添加验证
    使用正则表达式抓取博客园列表数据
  • 原文地址:https://www.cnblogs.com/guxh/p/15182670.html
Copyright © 2011-2022 走看看