[spring-projects/spring-boot]Java 信息​​贡献者

2024-05-14 322 views
6

InfoContributor将 Java 相关的详细信息添加到执行器的信息端点,作为增强可观察性工作的一部分:https://github.com/spring-projects/spring-boot/issues/25476 配置后,它看起来像这样:

  "java": {
    "vendor": "Eclipse Adoptium",
    "version": "17",
    "runtime": {
      "name": "OpenJDK Runtime Environment",
      "version": "17+35"
    },
    "vm": {
      "name": "OpenJDK 64-Bit Server VM",
      "vendor": "Eclipse Adoptium",
      "version": "17+35"
    }
  }

如果您好奇这在其他 OpenJDK 发行版上或使用本机映像会是什么样子,我测试了 30 多个最流行的 OpenJDK 映像(最新和当前的 LTS),您可以在这个公共要点中看到结果:java-info.md。您可以看到上面的值有什么不同(例如:不同的 java 和 vm 供应商或不同的 jre 和 vm 版本等)。如果您想运行自己的测试,请查看此存储库:https://github。 com/jonatan-ivanov/app-info

关于这些变化的一些注意事项:

  • 默认情况下是JavaInfoContributor自动配置的
  • 我还没有写文档,如果这些更改最初看起来没问题,我会添加它们
  • 我使用真正的课程而不是Map<String,Object>InfoContributor
  • 我不确定序列化输出是否在任何地方进行了测试,我没有编写任何测试来涵盖这一点,但我很乐意这样做,我只需要一些关于将它们放在哪里的指导
  • 故意不使用 JMX 是为了使实现更简单,并且本机映像在 JMX 方面仍然存在一些挑战

回答

8

感谢您的公关,@jonatan-ivanov。

请注意 Boot 团队未来的自我:我已将其标记为与修订合并,因为我们可能会重命名一些 DTO。

1

此类信息默认公开的原因是什么?与 #25134 类似,我认为这是潜在的信息泄露源,可能会导致漏洞利用。

0

是的,我知道info端点现在默认被视为安全的。我个人欢迎这种改变。

但是,我不会将安全设置与启用可能成为信息泄漏源的个人贡献者混为一谈。 IMO 任何可以归类为此类的东西都应该是具有专用配置属性的选择加入功能。例如,错误属性 (#7872) 或 favicon (#17925) 就没有这样的假设。甚至health端点 - 即使我保护它,我仍然需要选择公开健康贡献者的详细信息。

同样重要的是要考虑到许多人向公众公开他们的信息端点。甚至 Spring本身会这样做。许多人可能已经进行了调整,升级到 2.5(端点变得安全),现在当他们选择 2.6 时,就会隐式地得到这一点。info

最后,但不可否认的是,我个人的看法是,许多其他人可能不会分享,具体取决于他们运行应用程序的环境,我真的看不到默认启用此功能的价值。如果我至少对运行时基础设施有一定的控制,或者正在运行容器,那么我几乎可以控制 JVM 运行时,因此我不需要应用程序端点来告诉我有关它的详细信息,因为这是一个有意识的选择。因此,将其放在那里只会存在某种风险。

0

我想我和您一样担心默认启用与选择加入的问题,但我不同意这一点:

如果我至少对运行时基础设施有一定的控制,或者正在运行容器,那么我几乎可以控制 JVM 运行时,因此我不需要应用程序端点来告诉我有关它的详细信息,因为这是一个有意识的选择。因此,将其放在那里只会存在某种风险。

这个功能背后的整个想法(至少从我的角度来看)是让应用程序更容易观察,这样我们就可以检测到那些永远不应该发生但不知何故却发生的事情,例如:你认为你使用某个 Java 版本是因为你可以控制它并明确设置它,但不知何故你最终得到了不同的版本。让我举几个例子,我在生产中看到了每一个例子:

  • 部署解决方案从版本化文件夹中复制了 JRE,不知何故,名为 java6uXYZ 的文件夹中有 Java 5
  • 有人JAVA_HOME手动更改
  • 有人在配置文件中设置了错误的值 -> 错误的版本(Spring 也做了类似的事情
  • 部署期间引用/链接了错误的配置文件
  • 部署配置已更新以更新java版本(应用程序版本未更改),但在部署过程中出现静默回滚(验证过程仅检查应用程序版本)
  • 人们使用或不指定容器镜像的latest完整版本(8、等)11
  • 此外,docker 使用了缓存中的图像,应用程序没有获取新版本
  • 有人错误标记了 docker 基础镜像,并在一分钟内修复了该问题;在那一分钟内,有多个部署使用了错误的 Java 版本
  • 不知何故,该应用程序被部署到一个应该已停用的盒子(使用旧的 Java 安装)

从我的角度来看:如果我至少对运行时基础设施有一定的控制,或者正在运行容器,我应该控制 JVM 运行时,但事实上我不能 100% 控制它,而且我永远不会,所以我需要一些东西(比如应用程序)端点)告诉我有关它的详细信息,以便我可以验证。

0

我们将翻转默认设置。请参阅#28310(我们无法重新打开此 PR,因为分支已消失)

4

谢谢@philwebb。

@jonatan-ivanov 我承认你列出的事情可能会发生,但在我看来,其中大多数只是忽视了核心(软件)工程原理,例如可重复性。构建应该是可重复的,基础设施设置/脚本也是如此。因此,我相信对这些原则的教育可以解决所列出的问题,而不是在其之上增加另一个潜在问题(信息泄漏)。

3

我完全同意你的观点,除了最后:无论你做什么,软件都非常复杂,我们都是人类,我们都会犯错误,你无法真正避免它(有时软件和硬件也会犯错误) 。

这就是为什么我们有日志、指标、分布式跟踪,这就是为什么编写测试,这也是我们有 Spring Boot Actuator 的原因。你可以称之为信息泄漏,但我会称之为“可观察性”。再次强调,我同意默认禁用此功能,但我不同意根本不使用它。

6

我认为没有人会争论根本不拥有它——这在某些情况下肯定会有所帮助。

9

@jonatan-ivanov 你如何看待它java.vendor.version?有了这个新功能,JavaInfoContributor我现在得到以下信息:

{
  "java": {
    "vendor": "Amazon.com Inc.",
    "version": "11.0.13",
    "runtime": {
      "name": "OpenJDK Runtime Environment",
      "version": "11.0.13+8-LTS"
    },
    "jvm": {
      "name": "OpenJDK 64-Bit Server VM",
      "vendor": "Amazon.com Inc.",
      "version": "11.0.13+8-LTS"
    }
  }
}

然而,我实际使用的Java版本是:Corretto-11.0.13.8.1 (11.0.13.8.1) 目前我可以通过以下方式获取完整版本字符串: info.java-version=${java.vendor.version}

你认为曝光${java.vendor.version}也有意义吗?

9

@dmengelt 我不太记得为什么我没有将其包含java.vendor.version在原始 PR 中。我我没有这样做,因为一般来说,它是不确定的/非常有价值:我使用 40 多个不同的 Java 发行版(+1 GraalVM)测试了属性,有时该值丢失,有时它没有添加新信息。

让我今晚重新运行测试并回复您(如果您好奇,可以在这里test.sh找到它们,请参阅)。

4

我重新运行了针对 35 个图像的测试,TL;DR:似乎只有 Corretto 11 和 17 图像具有提供额外信息的一些价值(也许Zulu 11 和 17 图像也有,但我不确定,请参见下文)。

基于此,我可以明白为什么过去我没有包含它,但是,由于它在某些情况下是有意义的,我认为至少值得在问题中询问启动团队(应该相当容易实现,但它可能会改变响应:vendor.namevendor.version)。

细节

  • 其中 17 个图像具有此属性,其中 18 个图像没有:参见java-vendor-versions.md
  • 拥有此房产的 17 人中
    • 其中一些对我来说没有意义
    • openjdk:11-jre-slimjava.vendor.version: 18.9(同时java.version: 11.0.13
    • sapmachine:11java.vendor.version: SapMachine
    • sapmachine:17java.vendor.version: SapMachine
    • 或者不添加新信息
    • adoptopenjdk:11-jre-openj9
      • java.vendor.version: AdoptOpenJDK-11.0.11+9
      • java.runtime.version: 11.0.11+9
    • adoptopenjdk:16-jre-openj9
      • java.vendor.version: AdoptOpenJDK-16.0.1+9
      • java.runtime.version: 16.0.1+9
    • eclipse-temurin:11-jre
      • java.vendor.version: Temurin-11.0.13+8
      • java.runtime.version: 11.0.13+8
    • eclipse-temurin:11-jre-alpine
      • java.vendor.version: Temurin-11.0.13+8
      • java.runtime.version: 11.0.13+8
    • eclipse-temurin:17-alpine
      • java.vendor.version: Temurin-17.0.1+12
      • java.runtime.version: 17.0.1+12
    • eclipse-temurin:17-jdk
      • java.vendor.version: Temurin-17.0.1+12
      • java.runtime.version: 17.0.1+12
    • 或者让我感到困惑(我猜这是内部构建版本,所以应该有意义,但我们可以在 中跟踪它java.runtime.version
    • azul_zulu-openjdk-alpine:11-jre
      • java.vendor.version: Zulu11.52+13-CA
      • java.version: 11.0.13
      • java.runtime.version: 11.0.13+8-LTSjava.vm.version是一样的)
    • azul_zulu-openjdk-alpine:17-jre
      • java.vendor.version: Zulu17.30+15-CA
      • java.version: 17.0.1
      • java.runtime.version: 17.0.1+12-LTSjava.vm.version是一样的)
    • azul_zulu-openjdk:11
      • java.vendor.version: Zulu11.52+13-CA
      • java.version: 11.0.13
      • java.runtime.version: 11.0.13+8-LTSjava.vm.version是一样的)
    • azul_zulu-openjdk:17
      • java.vendor.version: Zulu17.30+15-CA
      • java.version: 17.0.1
      • java.runtime.version: 17.0.1+12-LTSjava.vm.version是一样的)
  • Corretto 11 和 17 图像虽然有意义(Corretto 8 图像没有此属性)
4

我发现另一件事:似乎这是在JEP-322 (Java 10) 中引入的,但他们想删除它,尽管社区发现它有用,所以他们保留了它。根据对该问题的评论,我想说该属性对于 Zulu 和 Corretto 图像有意义,并且可能对未来的更多发行有意义。

6

谢谢@jonatan-ivanov

0

非常感谢 @jonatan-ivanov 的广泛研究。

9

是否有任何特殊原因导致java.homejava.vendor.url没有被包含在JavaInfo课程中?

6

我看不出了解有什么好处java.home。了解 JVM 安装位置有什么好处?我正在努力思考对java.vendor.url其中任何一个的强烈需求。如果您有需要,请随时提出一个新问题来为他们提供理由,我们可以考虑。