长亭百川云 - 文章详情

揭秘牧云插件开发者的创新之路:从无法解决的问题到“妙趣横生”

huraway

75

2023-03-31

本文将介绍牧云为什么需要插件系统。我们将探究使用插件系统的优势和挑战,并介绍我们过去使用基于 Lua 的插件系统时所遇到的一些问题和限制。此外,我们还将简要介绍未来我们打算引入基于 WASM 的插件系统的计划和期望。

这是系列文章“主机Agent插件引擎开发故事”的第一篇,后续将会持续更新。该系列文章将带领您深入探究长亭牧云团队主机Agent插件引擎的开发历程,内容涵盖技术选型、插件接口设计、组件通信框架等多个方面,并详细讲解背后的原理和实现方式,无论您是网络安全专业人员还是对技术开发感兴趣的读者,都可以从中得到收获。我们希望通过分享在开发过程中面临的挑战、解决方案以及实践经验,提供深入见解和有价值的技术参考,帮助读者了解如何构建高效可靠的安全产品,共同推动安全技术社区的发展。

I. 为什么要做牧云

主机安全产品最基础的部署架构

牧云是长亭的主机安全产品,主要产品定位是基于Agent的深度服务器工作负载安全平台,大致归类于主机安全(HIDS)和云工作负载保护平台(CWPP)。与防火墙、扫描器等安全产品定位不同的是,牧云以服务器主机为单位,将一个 Agent 程序部署在服务器内部,通过深入服务器内部监测和分析服务器的行为,可以做到以最准确、最及时的手段和方法获知服务器的安全状态。

长亭牧云主机安全管理平台架构

牧云的主要目标是为甲方安全负责人提供一种统一管控大规模服务器安全状态的解决方案,同时需要适应本地部署、公有云部署、混合云部署等复杂场景下的主机安全需求。

II. 什么鬼,这是无法解决的问题

牧云需要插件系统

作为牧云最核心的系统,智能、轻量、安全、兼容、稳定Agent 设计的核心目标。在这个目标下进行 Agent 程序设计需要满足很多相互约束、看似不可能同时满足的条件。例如:

  1. 既要轻量,也要高性能:高性能往往需要占用较多的资源,而轻量化设计则意味着要尽可能地减少资源占用。
  2. 既要安全,也要灵活:安全通常需要实施限制和约束,而灵活性则要求系统能够根据不同的需求和情况做出不同的响应。
  3. 既要实时,也要稳定:实时性往往需要牺牲一定的稳定性,而稳定性则可能影响实时性能够得到保障。
  4. 既要智能,也要可控:智能系统往往会具有一定的自主决策和执行能力,而可控性则要求系统受到管理员的控制和干预。
  5. 既要节省资源,也要实时:保证实时性需要系统能够保证随时调用足够的资源,而节省资源则要求不能占用这些资源。

装逼

其实从一开始我们就都知道,上面这些东西过于理想化了,很难真正实现,更何况眼前明晃晃就摆着一种极其朴素的逃课方式。

这种朴素的设计方式就是,通过扫描和命令执行来提供基础的安全能力。市面上也确实存在一部分通过这种方式实现的主机安全系统。这种方式存在以下几个限制:

  1. 不够智能化:扫描和命令执行需要人工编写具体的扫描规则和命令,不能自适应地对安全事件进行检测和处理。
  2. 重量级:扫描和命令执行需要占用大量系统资源,因此会对系统性能造成不良影响,降低系统的稳定性和可靠性。
  3. 安全性不够高:扫描和命令执行容易受到攻击和绕过,安全性也很成问题。
  4. 兼容性差:扫描和命令执行需要依赖特定的操作系统版本和二进制版本,难以应对各种不同的安全场景。

也许有些人认为只要能用就行了,但显然这种粗暴的形式是无法满足这些苛刻到近乎变态的设计目标的,所以我们决定不妥协。虽然这看起来像是一个“无法解决的问题”,但成年人都知道既要也要

为了使 Agent 程序达到稳定、灵活、可拓展的设计目标,我们在早期做过非常多探索,最终确定了一条准则。简单来说,就是在 Agent 程序设计中需要分离出安全业务能力和安全基础能力,从而做到在保证安全能力灵活可拓展的同时保持核心系统持久稳定。由 Agent 提供基础支撑,并通过插件系统实现具体安全检测算法,就是这条准则的具体体现。

长亭的安全理念认为,任何单一安全产品都不能彻底解决安全问题,多产品、多角度联合的“塔防体系”是必然发展方向。而安全的主动权应该交还给甲方,因为只有甲方最了解实际的安全需求。即乙方提供基础设施、框架和工具,甲方根据需求使用乙方提供的设施和工具进行灵活扩展,解决问题。插件系统就为这种安全理念的落地准备好了充分的土壤。

分离安全业务能力和安全基础能力

分离安全业务能力和安全基础能力是为了提高系统的灵活性和可扩展性。

在安全产品中,安全业务能力指的是具体的安全检测算法和策略,包括资产清点、病毒扫描、漏洞检测、入侵检测等。而安全基础能力则是指系统提供的基础设施和工具,如数据采集、插件管理、日志管理、网络通信等。

将安全业务能力和安全基础能力分离后,可以实现不同安全业务能力的模块化开发和部署,从而实现安全业务能力的灵活扩展和定制,同时提高系统的稳定性和可靠性。此外,通过插件系统,还可以实现安全业务能力的动态更新和升级,从而适应不断变化的安全威胁和攻击手段。

插件系统的优势主要包括以下几个方面:

  1. 保持主程序代码的简洁和稳定:可以将一些功能单独实现在插件中,避免 Agent 程序的代码过于臃肿和复杂,从而提高代码的可维护性,同时也可以减少因 Agent 程序代码变动变动而带来的稳定性风险。
  2. 灵活升级和扩展功能:可以方便地添加、升级和替换插件,从而实现功能的快速扩展和升级,做到快速迭代安全能力,第一时间跟进最新安全事件,提供最前沿的安全检测能力。
  3. 避免影响业务稳定性:可以独立地修改和升级插件,而不会对主程序造成影响,从而保证 Agent 的稳定性和可靠性。
  4. 便于限制安全业务对系统的影响:可以方便地对插件进行限制和隔离,从而避免安全业务对系统性能和稳定性造成不良影响。

III. “妙趣横生”的开始

插件系统的挑战

虽然说了这么多好处,但要真正落地给出一个高性能的实现,仍然是一条充满挑战的漫漫长路。要解决这条路上的困难,首先就要考虑清除插件系统的设计和实现中的以下问题:

  1. 统一接口设计Agent 需要为插件提供操作系统和安全事件的统一接口,并考虑 API 的稳定性和兼容性。
  2. 跨平台抽象Agent 需要提供跨平台抽象,使开发聚焦安全业务的插件时不必考虑不同平台的差异。
  3. 插件的调度、限制和隔离机制:为了保证插件的安全性和稳定性,需要对插件进行调度、限制和隔离,从而避免插件对系统的不良影响。
  4. 插件通信方式:插件需要与主程序进行通信,如果通信开销过高,会导致系统性能下降,从而影响系统的稳定性和可靠性。
  5. 插件的更新机制:插件通常需要经常更新和维护,这需要开发人员具有一定的技术能力和经验,同时需要建立有效的更新和维护机制,从而保证插件的稳定性和可靠性。

巧妙且时髦的解决方案

Go-LNG-Lua

为了便于实现 Agent 程序的跨平台设计目标,当前使用了 Go 语言进行开发,试图借助 Go 语言跨平台编译的基础设施降低 Agent 程序的开发和维护成本,并且在项目早期非常有帮助。使用 Go 语言开发的另外两个重要原因是:

  1. 我们有使用 Go 开发的成功产品,而牧云的早期团队很大一部分成员来自于这个产品。
  2. 那个时候 Go 是一个新兴的时髦技术,当时长亭全公司从上到下全都是激进的技术爱好者。

为了达到插件程序的灵活、高效的设计目标,插件的开发语言做过许多考虑,包括 Python 的嵌入式版本和 JavaScript 都是我们仔细考虑过的。这两个都是我们熟悉而且生态极其丰富的编程语言,但遗憾的是距离理想中的设计目标还有不小的距离。通过进一步对整个插件生态进行仔细研究,最终我们认为结合我们整体的设计目标,选择插件开发语言的标准对我们来说最重要的应该是“稳定”“简单”和“”。因为“稳定”是安全产品的核心目标,“简单”可以让代码逻辑直面业务避免无谓的干扰;“”帮助我们更好地达到“轻量”且“高性能”的目标。

所以我们在最初使用了在这三点上做到极致了的 Lua 作为插件开发语言。为了更快,底层 Lua 虚拟机使用 LuaJIT。后来,这种过分的简单性带来了一些坑,为了解决可维护性问题转型到了带类型的 Lua 方言,即 CtLua。关于 CtLua 的故事,在【主机安全|开发避坑奇旅】中我们曾经详细分享过。简单来说是脚本语言的动态性给了我们在软件工程上的一记重击。

为了使 Agent 程序与插件程序进行有效交互,我们开发了 lng 项目(Lua Engine for Go)支持 LuaVMGo 的通信,在这个项目上做了许多技术创新。例如:

  • 为适应安全业务的特点为 LuaVM 做了兼容性的增强使原本不支持的环境下也可正常运行。
  • 增强了虚拟机隔离性,使一切与外部环境交互的操作都必须经过 Agent 的审查和管控。
  • 做了安全性的 Patch,通过禁用和包装一些敏感操作保证无法写出危及系统安全性和 Agent 稳定性的插件。
  • Lua 插件提供了基于 MessagePack 序列化的通信接口,为 Lua 极大提高了跨插件边界传递复杂数据结构的能力。
  • 提供了调度 LuaVM的能力,即根据资源使用情况和限制动态在并行执行的多个 VM 中分配执行时间片以控制插件资源滥用。
  • 类似 JavaScriptPromise 语法的异步能力
  • 通过注入依赖提供便捷的 OO封装能力

lng 项目的支撑下,在相当长一段时间里我们得到了当时效果感到十分满意的插件开发体验,并在很大程度上达到了灵活、稳定、轻量的设计目标。

但经过长期的维护和使用,安全业务越来越复杂庞大,对插件的工程质量和可维护性提出了更高的目标;对探针的轻量级、高性能和兼容性提出了更加苛刻的要求。原本的选型不再令人满意。

Agent 的角度来看,作为一个系统应用,难以精确控制行为和资源占用是一个巨大的缺点。对于 AgentIO 密集型的部分,长期以来一直通过使用混合语言开发缓解相关的问题。从插件的角度来看,基于渐进式类型系统和类型标注来在动态语言中进行类型推理是一件困难而且效果不理想的事情,难以对大型软件仓库进行有效组织。从 lng 的角度来看,由于与 LuaVM 的交互需要借助 CGO 导致要传递数据必须拷贝数据,在大规模安全事件触发时因为通信开销过高很难做到兼具轻量和高性能。

在我们经历了自行设计插件通信标准并提供开发调试基础设施、自行修复 LuaJIT VM 实现缺陷、自行设计和维护 CtLua 编译器、自行兼容 Go 语言和低版本操作系统、自行修复 Linux 内核 Bug等传奇事件后,终于做出了一个惊人的决定。

IV. 新技术栈的选择

经过长期的挣扎和斗争,团队最终决定使用全新技术栈打造下一代主机安全探针体系。

Rust+WASM

一句话技术选型:使用 Rust 开发 Agent 程序,基于 WASM 打造新的插件体系。

这样做的期望是通过 Rust 获得较佳的开发体验,同时克服在 Go 的技术体系下难以逾越的兼容性和底层控制的困难。同时,WASM 的跨语言特性将为静态语言的插件开发提供支持,从而提高工程质量,降低插件通信开销,增强插件隔离性。

新的技术栈中可以更好地满足牧云的需求,从而实现更加灵活和可扩展的安全检测功能,以适应日益复杂的安全威胁环境。同时,也将可以更加精细地控制 Agent 程序的行为和资源占用,以提高系统性能和稳定性。

关于新的选择中新的考虑和挣扎,将会在后续的系列文章中逐渐揭秘。系列文章将会与全新的次时代主机 Agent 的开发和打磨过程同步发布,分享最为真实鲜活的故事和经验。

V. 总结

对于主机安全产品的未来发展,我们可以预见以下几个趋势:

主机安全趋势

  1. 面向云原生应用的安全产品需求将会增加。随着云原生应用的普及,传统的主机安全产品可能无法满足云原生应用的安全需求。因此,未来的主机安全产品需要更好地适应云原生应用,提供更加灵活、可扩展、自适应的安全解决方案。
  2. 安全自动化程度将会提高。未来的主机安全产品需要更加注重安全自动化,减少对人力资源的依赖。这包括自动化的安全检测、自动化的安全分析、自动化的安全决策、自动化的安全响应等等。
  3. 多产品协同防御快速发展。未来的主机安全产品需要充分发挥产品形态优势,与各个环节的安全产品深度融合,构建纵深防御体系,提供立体防护能力。
  4. 安全合规性将会更加重要。未来的主机安全产品需要更加注重安全合规性,这将为企业提供更加可靠的安全保障,同时也将促进行业的健康发展。

未来的主机安全产品需要适应不断变化的安全威胁环境和用户需求,采用更加灵活、自动化、智能化、合规化的安全解决方案。长亭主机安全产品团队将会不断创新和突破,不断推进产品的发展,为社区和用户提供更加优秀的安全解决方案和服务。

相关博文推荐

下一篇:【牧云插件系统面向未来的设计原则】

系列文章目录:【预告】主机Agent插件引擎开发故事汇总

  1. 【揭秘牧云插件开发者的创新之路:从无法解决的问题到“妙趣横生”】
  2. 【牧云插件系统面向未来的设计原则】
  3. 【牧云插件系统选型斗争】
  4. 【牧云插件系统技术选型之探针开发用什么?】
  5. 【牧云插件系统技术选型之插件开发用什么?】
  6. 【牧云插件系统技术选型之插件通信框架大PK】
  7. 【牧云插件系统技术选型之自己人都会吐槽的序列化方法选择之争】
  8. 【牧云插件系统技术选型之WASM运行时选哪个?不选这个竟然出大问题!】
相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2