现代化 Malwarebytes 的隐藏工作

为什么严格的依赖现代化是安全产品可以进行的最高杠杆工程投资之一。

来源:Malwarebytes Labs 博客

确保安全产品值得信赖的大部分工作都是无形的。用户会看到扫描完成、威胁被阻止、以及夜间应用的更新。他们看不到下面的平台。运行时、托管库、本机驱动程序和 Windows 要求都必须保持最新状态,并在数百万个端点上协同工作。我们向 .NET 10 的迁移是我们如何保持该平台不断发展的一个示例,也是本文的重点。

可以很容易地调用这些升级维护任务并继续。但这是低估他们的。我们的代码在 Windows 的一些最敏感的部分旁边以提升的权限连续运行。

我们堆栈中的每个依赖项,从运行时和第三方库到本机驱动程序和操作系统要求,都会影响我们软件的运行环境。当一个人发生变化时,依赖它的一切可能也必须改变。

问题:平台因停滞不前而落后

在端点安全中,地面永远不会停止移动。 Windows 不断发展。威胁不断演变。硬件不断发展,从 ARM64 笔记本电脑到比我们最初编写代码时内存更多、存储速度更快的机器。

静止的平台不会保持不变。它落后了。每一次跳过的依赖项或运行时版本都会扩大我们所构建的生态系统与当今稳定的生态系统之间的差距。

现代运行时,尤其是 .Net 10 可以为我们提供更好的安全性、更快的代码路径、更小的内存占用和更丰富的诊断。它还为我们的工程师提供了语言和工具方面的改进,帮助他们更高效地工作。

对于安全软件来说,风险也特别高:

  • Web 应用程序可以通过部署进行回滚。已安装在客户端点上的软件则不能。
  • 我们的代码以高权限运行,并具有内核驱动程序和防篡改保护。
  • 运行时回归不会影响一台服务器。它有可能影响数百万台机器。
  • 因此,我们将运行时升级视为安全功能。

    挑战:一切齐头并进

    Malwarebytes for Windows 不是一个单一的程序。它是一个协调的系统:一个面向用户的界面、几个长期运行的 Windows 服务、一个安装程序、一个自我更新管道、一个插件表面和第三方管理的依赖项。

    它们位于本机驱动程序和我们的检测引擎之上。 .NET 10 迁移涵盖了 Malwarebytes 的托管部分,同时保持了本机核心不变。但不同的层仍然必须一起工作。

    迁移必须同时满足多个要求:

  • 安全敏感代码在更改之前和之后必须具有相同的行为。
  • 本机驱动程序和防篡改层必须继续与托管代码正常工作。
  • 安装程序和更新管道必须部署新的运行时文件并清理旧的文件。
  • 插件和第三方依赖项必须保持兼容。
  • 现有的 Malwarebytes 安装必须继续工作。
  • 我们的自动验证必须足够广泛,以信任结果,而无需手动检查每条路径。
  • 托管代码和本机代码之间的界限值得特别注意。我们服务中的托管代码通过 P/Invoke 和 COM 等接口与本机组件进行通信。运行时更改可能会微妙地影响 Malwarebytes 的这些不同部分如何通信和协同工作。

    并非每次更新看起来都一样

    .NET 迁移:我们为何这样做

    值得记住的教训

    这些差异可能永远不会出现在演示中。它们可能只有万分之一的机器上出现。在客户之前找到它们是重要的部分。

    我们更新依赖项的三个主要原因:我们选择这样做、底层平台强迫我们这样做、或者漏洞迫使我们这样做。每个都有不同的时间表。

    选择性现代化。我们可以选择迁移到新的运行时、新的库主要版本或新的平台功能,以利用新功能、修复或安全改进。

    基线变化。随着平台需求的发展,一些旧的兼容性限制可能会阻碍现代化。例如,迁移到 .NET 10 使我们能够更新应用程序基线并采用更新的受支持的运行时。作为同一更改的一部分,Windows 7 支持已被弃用。

    强制补丁。有时,我们发布的库或我们依赖的系统中会披露漏洞。改变不再是可选的,时间表也不是我们的。我们可以控制的是我们的准备情况:测试、发布过程和分阶段推出,使我们能够快速响应,而不会引入新问题。

    不同的原因和不同的时间表,但每一个都需要同样谨慎的方法。

    迁移到 .NET 10 为 Malwarebytes 提供了更安全、更受支持、功能更强大的 Windows 基础,并具有多种优势:

    安全性。现代运行时受益于 Microsoft 正在进行的安全工作,包括更安全的默认值、更强大的加密以及内存和互操作性错误的缓解。继续使用 Microsoft 积极支持的运行时意味着我们可以在发现漏洞时继续应用修复程序。

    受支持的基础。这可能不是一个迷人的理由,但 .NET 10 让我们保持在受支持、积极开发的平台上,该平台与较新版本的 Windows 更好地保持一致。它可以更轻松地将未来的修复、功能和改进作为日常工作而不是一次性项目。

    诊断和可观察性。现代 .NET 具有更强大的内置跟踪、指标和崩溃诊断。在安全产品中,了解代码在现场的行为方式很重要。更好的诊断帮助我们识别和解决可靠性问题。

    性能和内存效率。最近的 .NET 版本改进了即时编译器、垃圾收集器和核心库。我们的进程整天在后台运行,因此它们运行和管理内存的效率很重要。这些功能为我们提供了更多提高效率的机会,尽管影响因组件而异。

    .NET 迁移:我们是如何做到的

    指导原则很简单:永远不要比证据允许的速度更快。

    我们首先将工作隔离在专用分支上。我们重新定位了平台并刷新了每个托管依赖项,以便新的运行时和代码库准确地就应该发布哪些组件达成一致。

    这暴露了早期升级的一些不太明显的后果:已重命名或折叠到运行时中的库、不再需要的文件以及必须在其位置上发布的新文件。

    部署很容易被忽视,而且出错的代价也很高。运行时迁移不仅仅涉及运行的代码。它还与客户磁盘上的内容有关。

    我们的安装程序和更新服务必须了解新运行时的文件布局。他们必须删除运行时现在提供的依赖项,停止传送重命名的文件,并在全新安装和就地更新期间干净地交付替换文件。

    一旦构建正常工作,重点就转移到验证上。

    正确部署是用户从未注意到的升级与造成支持问题的升级之间的区别。

  • 涉及的迁移:
  • 跨服务、安装和更新路径的广泛自动化测试。
  • 针对实际配置和以前安装的兼容性验证。
  • 性能基准测试,以捕获启动、内存和扫描行为中的回归。
  • 金丝雀和分阶段部署,从小规模开始,仅在结果显示安全时才扩大规模。
  • 现场持续监控和自动回归检测。
  • 跨平台、QA、安装和更新以及发布工程的跨职能工作。

    “我们的进展速度永远不会超过证据允许的速度。每扇门都必须自行变绿。”

    .NET 迁移:权衡

    这一切都不是免费的,而且选择都需要经过深思熟虑的权衡。

    分支上的权衡是漂移。隔离迁移可以保护主代码库,但该分支存在的时间越长,它就越可能偏离主动开发。我们通过频繁的集成来管理这种风险,而不是把一个大型的、有风险的合并留到最后。

    部署的权衡是速度。分阶段部署还意味着客户收到更新的时间比大爆炸发布的时间要晚。我们接受了这种权衡。来自较小群体的证据使我们有机会在更新到达更多端点之前发现问题。

    AOT 的权衡是灵活性。提前编译可以提高启动性能,但也会限制动态行为。我们有选择地、逐个组件地应用它,而不是默认情况下到处应用它。

    .NET 10 迁移对客户意味着什么

    基础设施工作的最佳成果是客户无需思考即可从中受益。

  • 在 .NET 10 上,Malwarebytes 客户的优势包括:
  • 提高了完全受支持、积极维护的运行时的可靠性。
  • 受益于平台持续安全改进的更安全的基础。
  • 访问新的 .NET 功能和修复。
  • 更好地支持较新版本的 Windows。
  • 更新的 .NET 工具可以帮助我们更快地开发和提供新的保护。

    每一项更新(运行时、基线、安全补丁)都让团队更加坚定地持有一些信念。

    平台升级是对建立在其之上的一切的战略投资。现代化在持续进行时效果也最好:平台落后的时间越长,最终升级就越困难。

    自动化对于如此广泛的变化尤其重要。几年前做出的小而平庸的决定也是如此,例如保持组件之间清晰的边界以及建立一个准确了解其交付内容的构建过程。

    这些基础使得更大的改变成为可能。

    “技术债务就像金融债务一样复杂。最便宜的升级是你从不推迟的升级。”

    接下来会发生什么

    没有升级是终点线。每一步都是一个更长的模式中的一步:持续、审慎地进行现代化,因此平台永远不会落后。基线将再次发生变化。漏洞会在没有警告的情况下出现。在我们继续前进之前,每个人都将满足相同的纪律:相同的测试、相同的分阶段部署以及相同的证据。

    “地球上最好的网络安全套件之一。”

    这种纪律是值得信赖的产品实际上是由每天在每台机器上运行而无需再考虑的。

    适用于 .NET 10 上的 Windows 的 Malwarebytes 已在 5.6.0 版中发布。这是长期致力于投资产品底层平台的最新一步,以便其之上的保护能够不断变得更好。

    据 CNET 报道。阅读他们的评论→