作者:Elkeid Team
公众号:灾难控制 局

此前我们已开源了自研的主机层入侵检测系统Elkeid(原AgentSmith-HIDS)端上的能力(Agent/Driver/以及部分Agent插件)。本次为Elkeid开源计划的第二部分:Server后台模块。

目前,Elkeid完整版本部署规模已达到100万量级,其稳定性/性能/数据采集能力/检测能力/溯源能力等均得到了实战验证,均有不俗表现。

我们希望通过开源的方式和大家分享我们踩过的坑,向优秀同行学习,回馈行业。

关于 Elkeid Server

Elkeid Server 需要配合端上的数据采集层(Elkeid Driver/Agent)一起使用,实现了对大规模Agent的监控,管理和策略更新。能适配各种复杂的网络环境,可单机也可集群部署。具体部署方案,请移步Repo查看。

开源地址:https://github.com/bytedance/Elkeid/tree/main/server

开源协议:Apache-2.0

Elkeid Server 组件简介

Elkeid Server 架构如下:

Elkeid Server 大体包含4个模块:

  • AgentCenter:负责与Agent进行通信,采集Agent数据并简单处理后汇总到消息队列集群,同时也负责对Agent进行管理包括Agent的升级,配置修改,任务下发等。

  • ServiceDiscovery:后台中的各个服务模块都需要向ServiceDiscovery中心定时注册、同步服务信息,从而保证各个服务模块中的实例相互可见,便于直接通信。

  • Manager:负责对整个后台进行管理并提供相关的查询、管理接口。

  • 实时/离线计算模块:消费server采集到消息队列中的数据,进行实时和离线的分析与检测。(此部分还未开源)

简单来说就是:

  • AgentCenter收集Agent数据

  • Manager管理着AgentCenter和这些计算模块

  • ServiceDiscovery把这些所有的服务、节点都串联了起来

  • 实时/离线计算模块对这些数据进行分析和检测

本次开源部分是架构图中的AgentCenter、ServiceDiscovery和Manager三部分。

产品优势

  • 百万级Agent的后台架构解决方案

  • 分布式,去中心化,集群高可用

  • 部署简单,依赖少,便于维护

资源需求参照表

技术细节

Elkeid AgentCenter(下面简称AC)

AC一方面需要从Agent采集数据并进行初步处理,然后把处理后数据写入Kafka集群(供后续分析模块消费),另一方面要向Agent下发指令,这个通信是双向的。

同时AC也对外提供HTTP接口,Manager通过这些HTTP接口实现对AC和Agent的管理和监控。

示意图:

相关技术介绍:

  • 通信效率:在百万级Agent的情况下,如此大量级的数据对后端的压力不容小觑。而通信和处理效率主要受通信协议和编码方式的影响。对比各种通信方式,我们最终选择使用gRPC双向流的方式。

    • 一方面gRPC基于HTTP2协议标准设计开发,相对于其他RPC框架,gRPC带来了更多强大功能,如双向流、头部压缩等。这些都很好的符合我们现在的需求,同时通信效率也很高。

    • 另一方面我们采用Protobuf作为编码方式。Protobuf具备了标准的IDL和IDL编译器,同时序列化数据非常简洁,紧凑;另外编解码速度在众多序列化协议中也处于领先。

  • 通信安全性:Agent是具备root权限的应用,Server具备对Agent下发指令的能力,如果通信链路被控制,将是灾难性的。这里我们使用了双向SSL校验,一方面保证了Agent/Server不会与未知的对端通信,另一方面SSL也保证了通信过程数据都是加密的。

Elkeid Service Discovery(下面简称SD)

服务发现/负载均衡机制大致两个设计思路,一个集中代理,一个是端代理。

集中代理方式例如F5、nginx,请求先发送到集中代理点,代理再根据一定的负载均衡算法进行转发,服务的响应也会先到代理点,再转发到请求端。这个方式虽然是最常见的,但有两个问题,一个是经过代理来回转发,请求响应的时延会增加,另一个是在大规模Agent请求下,代理点的负载压力太大,因此在大规模部署的环境下不能使用这个方案。

端代理方式需要一个服务发现注册中心的服务,如下:

示意图:

相关技术介绍:

  • 服务提供方定时向SD发送注册信息,包括服务名字,实例ip,端口,负载状态等,这样SD就维护着所有这个服务实例的状态。

  • SD这个服务中的各个节点间需要进行数据同步,例如上面1中注册信息发送到NodeA上,NodeA需要把这个信息同步给NodeB,这样如果有请求访问NodeB,NodeB也有对应的注册信息。

  • 服务使用方通过服务名,请求服务发现/注册中心,获取对应服务名下能使用的实例IP、端口列表,进而可以直接访问。

  • SD各个节点间的数据同步是以广播的方式批量同步,保证了一定的性能。某个时间点节点间的数据并不是一致的,但最终能保持一致,满足分布式CAP理论中的AP,在大规模Agent,AC场景下,并没什么影响。此外也没用到任何一致性中间件(etcd,zookeeper等),部署方便,维护简单。

  • 由于SD维护了各个注册服务的状态信息,所以当服务使用方在请求服务发现时,SD会进行负载均衡。比如Agent请求获取AC实例列表,SD直接返回负载压力最小的AC实例。

Elkeid Manager

Manager管理整个后台,并提供各种查询、管理接口。包括管理AC集群,监控AC状态,控制AC服务相关参数,并通过AC管理所有的Agent,收集Agent运行状态,往Agent下发任务,同时manager也管理实时和离线计算集群。

鉴于Manager管理着后台的各个集群,所以任何的管理操作都是对集群的操作,调用Manger的接口请求会通过Manager转发给目标集群所有的节点,然后再收集所有节点的响应,再进行处理。为了提升这个过程的响应速度和稳定性,Manager内部实现了一个简单的分布式任务管理系统。

示意图:

相关技术介绍:

  • Manager向集群发送请求,为提高并发能力,会启动多个协程同时下发。

  • Manager本身也是个集群,同一个任务Manager节点间也会进行同步,进一步提升任务下发的并发能力。例如,10个manager节点要操作一个1000个节点的集群,一个操作指令会同步到10个manager节点,每个节点可以启动100个协程并发的向1000个节点下发操作命令。

  • 返回的结果会在全局的存储和缓存里进行处理、汇总。

  • 当前支持的功能有:

    • Agent管理:Tags

    • Agent任务下发:分布式任务下发,并行处理,重试

    • AC负载均衡控制:根据AC负载,动态调整AC连接数

    • Agent状态采集和统计

    • Agent任务查询与对账

Elkeid Agent版本更新

之前的Elkeid Agent受限于Server没有开源,提供受限的数据传输能力(kafka),所以裁剪了较多功能(主要是与数据传输、指令下发、插件配置相关)。

在这次Server开源之后,Agent也一同进行了更新,在使用新版本Agent时请注意以下四点:

1.编译Agent所需的Go编译链升级到了1.16

在最新版本Agent中用到了1.16编译链的go embed功能,另外优化了内存使用情况,详情查看:https://golang.org/doc/go1.16

2.编译前对通信相关的安全证书、参数进行配置

agent/transport/connection 目录中的ca.crt、client.key、client.crt分别是自签名的ca证书,客户端私钥,客户端证书,请与Server生成证书时一同替换修改。product.go中可以配置与Server通信的地址,并支持复杂网络情况下的通信配置,具体请查看Agent的readme。

3.功能插件的开启与关闭不再依赖config.yaml,通过Manager API动态下发

每个Agent默认是空配置,不具备任何安全能力,只承载控制/通信/自身监控能力。如果需要开启安全功能,需要通过相应API进行配置并下发插件,配置将会持久化存储在后端,并在连接建立时自动下发。进一步,可以通过下发配置对Agent进行自升级(需要被守护拉起),或者升级指定功能插件。

4.请自行选用合适的守护/自保护方式,并置于后台执行

推荐采用systemd托管服务,并加入cgroup限制资源使用,设置进程工作目录等,否则可能会出现自升级等功能异常的情况。

后续计划

Elkeid 会长期维护更新;且后续会陆续开源更多Agent Plugin以及RSAP。

我们计划22年4月底/五月初在飞书群【 Elkeid 交流群】举行一次线上的技术交流,主要内容是Elkeid Server开源版本的设计实现细节和代码结构等,欢迎大家关注。

致谢及交流

非常感谢项目开发/推动过程中相关团队/同学的支持与帮助。

欢迎大家通过GitHub或飞书群【 Elkeid 交流群】进行交流讨论和建议反馈。

Elkeid项目地址: https://github.com/bytedance/Elkeid

飞书群二维码:


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1566/