Linkerd引入了fuzz测试

2021-05-27 15:44:18 浏览数 (1)

作者:William Morgan

(Photo by Prince Abid on Unsplash.)

在过去的几个月里,Ada Logics[1]的团队一直在努力将模糊测试引入到Linkerd 的 Rust 代理[2]。这些 fuzz 测试现在通过谷歌的OSS-Fuzz[3]服务在 Linkerd 上持续运行,为全球 Linkerd 用户提供了另一层安全保障。总的来说,fuzzing 被集成到代理的 7 个依赖项以及代理本身中,其中 5 个项目现在正在 OSS-Fuzz 上持续运行。

这些模糊测试发现了代理中的两个小 bug,现在已经修复了。(相比之下,最近一个基于 C 语言的 CNCF 项目发现,并修复,了 30 多个 bug,主要与内存安全有关)。此外,在依赖项中还发现了一些小问题,这些问题都已经传达给了维护人员。

你可以在这里阅读完整的报告[4]。有关细节,以及如何参与到这一重要的安全措施,请继续阅读!

背景资料:

  • https://linkerd.io/2020/07/23/under-the-hood-of-linkerds-state-of-the-art-rust-proxy-linkerd2-proxy/
  • https://linkerd.io/2020/12/03/why-linkerd-doesnt-use-envoy/

为什么对代理进行模糊测试?

模糊测试是一种自动软件测试,它使用随机输入和基于覆盖率的遗传算法来评估代码的行为。因为输入是随机生成的,所以模糊测试在捕获人类可能错过的测试用例方面很有用,特别是在涉及无效或意外输入的角落用例时。

Linkerd 使用一系列自动化测试[5]来确保每次提交的安全性和可靠性。这些测试范围从代码检测和静态分析,到单元测试,再到综合的集成测试套件。虽然这些测试在 Linkerd 的开发过程中扮演着重要的角色,但有三个原因让我们特别想通过代理的模糊测试来增强它们:

  1. Linkerd 的代理处理来自网络的不可信输入。 代理必须接收来自应用程序或可能来自开放互联网的请求;解析数据;然后用它来“做某事”——把它送到目的地,拒绝它,等等。虽然 Rust 的内存安全保证帮助我们避免了 C 和 C 代码特有的整个类型的安全漏洞,但这当然不能防止其他类型的漏洞。代理的弹性阈值非常高——它必须能够处理由具有完整源代码访问权限的人编写的恶意输入的最坏情况。
  2. 数据平面代理是任何服务网络中最关键的运行时组件。 虽然 Linkerd 被设计成控制平面组件的临时故障不会影响应用程序的运行,但数据平面级别的临时故障意味着 pod 无法处理请求。除了简单的故障之外,代理中的 bug 最糟糕的情况是可怕的:更改或破坏请求可能是灾难性的;不正确处理 mTLS 可能会将流量暴露给攻击者等等。因此,除了我们现有的关于代码评审的可靠性实践之外,我们应该拥有最健壮的测试集。
  3. 与其他语言相比,Rust 的模糊测试系统并不发达。 投资于这一关键领域意味着不仅是 Linkerd,还有其他建立在最先进的 Rust 网络生态系统上的项目(像Tokio[6]Hyper[7]Rustls[8]Tower[9]等项目)都可以从这项工作中受益——双赢。

模糊测试发现了什么?

最初的模糊测试在 Linkerd 的代理中发现了两个小 bug。

首先,当 DNS 查找导致名称超过 255 字节时,代理会恐慌,这是由于代理用于 DNS 查询的trust-dns 库中的一个 bug[10]。该库的维护者立即修复了这个问题,并在最近的 Linkerd 版本中合并了这个修复。

其次,代理在解析端口 80 的 IPv6 地址时会恐慌。(大多数 Kubernetes 供应商目前还不支持 IPv6,但当他们支持 IPv6 时,代理是可以支持的。)这是代理本身的一个 bug[11],也被立即修复了,并将修复合并到最近的 Linkerd 版本中。

这些 bug 展示了模糊测试的价值:它们代表了代理(和依赖库)中的逻辑缺陷,这些缺陷涉及到经过几轮人工检查的代码中意外的边缘情况。

虽然没有两个项目是相似的,但作为一个比较点,Ada Logics 最近对一个用 C 编写的毕业 CNCF 项目进行了类似的练习,产生了超过 30 个 bug,包括 4 个“高严重”和 8 个“中等严重”bug。这些错误中的大多数是缓冲区溢出、null 引用、内存泄漏和其他类型的内存错误,而 Linkerd 使用 Rust 可以让我们首先避免这些错误。(链接[12]

下一步是什么呢?

模糊测试能够发现 bug 这一事实非常棒!但这只是模糊测试故事的开始,而不是结束。最初的工作只捕获了代理表面区域的一部分,模糊测试还可以带来更多的好处。

如果你正在寻找参与 Linkerd 的方法——我们很乐意邀请你——好消息是,这是你可以帮助项目的另一种方法。如果你对进一步构建 Linkerd 的模糊测试有兴趣,请查看Linkerd 的代理模糊开发文档[13],进入Linkerd Slack[14]上的#contributors,让我们实现它!

鸣谢

Linkerd 的维护人员想要特别感谢 Ada Logics 团队,特别是 David Korczynski,感谢他们在实现这些 fuzzer 方面的辛勤工作,感谢他们在 Rust 的 fuzzer 测试的未知水域中涉水,感谢他们帮助我们导航 OSS-Fuzz 项目。我们也要感谢 CNCF,特别是 Chris Aniszczyk,对这项工作的赞助。

Linkerd 适合所有人

Linkerd 是一个社区项目,由 CNCF 托管。Linkerd致力于开放治理[15]。如果你有功能请求、问题或评论,我们希望你加入我们快速增长的社区!Linkerd 的代码是在 GitHub 上托管的,我们在 Slack、Twitter 和邮件列表上有一个繁荣的社区。快来加入我们一起玩吧!

参考资料

[1]

Ada Logics: https://adalogics.com/

[2]

Linkerd 的 Rust 代理: https://linkerd.io/2020/07/23/under-the-hood-of-linkerds-state-of-the-art-rust-proxy-linkerd2-proxy/

[3]

OSS-Fuzz: https://github.com/google/oss-fuzz

[4]

完整的报告: https://github.com/linkerd/linkerd2-proxy/blob/main/docs/reports/linkerd2-proxy-fuzzing-report.pdf

[5]

一系列自动化测试: https://github.com/linkerd/linkerd2/actions

[6]

Tokio: https://tokio.rs/

[7]

Hyper: https://hyper.rs/

[8]

Rustls: https://github.com/ctz/rustls

[9]

Tower: https://github.com/tower-rs/tower

[10]

trust-dns 库中的一个 bug: https://github.com/bluejekyll/trust-dns/issues/1447

[11]

代理本身的一个 bug: https://github.com/linkerd/linkerd2-proxy/pull/976

[12]

链接: https://www.cncf.io/blog/2020/12/15/securing-open-source-fuzzing-integration-vulnerability-analysis-and-bug-fixing-of-fluent-bit/

[13]

Linkerd 的代理模糊开发文档: https://github.com/linkerd/linkerd2-proxy/blob/main/docs/FUZZING.md

[14]

Linkerd Slack: https://slack.linkerd.io/

[15]

致力于开放治理: https://linkerd.io/2019/10/03/linkerds-commitment-to-open-governance/

0 人点赞