发布于周五 14:555天前 本文将介绍我们在牧云插件系统中技术选型上的一些挣扎和思考。我们将探讨在设计主机安全系统的插件系统时如何考虑、如何做出选择,以及为什么最终选择WASM 作为牧云插件系统的底层技术。这是“**Host Agent插件引擎开发故事**”系列文章的第三篇,以后会持续更新。本系列文章将带领您深入了解长汀牧云团队的主机Agent插件引擎的开发过程。内容涵盖了技术选型、插件接口设计、组件通信框架等多个方面,并详细讲解了其背后的原理和实现方法。无论您是网络安全专业人士,还是对技术开发感兴趣的读者,您都可以从中有所收获。我们希望通过分享开发过程中面临的挑战、解决方案和实践经验,提供深入的见解和有价值的技术参考,帮助读者了解如何构建高效可靠的安全产品,共同推动安全技术社区的发展。 ## 牧云主机安全系统插件要求 根据之前两篇文章(**[[揭秘牧云插件开发者的创新之路:从无解问题到“好玩”]](https://stack.chaitin.com/techblog/detail?id=72)**和**[[牧云插件系统面向未来的设计原则]](https://stack.chaitin.com/techblog/detail?id=73)**)介绍,作为主机安全系统,牧云需要高效、可靠、稳定的“Agent”核心程序还必须能够随时更新安全能力,灵活适应不同的运行环境,检测不断变化的网络攻击方式。因此,需要一种基础安全能力和安全服务分离的技术架构。这个架构对应的是软件工程,就是我们熟悉的插件系统。 ## 插件系统的可能形式 ### 表1: 每个插件都是一个独立的功能,并且是宿主程序的一部分。 其实很难说这是插件形式。看起来更像是`Agent`程序代码的一种组织方式。但不得不承认,这确实是理论上性能最好的方案,但同时也是对稳定性最大的打击。从灵活性角度来看,只要手动保证各个功能的代码组织独立,似乎就可以通过更新`Agent` 来更新安全能力。虽然更新“Agent”本身造成的安全能力破坏似乎有些难以接受。 **优点:**性能最佳,插件与主机之间几乎没有通信成本。 **缺点:**稳定性相对难以保证,更新很容易导致安全能力中断。 ### 表格2: 每个插件都是一个独立的协程/线程,并且是宿主程序的一部分。 它看起来也不像一个插件。与第一种形式相比,它提高了一点隔离性,并获得了一点对插件的控制,但幅度不大。 **优点:**性能很好,异步运行方便,通信增加一点同步成本。 **缺点:** 对插件的控制不够,仍然不容易保证稳定性,而且更新也会造成安全能力的中断。 ### 表3: 每个插件都是宿主程序的一个子进程,独立于宿主程序。 子进程是非常独立的,在操作系统中是非常独立的。子进程崩溃不会影响`Agent`的稳定性。跨进程通信的成本有点高。 **优点:** 最独立的插件形式,非常有利于`Agent`的稳定性维护。 **缺点:** 通信成本稍高,对子进程的控制不足,意外的bug很容易导致更严重的事故。 ### 表4: 主机程序与单独的脚本执行引擎交互。每个插件都是一个脚本程序。 使用脚本执行引擎将插件脚本放在独立的子进程中(而不是子进程本身就是一个插件)执行,这样脚本执行引擎可以增强控制插件行为的能力。 **优点:** 在第四种形式的基础上,加强了对插件的控制,大大降低了发生严重事故的概率。 **缺点:** 对性能是一个重大打击。在跨进程通信的基础上,还增加了解释和执行的损耗,在繁忙的系统中可能无法响应大量的安全事件。 ### 表5: 脚本执行引擎嵌入在主机程序中。每个插件都是一个脚本程序。 在获得对脚本执行引擎的控制权的同时,消除了跨进程通信的消耗。 **优点:** 沟通成本比Form 4低。 **缺点:** 解释执行速度确实很慢。 ### 表6: 虚拟机嵌入在主机程序中。每个插件都是在虚拟机上执行的一段字节码。 通过基于虚拟机的插件执行引擎替换脚本执行引擎,提高插件执行效率。可选的加速方式包括“JIT”(Just In Time,即时编译)和“AOT”(Ahead of Time,预运行编译)技术。如果选择性能好的虚拟机,并且支持一些加速技术,似乎就很不错了。事实上,这也是牧云插件系统目前选择嵌入式`LuaJIT VM`来实现插件系统的原因。 **优点:**与Form 5相比,提高了插件执行性能的理论上限,有利于在安全事件增多时保持安全响应能力。 **缺点:** 貌似没有什么缺点,详细请参考系列第二篇文章。 ## 团队内部的选拔辩论 虽然看似形式6取得了全面胜利,但面对现实中遇到的实际问题,牧云团队内部对于上述形式的选择仍然存在很多不同意见: * 只要插件代码和实现语言足够稳定,就可以直接写入`Agent` 中。 * `Agent` 核心代码必须保持稳定,因此不能将插件写入`Agent` 中。 * 足够稳定的插件在工程上是无法实现的白日梦,所以必须采用强制隔离的方式来保证`Agent`的稳定性不受插件的影响。 * 稳定性必须通过隔离来保证,但隔离不一定需要采用嵌入式虚拟机的形式。还可以实现子流程。 * 解释执行的脚本引擎足够高效,无需通过其他手段追求执行效率。 * 有必要采用一种理论上最小化开销同时控制成本的方法,因为这是`Agent`程序的核心设计目标之一。 * 额外成本最少的解决方案是在进程内部运行插件,并使用与插件相同的语言实现,这是第一种形式;如果想要一定程度的隔离和控制,可以通过线程和协程的调度来实现。 * 考虑到稳定性和灵活性的平衡,插件独立实现是必然的选择。在脚本引擎和虚拟机引擎之间,当然选择性能更好的虚拟机引擎。 关于这些点,以下是高级网络安全专业人员之间的模拟对话。角色分别是领导者A、看重性能和稳定性的代理开发者B、看重隔离性和灵活性的插件开发者C: A: 大家都知道我们面临的问题:我们需要找到一种插件化的系统解决方案,既能保证性能和稳定性,又能实现隔离和灵活性。我们一起来讨论一下吧。 B: 是的,性能和稳定性非常重要。我更喜欢形式一,每个插件都是独立的功能,沟通成本低。我们可以通过严格的代码审查来确保稳定性。 C: 我觉得中四也是一个不错的选择。每个插件都在独立的进程中执行,并且安全隔离。这是主机安全系统的一个重要因素。 B: 但是,进程隔离会增加通信成本。我们可以考虑第二种形式:协程或线程。通过合理的同步策略,我们可以实现良好的隔离性和稳定性。 C: 除了这些解决方案外,我们还可以考虑基于脚本执行引擎的形式五。这使得插件更加灵活并且更容易调试和维护。 B: 脚本引擎性能可能会受到影响。我认为Form 6是一个折衷方案。虚拟机可以在保证主机安全的同时提供更好的性能和控制。 C: 是对的。虚拟机可以提供更好的隔离,有利于主机安全。我们可以选择支持JIT或者AOT技术的虚拟机,比如LuaJIT,来保证性能。 B: 好的,我同意尝试中六。我们可以观察实际应用中的表现,如果有问题就进行调整。 A: 我们先尝试第六种,使用虚拟机作为插件系统的基础。如果实际效果不理想,请根据实际情况进行调整。 讨论结束,大家都有些不知所措,该怎么办的问题一直萦绕在大家的脑海里。事实上,以上几种形式在业界都有广泛的应用。它们适合各自的场景,不能说是糟糕的选择。然而,哪一种最适合主机安全系统的选择确实需要仔细考虑。 ## 思考:解决问题、成本、价值 观察竞争对手的实际选择,事实上,一些我们可能认为明显不是最优的解决方案实际上是存在的。确实很难猜测每家公司做出权衡的实际原因是什么。例如,有的使用“Java”实现“Agent”,有的使用“C++”实现“Agent”;有的使用Python 实现插件,有的使用Bash 实现插件,有的使用Perl 实现插件。 事实上,牧云目前的选择,用Go 语言编写Agent,用Lua 实现插件,本身就是一个难得的选择。理论上来说,Go 是一种高效、灵活、跨平台的语言,而Lua 则以稳定性和高性能着称。在牧云刚成立的时候,这个选择似乎是无可挑剔的。 最终,我们真正需要考虑的是我们之前的插件系统解决了哪些问题,以及新的选项可以带来多少成本和价值(继续思考……)。 ## 最终选择 插件架构的最终决定是以上考虑因素的折衷。目前看来,多种插件系统形式的好处都可以得到。那是七年级。除了表单本身的变化之外,通过改用Rust 来实现Agent 程序,您可以获得解决兼容性问题的能力,避免因CGO 导致的数据复制,并通过WASM 获得上一篇文章中描述的许多好处。 ### 表7: 宿主程序与独立的虚拟机引擎通信,插件运行在虚拟机上。 简单来说,我们不满足于插件运行速度快,还希望将其限制在指定的资源上。 `CPU`占用率不能超过指定阈值,内存不能超过指定阈值,`IO`不能超过指定阈值。整体资源占用和消耗稳定,优先保证业务,但同时安全能力也不能差。因此,设计并实现了一套完整的插件限制和调度机制。然而,就像进程对自己的协程的控制很差一样,我们对虚拟机执行的线程的控制也很有限。在满足上述条件的情况下,很难进一步提高安全效果。将运行插件的虚拟机移至单独的进程中似乎是一个可行的选择。为了减轻进程间通信的成本,经过分析,对插件需要访问的资源进行了拆分。大部分都是直接在虚拟机进程上完成的。少量需要`Agent`主程序配合的数据是通过新设计的进程间通信`RPC`框架完成的。至于具体如何解决,那就是新故事了。 **优点:**在解决了形态六的缺点的同时,也缓解了形态四的缺点。 **缺点:** 迁移全套安全功能需要一点时间,并且可能存在我们看不到的风险。 ## 总结 在牧云主机安全系统的开发过程中,我们对插件需求进行了深入的讨论,并对各种插件系统形式进行了分析和比较。通过团队内部的选型辩论和对行业解决方案的观察,我们意识到在选择插件系统时需要综合考虑解决问题、成本、价值等多重因素。最终我们根据项目需求以及团队的技术特点做出了独特的选择。 在整个过程中,我们始终专注于满足系统的安全性、性能、可扩展性和稳定性。我们希望通过构建强大、灵活的插件系统,为牧云主机安全体系的持续优化和完善奠定基础,为用户提供更加安全稳定的服务。 ## 推荐相关博文 上一篇:**【【牧云插件系统面向未来的设计原则】】(https://stack.chaitin.com/techblog/detail?id=73)** 系列文章目录:【【预览】主机Agent插件引擎开发故事总结】(https://stack.chaitin.com/techblog/detail?id=82) 1. **[[揭秘牧云插件开发者的创新之路:从无法解决的问题到“充满乐趣”]](https://stack.chaitin.com/techblog/detail?id=72)** 2. **[【牧云插件系统面向未来的设计原则]](https://stack.chaitin.com/techblog/detail?id=73)** 3. **【【牧云插件系统选型之争】】(https://stack.chaitin.com/techblog/detail?id=77)** 4. **【【牧云插件系统技术选型中探针开发用什么? 】](https://stack.chaitin.com/techblog/detail?id=83)** 5. **【【牧云插件系统技术选型及插件开发? 】](https://stack.chaitin.com/techblog/detail?id=85)** 6. **【【牧云插件系统技术选型插件通信框架PK】】(https://stack.chaitin.com/techblog/detail?id=94)** 7. **[【牧云插件系统技术选型:大家都会抱怨的序列化方法选择之争]](https://stack.chaitin.com/techblog/detail?id=97)** 8. **[【牧云插件系统技术选型:应该选择哪种WASM运行时?如果不选择这个,就会出大问题! 】](https://stack.chaitin.com/techblog/detail?id=105)**
创建帐户或登录后发表意见