共计 5236 个字符,预计需要花费 14 分钟才能阅读完成。
概要
1. 分布式安全服务编排概念
2. 须弥 (Sumeru) 关键实现思路
3. 应用场景
前言
在笔者理解,安全防御的本质之一是增加攻击者的攻击成本,尤其是时间成本,那么从防御的角度来说,如何尽早和及时地发现潜在的安全风险变得尤为重要,因此安全扫描对时效性要求很高。在进行自身检测的同时,数以万计攻击者也在时刻探测着你的安全风险,乐观者可能不以为然,但事实上做安全就是木桶原理,短板是攻击者的首选。如果加上验证程序开发和落地的时间开销,可能又会造成一定的发现时延。有时候出了问题,就要与时间赛跑,及时避损或止损。
另外,分布式技术一直以来被用于解决单机性能瓶颈,而且像漏洞扫描器这类安全产品开发者对分布式这个概念也一直有着很深的执念,因为在漏报率和误报率达到某种瓶颈之后,扫描速度成为了另外一个突破口。
安全扫描周期较长也是我们在之前实际工作中遇到的痛点,加上安全防御是整个面而不是单个点,所以想要形成面,需求真的是不要太多,所以扫描工具研发和运维成本较高的问题也同样令人头秃,借此,本文为大家介绍宜信安全团队应用分布式安全服务编排的实践经验,虽说依然存在许多不足之处,但也达成了不少预期效果,总之,希望大家能有所收获或参考。
需求简述
缩短安全扫描周期
举例:端口扫描周期较长,目标:10000+ 个 IP,全端口 + 服务指纹扫描,从 7 小时优化到 30 分钟内。Masscan 做端口扫描要保持稳定的速率(根据实际不同的网络环境而定),否则会造成大量的漏报,所以单机多进程方案并不可靠。
充分发挥服务器 I / O 和计算资源
降低扫描工具研发和运维成本
提供应用开发机制,支持一键导入导出和版本管理。
通过可视化操作,将安全任务灵活编排成扫描流程。
满足日常需求快速上线和迭代,如情报收集,目标监控,特定扫描等等
提供 SDK 和 Restful API,方便其他平台进行调用
安全服务编排
有的同学可能对安全服务编排比较陌生,先来简单解释下:服务编排是微服务体系里的概念,编排(Choreography)指通过消息的交互序列来控制各个部分资源的交互。而参与交互的资源都是对等的,没有集中的控制。
安全服务编排我们可以理解为 通过一系列独立安全服务相互调用构成的工作流,如下图所示,每一个方框都代表着一个独立的安全服务,通过互相调用,形成了一个完整工作流。
通常,安全风险检测就是一个完整工作流,而不是单一的功能模块,如上图所示,我们做端口扫描的目的除了用于检测高危暴露端口之外,还会用于作为弱口令扫描,PoC 扫描等等的扫描目标,扫描完之后可能还需要继续进行过误报处理或通知告警等行为。现实中开源和商业的安全产品 (工具) 数量都很多,功能也比较参差不齐,我们大多需求都是希望能将他们部分功能进行组合,所以我们的做法是将安全产品 (工具) 抽象成应用形式的安全服务,举例来说,业界比较出色的两款端口扫描工具都具备各自的优势:
Masscan,高速无状态端口扫描
Nmap,具备丰富服务指纹扫描
我们如何将这两种工具的特性结合为我们所用?现有常见的做法一般是通过像 Python 这种胶水语言把他们粗暴地整合在一起,而这样一来,出现了整合成本较大的问题,具体来说主要有两方面:
难以灵活组合以及复用
扫描规模受限
而另外一种情况,具备自研能力的甲方团队,由于研发成本的考虑,大多都采用了开源工具进行二次开发,所以将工具们通过编码的方式深度集成,带来的开发代价是无疑是巨大的,那么有没有稍微优雅一些的解决方案呢?下面我们来看看编排的特点:
编排的关键在于流程 + 适配,
流程是将各个任务串成一个工作流
适配是把任务之间的数据打通
看起来编排似乎能解决我们的一部分问题,为了更为方便地实现和验证上述概念,我们使用 Python 开发了须弥 Sumeru 分布式任务调度框架,须弥脱胎于宜信的分布式扫描器摘星,将底层分布式任务执行逻辑进行抽离。
须弥 Sumeru 实现了可视化拖拽的编排概念,无论是在设计阶段还是结果展示阶段我们都可以通过一个树形结构来观察我们的任务执行情况,下图为须弥任务编排的编辑界面截图,可以将不同的应用通过拖拽的方式进行任意编排,下图就是一个日常的综合扫描计划任务,将 IP 解析,Masscan 端口扫描,Nmap 服务指纹扫描,敏感目录扫描,PoC 扫描整合成了一个完成的工作流:
同时提供了树形结果展示界面,会实时刷新任务执行状态,为用户提供一个直观的任务执行概况,不同的任务状态会体现在点的颜色上:
须弥 Sumeru 分布式任务框架实现思路
根据 Imperva 对 GitHub 代码库的调查数据表明,目前的 GitHub 代码库中,有超过 20% 的网络攻击工具或 PoC 代码都是采用 Python 编写的,Python 变成了黑客开发网络攻击工具时的首选语言。须弥承载了一些已有工作的优化期待和对之后工作的愿景,同时也参考了很多已有的分布式任务调度框架如 Python 实现的 Celery,Java 实现的 XXL-job 和 Elastic-job 等,发现并没有能很好满足我们的需求。同时,很大部分常用的开源安全工具都是由 Python 实现或有 Python 实现的调用类库,所以基于 Python 实现的分布式任务调度框架成为了须弥的目标定位,下面为大家介绍比较关键的几个功能点,同时贴出功能架构图供大家参考。
应用 - 安全即服务(Security as a Service)
重新创造一个已有的或是已被其他人优化的基本方法,在业界大家都称之为造轮子,所以复用的意义即如何避免重复造轮子,也就是将重复性的工作更通用地抽象出来,我们的需求很简单,就是将功能各异的工具变成可复用的轮子, 这与微服务的思想如出一辙,但又有稍许不同,光有轮子还不行,我们需要让轮子转起来,先说说我们如何将轮子转起来, 关键的步骤主要有两点:
转化,即应用开发— 将第三方工具的交互接口抽象成应用。
组装,即编排设计— 设计应用之间的调用关系。
应用开发是落地实施的第一步,所以须弥设计了应用中心的功能,方便对应用进行版本管理和分发,同时提供应用一键导入导出。如应用中心截图所示:
应用的概念让安全服务或工具具有独立性,更适合进行维护和开发迭代。
核心实现:任务分片和失效转移(Failover)
这里提到了传统分布式任务调度框架实现过程中很关键的两个概念: 任务分片和失效转移,前者为了提升性能,后者为了提高可用性。
任务分片
任务分片就是将一个较大规模的任务进行更细力度的数据并行,来提升整个系统的吞吐量,对分布式性能的提升起到了至关重要的作用。那么到底什么是任务分片呢?我们下面举个例子来说明一下:
假设我们有 2 个扫描目标 IP:192.168.1.1 , 192.168.1.2,
2 个用户名:admin,guest,
2 个密码:123456,111111,如下所示:
target 192.168.1.1 , 192.168.1.2
username admin,guest
password 123456,111111
如果设置了切片选项,Sumeru 会使用笛卡儿积计算来支持任务分片,分片后:2 2 2 = 8 共 8 个分片
192.168.1.1,admin,123456192.168.1.1,admin,111111192.168.1.1,guest,123456192.168.1.1,guest,111111192.168.1.2,admin,123456192.168.1.2,admin,111111192.168.1.2,guest,123456192.168.1.2,guest,111111
如果没有分片,这 8 个任务只能作为一个整体,无法分配到各个执行节点上分布式执行,而且无法更细粒度地进行失效转移,任务分片后,须弥会根据编排和分片结果生成一个用于保存任务状态的任务树,并根据基于负载均衡等多种调度算法来进行任务分配执行节点。
失效转移
失效转移(Failover) 又称故障切换,指系统中其中一项设备或服务失效而无法运作时,另一项设备或服务即可自动接手原失效系统所执行的工作,在须弥用于保障任务执行过程中的执行状态。
我们设计以下两种情况会触发失效转移,如下图所示(红色代表异常状态):
任务出现异常,包括任务管理器捕获的异常和用户主动抛出的异常。
执行节点出现异常。
我们这里有一个实际应用场景,实现了自适应内外网域名端口扫描,后文会有介绍。
Sumeru 还支持设置超时,如果超出指定时限会被视为任务出现异常,防止任务由于未知原因导致的挂起。
守护模式
守护任务模式,适用于对外提供服务的场景,如风控规则引擎这类,是基于数据并行的数据处理类应用,分布式节点会明显提高其性能。
具体来说就是守护进程(线程)模式,用户可以根据实际场景来选择线程或进程模式,所以我们统称为守护模式。
常规任务一般是一次执行完毕或周期性计划任务执行,而在一些场景下,我们却希望任务一直保持运行状态,对外提供服务类应用(如被动扫描的代理应用,提供 HTTP 服务应用),像实时数据处理类应用(如风控规则引擎),与常规任务不同的是,我们要能尽可能地保证这些任务的存活状态,如果任务勾选了守护模式,调度中心会保证该任务在分组内有且只有一个任务实例运行,如果节点出现异常,将会进行失效转移到其他节点。
须弥提供了分发选项,如果勾选,将会在节点分组内每个节点上保证有且只有一个任务实例。
其他特性
其他特性也简单做一下列举:
基于 ETCD 实现的 Scheduler – HA,为保证整个调度中心的高可用,我们基于分布式 K - V 系统 ETCD 进行了高可用实现
并发支持: 提供线程和进程不同粒度任务执行
秒级计划任务, 支持自定义计划任务扩展(如 @hourly,@weekly)
提供应用开发套件:基类,调试,部署,版本管理
提供 SDK 和 RestfulAPI 以及完整的授权机制
支持邮件通知,数据备份,日志 ElasticSearch 接入等
异步实现
Python2/ 3 兼容
支持 Web 控制台形式查看执行日志查看,如下图所示:
其他特性包括任务生命周期的管理,应用可用性检测,安全通信等,限于篇幅不此详述。
应用场景举例
须弥在设计之初就是为了解决一些场景下的问题,所以也将这些应用场景简单做下介绍。
1、端口扫描为任务分片提升扫描性能
性能提升 : Python 的性能确实比较低,但大多是计算密集型的场景会产生瓶颈,像安全扫描这种 IO 密集型的还是不会产生太大的影响,在前文已经介绍过分片的原理,这里我们拿具体数据来测试一下,切片 + 分布式的性能提升状况。我们拿端口扫描为例,10000+ 个 IP,进行全端口 + 服务指纹扫描,如图所示,节点 {1,3,6,9} 分别耗时{25220.28, 5386.728 , 3076.681 ,1624.101} (秒), 优化到之前时间消耗的 6.4%。
2、失效转移自适应网络环境
扫描过程中遇到某个节点网络不通或网络不稳定的情况,会转移到同分组内其他节点继续执行,直到所有任务可以正常运行, 如下图所示。
3、需求快速上线
须弥提供了一套完整的应用快速开发和上线流程。
现有大多数甲方的安全平台实际需求都是综合性比较强的平台,所以常常被做成一个大而全的工具集合,大多包括扫描工具(Web 扫描,被动扫描,主机扫描,端口扫描,Git 泄漏扫描),威胁情报,知识库等等。大而全的同时,也带来的维护成本的增加,比如突然新来一个需求:监控暗网交易情报,乍一看属于威胁情报,但又与原来的威胁情报格式,使用和部署方式都完全不一样。开发小哥可能只能无奈地在威胁情报的子菜单里新增一个功能,埋头去开发了。这样的需求不在少数,最后整个平台越来越臃肿难以维护。
如果使用应用开发方式,我们可以将功能抽象成一个应用,只需进行应用编写,上线分发,远程调用即可,把服务和平台二者分离出来,同时也更加方便团队协同的维护。
须弥提供的 Restful API 使得应用作为服务集成在 CI/CD(持续集成 / 持续部署)的过程中更加容易,使用 Python 来实现,对 Python 生态支持也比较友好。如果有同学遇到比较合适的场景的话,欢迎与我们一起多多交流。
总结
能避免重复造轮子,能将一部分精力集中在业务专业能力的提升上是我们的初衷,须弥将分布式安全服务编排的思想基本上都实现了,性能和稳定性上的还有不小的提升空间,期待它能发挥更多的价值。
感谢一起付出努力的小伙伴们!本文之后会有同事继续分享相关内容,敬请期待。
作者微信号: lfzark (添加请注明来意),欢迎大家一起交流,共同进步。
一个想法的落地需要一系列的技术和资源的去支撑,在甲方公司的安全部门沉下心来打磨安全产品实为不易,感谢那些甚至做出媲美乙方产品的大神们,为我们提供学习的榜样。
宜信安全应急响应中心(CESRC)网址为:https://security.creditease.cn,该平台旨在集合安全领域的专家、社会团体及个人共同发现潜在的漏洞信息,为宜信全线产品和业务安全保驾护航,促进白帽子、安全团队和安全爱好者们与宜信的直接交流与合作,减少、降低可能存在的各类安全隐患。
宜信技术学院