从类路径中删除 Log4j 1.x JMSAppender 和 SocketServer 类

Databricks 最近发布了关于 Log4j 2 漏洞(CVE-2021-44228)的研究和评估的博客。 Databricks 不会直接在 Azure Databricks 平台中使用已知受此漏洞影响的 Log4j 版本,我们理解这可能容易受到攻击。

Azure Databricks 也不会使用 Log4j 1.x 中具有已知漏洞的受影响的类(CVE-2021-4104CVE-2020-9488CVE-2019-17571)。 但是,如果代码使用其中的一类(JMSAppender 或 SocketServer),则使用时可能会受到这些漏洞的影响。

如果代码使用 Log4j,则应升级到 Log4j 2.17 或更高版本。

如果由于技术原因无法进行升级,则可以使用全局 init 脚本在群集启动时从 Log4j 中剥离受影响的类。

重要

由于我们不控制用户运行的代码,我们无法保证在所有情况下,这种解决方案都让 Log4j 不加载受影响的类。

配置全局 init 脚本

注意

对于依赖于受影响的类的任何代码,运行此脚本都是重大更改。

  1. 转到管理控制台,然后单击“全局 init 脚本”选项卡。

  2. 单击“+ 添加”按钮。

  3. 输入脚本名称。

  4. 将以下脚本复制到“脚本”字段中。

     #!/bin/bash
    
     echo 'Init script to remove certain Log4J 1.x classes, version 1.0 (2021-12-17)'
    
     FILES_TO_DELETE=(
       org/apache/log4j/net/JMSAppender.class
       org/apache/log4j/net/SocketServer.class
     )
    
     find "/databricks" \
         -name '*log4j*.jar' \
         -exec echo -e "\nProcessing {}" \; -exec zip -d {} "${FILES_TO_DELETE[@]}" \;
    
     exit 0
    

    Global init script to remove Log4j 1.x JMSAppender and SocketServer classes from the classpath.

  5. 如果为工作区配置了多个全局 init 脚本,则应将此脚本配置为在其他脚本之后运行。

  6. 确保“启用”的开关已打开。

  7. 单击“添加”。

  8. 重新启动所有正在运行的群集。

验证受影响的类是否不可用

应在每个群集上运行测试,以确保受影响的类不可用。

测试 1

可以对笔记本中受影响的类运行断言检查。

assert(this.getClass.getClassLoader().getResource("org/apache/log4j/net/JMSAppender.class") == null)
assert(this.getClass.getClassLoader().getResource("org/apache/log4j/net/SocketServer.class") == null)

如果已禁用受影响的类,则此示例代码将成功运行。

如果未禁用受影响的类,则此示例代码应返回错误。

测试 2

可以尝试将受影响的类导入到笔记本中。

import org.apache.log4j.net.JMSAppender
import org.apache.log4j.net.SocketServer

如果未禁用受影响的类,则此示例代码将成功运行。

如果已禁用受影响的类,则此示例代码应返回错误。

注意事项

在某些极端情况下,可以重新引入 JMSAppender 或 SocketServer 的 Log4j 1.x 版本。

问题

如果在 Log4j 1.x 上安装具有可传递依赖项的 Maven 库,则会将其所有类重新添加到类路径中。

解决方案

在安装 Maven 库时,可以通过将 Log4j 添加到“排除项”字段来解决此问题。

Install Maven library options showing the Exclusions field.

问题

如果配置外部 Apache Hive 元存储,则 Apache Spark 使用 Ivy 来解析和下载正确的元存储客户端库及其所有可传递的依赖项,其中可能包括 Log4j 1.x。

若要加快群集启动速度,可以在 DBFS 上缓存下载的 jar,并使用 init 脚本从缓存中进行安装。 如果缓存这样的 jar,则可能会包含 Log4j 1.x。

解决方案

可以为外部元存储配置 init 脚本,以删除受影响的类。