在 Log4j XML 配置文件中将 formatMsgNoLookups 放在哪里
Where to put formatMsgNoLookups in the Log4j XML configuration file
我使用 XML 文件配置我的 Log4j。我应该在哪里添加 formatMsgNoLookups=true?
<?xml version="1.0" encoding="UTF-8"?>
<!-- Upload files compare config -->
<configuration status="OFF">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} %p - %msg%n"/>
</Console>
<!-- http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender -->
<RollingFile name="File" fileName="logs/MyLogFile.log"
filePattern="logs/MyLogFile-%d{yyyy-MM-dd}.log"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d %p %c{1.} %m%n</Pattern>
</PatternLayout>
</RollingFile>
</appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</configuration>
作为 ,禁用 Log4j 查找的选项不是配置选项,而是系统 属性
log4j2.formatMsgNoLookups
根据您的环境(Spring, stand-alone executable, Tomcat 网络应用程序,...),系统属性的设置方式可能会有所不同。从 JAR 文件启动 Java 进程的最简单方法是添加
-Dlog4j2.formatMsgNoLookups=true
到您的命令行:
java -Dlog4j2.formatMsgNoLookups=true -jar myapp.jar
CVE-2021-44228 Log4Shell 漏洞
如果可以,升级到 Log4j2 + Java 版本,如 Apache logging site 上的安全细节所推荐。自从我原来的 post 以来,这个网站已经改变了;始终遵循 Apache 网站推荐的指南。
Apache 站点先前针对针对早期版本的 Log4j2 报告的 JNDI 查找漏洞提出了一些解决方法。
IMO:这是一个非常严重的漏洞,您不应该考虑这些解决方法,并且在您阅读本文时它们可能无济于事。升级 Log4j JAR 文件并查看下面关于要检查的地方的注释。
- 启动VM时设置系统属性
log4j2.formatMsgNoLookups
,作为
java -Dlog4j2.formatMsgNoLookups=true ...
.
- 将环境变量
LOG4J_FORMAT_MSG_NO_LOOKUPS
设置为 true。
- 对于从 2.0-beta9 到 2.10.0 的版本,缓解措施是从 class 路径中删除
org/apache/logging/log4j/core/lookup/JndiLookup.class
- 请参阅 log4j-core-*.jar
。
- 将某些版本的格式模式
%m
替换为 %m{nolookups}
我找不到 LOG4J_FORMAT_MSG_NO_LOOKUPS
when 运行 a grep
on the Java source code for 2.14.0
, 所以不清楚这是否有帮助全部.
某些 JDK 版本降低了风险:JDK 大于 6u211、7u201、8u191 和 11.0.1 不受影响,因为默认应用于 LDAP 查找。尽可能升级。
检查Log4j使用的一些地方
检查您使用的 Java 版本是否足够新:
java -version
扫描您的应用程序发布结构、应用程序服务器、开发环境以查找可能的 Log4j 旧版本:
find yourReleaseDir -type f -name log4j\*jar
如果您不确定您使用的是哪个 Log4j 版本,请在 ZIP 工具中打开 JAR 文件并查看 META-INF\MANIFEST.MF
- 可能有一行包含版本详细信息:
Log4jReleaseVersion: A.B.C
查看每个发布机器上的运行进程,看看是否有任何打开的Log4j JAR文件的文件句柄:
lsof | grep log4j
同时扫描计算机以验证 Java VM 是否是您期望的版本。这可能会发现更多需要处理的应用程序:
ps -ef | egrep "(java|jdk)" #OR: | grep -v grep
扫描应用程序服务器上的 EAR 和 WAR 存档以验证容器存档中没有任何嵌入式 Log4j JAR 文件。您可以使用 find
和 unzip
命令执行此操作,或者尝试我写的 ShowClassVersions
class 来检测 this answer. This would print out names of JAR files inside WAR and EAR 文件中的 Java 编译器版本:
java ShowClassVersions.java app_server_dir |grep log4j
app_server_dir/somewebapp.war => WEB-INF/lib/log4j2-core.jar
您可以这样做:%m{nolookups}
在布局中。
{nolookups}
是您在配置 XML 内容中设置 属性 log4j2.formatMsgNoLookups=true
的方式。
引用自 Log4j 源代码:
public static final boolean FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS =
PropertiesUtil.getProperties().getBooleanProperty("log4j2.formatMsgNoLookups",
false);
及其 javadoc:
LOG4J2-2109 if true, MessagePatternConverter will always operate as
though
%m{nolookups}
is configured.
Since:
2.10
在export catalina_opts
或export java_options
下添加分隔符-Dlog4j2.formatMsgNoLookups=true
。
请记住始终从下面列出的资源中获取最新信息。
CVE-2021-45105... 2.16.0 和 2.12.2 不再是有效的补救措施!当前修复版本为 2.17.0 (Java 8) 和 2.12.3 (Java 7)。所有其他 Java 版本必须采取权宜之计方法(removing/deleting JndiLookup.class 来自 log4j-core JAR 的文件。
环境变量选项不再被视为有效的补救或缓解措施。从技术上讲,它会稍微减少漏洞的暴露,但实际上不会修复任何东西。我在下面概述了补救信息。
- 更多资源
- Log4j 0day being exploited
- 这个有 吨 有用的信息,包括检测器、更多资源链接、非常容易理解的补救步骤等等
- Apache Log4j Vulnerability Guidance
- CISA Log4j (CVE-2021-44228) Vulnerability Guidance
- Apache Log4j Security Vulnerabilities
修复:
CVE-2021-45046 ... CVE-2021-44228 ... CVE-2021-45105
- 遵循这些资源中的指导...它可能会改变,但是
截至 2021-12-18
基本上是
- 如果可能,删除 log4j-core JAR 文件
- 从两台 运行 机器上立即修复 和
- 在您的源代码/源代码管理文件中,以防止未来的构建/发布/部署覆盖更改
- 如果那不可能(由于依赖),升级它们
- 如果你是运行Java8,那么你可以升级到Log4j 2.17.0+
- 如果你是运行Java7,那么你可以升级到Log4j 2.12.3
- 如果您运行是Java的旧版本,那么您需要升级到Java的最新版本,然后使用最新版本的Log4J
- 同样,这些更改必须同时发生在 运行 机器和代码中
- 如果由于某种原因这些都不可能...那么有 非-补救停止间隙从 [=44] 中删除 JndiLookup.class 文件=]log4j-core JAR 文件。
- 在 Linux 上使用
zip
命令有一个止损选项,默认情况下与大多数 Linux 发行版一起打包。
zip -q -d "$LOG4J_JAR_PATH" org/apache/logging/log4j/core/lookup/JndiLookup.class
- 在撰写本文时,Windows 上关于权宜之计选项的大多数在线指南都说要执行以下操作(再次...假设您不能执行删除 JAR 或升级选项之一多于):
- 安装类似 7-Zip
的东西
- 找到所有 log4j-core JAR 文件,对每个文件执行以下操作...
- 重命名 JAR 以将扩展名更改为
.zip
- 使用 7-Zip 解压缩 JAR 文件(现在具有
.zip
扩展名)
- 从解压缩的文件夹中找到并删除 JndiLookup.class 文件
- 路径是
\path\to\unzippedFolder\org\apache\logging\log4j\core\lookup\JndiLookup.class
- 删除旧的 JAR 文件(现在扩展名为 .zip)
- 使用 7-Zip 重新-zip 文件夹
- 重命名新的 .zip 文件夹以将扩展名更改为
.jar
- 还有一些使用PowerShell的选项
- Reddit thread: log4j_0day_being_exploited
- Ctrl + F 用于“PowerShell”
如果您只有一个或两个 JAR 文件要处理并且您不介意安装 7-Zip 或您有可用的 PowerShell 来执行此操作,这很好。但是,如果您有很多 JAR 文件,或者如果您不想安装 7-Zip 并且无法访问 PowerShell,我创建了一个开源 VBScript script (.vbs) that will do it for you without needing to install any additional software. Windowslog4jClassRemover
阅读自述文件和发行说明 - Release: The light is really easy to read & follow now CrazyKidJack/Windowslog4jClassRemover
关于要使用的变量有很多混淆,log4j2.formatMsgNoLookups、log4j.formatMsgNoLookups 等。请记住,如 PropertySource.java,
/ **
* Converts a property name string into a list of tokens. This will strip a prefix of {@code log4j},
* {@code log4j2}, {@code Log4j}, or {@code org.apache.logging.log4j}, along with separators of
* dash {@code -}, dot {@code.}, underscore {@code _}, and slash {@code /}. Tokens can also be separated
* by camel case conventions without needing a separator character in between.
*
* @param value property name
* @return the property broken into lower case tokens
* /
您可以为变量使用不同的值,因为您可以使用此测试代码进行检查(不幸的是,您必须在静态块中指示系统的属性,以便测试不同的选项,您必须注释或取消注释测试的不同行)。
package org.apache.logging.log4j.core.pattern;
import org.apache.logging.log4j.core.util.Constants;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/ **
*
* /
public class Log4jParameterTest {
static {
// Test Ok. All working
// System.setProperty ("log4j2.formatMsgNoLookups", "true");
// System.setProperty ("log4j.formatMsgNoLookups", "true");
// System.setProperty ("Log4j.formatMsgNoLookups", "true");
// System.setProperty ("org.apache.logging.log4j.formatMsgNoLookups", "true");
// System.setProperty ("log4j2-formatMsgNoLookups", "true");
// System.setProperty ("log4j2_formatMsgNoLookups", "true");
System.setProperty ("log4j2 / formatMsgNoLookups", "true");
// Test KO. All fail
// System.setProperty ("log5j2.formatMsgNoLookups", "true");
// System.setProperty ("log5j2-formatMsgNoLookups", "true");
}
@Test
public void testLookupEnabledByDefault () {
assertTrue ("Lookups deactivated", Constants.FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS);
}
}
给谁用 log4j-xml-config-file:
- 在 PatternLayout
中将 %m
替换为 %m{nolookups}
- 添加系统属性 log4j.formatMsgNoLookups = true:
System.setProperty("log4j2.formatMsgNoLookups", "true");
我使用 XML 文件配置我的 Log4j。我应该在哪里添加 formatMsgNoLookups=true?
<?xml version="1.0" encoding="UTF-8"?>
<!-- Upload files compare config -->
<configuration status="OFF">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} %p - %msg%n"/>
</Console>
<!-- http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender -->
<RollingFile name="File" fileName="logs/MyLogFile.log"
filePattern="logs/MyLogFile-%d{yyyy-MM-dd}.log"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d %p %c{1.} %m%n</Pattern>
</PatternLayout>
</RollingFile>
</appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</configuration>
作为
log4j2.formatMsgNoLookups
根据您的环境(Spring, stand-alone executable, Tomcat 网络应用程序,...),系统属性的设置方式可能会有所不同。从 JAR 文件启动 Java 进程的最简单方法是添加
-Dlog4j2.formatMsgNoLookups=true
到您的命令行:
java -Dlog4j2.formatMsgNoLookups=true -jar myapp.jar
CVE-2021-44228 Log4Shell 漏洞
如果可以,升级到 Log4j2 + Java 版本,如 Apache logging site 上的安全细节所推荐。自从我原来的 post 以来,这个网站已经改变了;始终遵循 Apache 网站推荐的指南。
Apache 站点先前针对针对早期版本的 Log4j2 报告的 JNDI 查找漏洞提出了一些解决方法。
IMO:这是一个非常严重的漏洞,您不应该考虑这些解决方法,并且在您阅读本文时它们可能无济于事。升级 Log4j JAR 文件并查看下面关于要检查的地方的注释。
- 启动VM时设置系统属性
log4j2.formatMsgNoLookups
,作为java -Dlog4j2.formatMsgNoLookups=true ...
. - 将环境变量
LOG4J_FORMAT_MSG_NO_LOOKUPS
设置为 true。 - 对于从 2.0-beta9 到 2.10.0 的版本,缓解措施是从 class 路径中删除
org/apache/logging/log4j/core/lookup/JndiLookup.class
- 请参阅log4j-core-*.jar
。 - 将某些版本的格式模式
%m
替换为%m{nolookups}
我找不到 LOG4J_FORMAT_MSG_NO_LOOKUPS
when 运行 a grep
on the Java source code for 2.14.0
, 所以不清楚这是否有帮助全部.
某些 JDK 版本降低了风险:JDK 大于 6u211、7u201、8u191 和 11.0.1 不受影响,因为默认应用于 LDAP 查找。尽可能升级。
检查Log4j使用的一些地方
检查您使用的 Java 版本是否足够新:
java -version
扫描您的应用程序发布结构、应用程序服务器、开发环境以查找可能的 Log4j 旧版本:
find yourReleaseDir -type f -name log4j\*jar
如果您不确定您使用的是哪个 Log4j 版本,请在 ZIP 工具中打开 JAR 文件并查看 META-INF\MANIFEST.MF
- 可能有一行包含版本详细信息:
Log4jReleaseVersion: A.B.C
查看每个发布机器上的运行进程,看看是否有任何打开的Log4j JAR文件的文件句柄:
lsof | grep log4j
同时扫描计算机以验证 Java VM 是否是您期望的版本。这可能会发现更多需要处理的应用程序:
ps -ef | egrep "(java|jdk)" #OR: | grep -v grep
扫描应用程序服务器上的 EAR 和 WAR 存档以验证容器存档中没有任何嵌入式 Log4j JAR 文件。您可以使用 find
和 unzip
命令执行此操作,或者尝试我写的 ShowClassVersions
class 来检测 this answer. This would print out names of JAR files inside WAR and EAR 文件中的 Java 编译器版本:
java ShowClassVersions.java app_server_dir |grep log4j
app_server_dir/somewebapp.war => WEB-INF/lib/log4j2-core.jar
您可以这样做:%m{nolookups}
在布局中。
{nolookups}
是您在配置 XML 内容中设置 属性 log4j2.formatMsgNoLookups=true
的方式。
引用自 Log4j 源代码:
public static final boolean FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS = PropertiesUtil.getProperties().getBooleanProperty("log4j2.formatMsgNoLookups", false);
及其 javadoc:
LOG4J2-2109 if true, MessagePatternConverter will always operate as though
%m{nolookups}
is configured.
Since:
2.10
在export catalina_opts
或export java_options
下添加分隔符-Dlog4j2.formatMsgNoLookups=true
。
请记住始终从下面列出的资源中获取最新信息。
CVE-2021-45105... 2.16.0 和 2.12.2 不再是有效的补救措施!当前修复版本为 2.17.0 (Java 8) 和 2.12.3 (Java 7)。所有其他 Java 版本必须采取权宜之计方法(removing/deleting JndiLookup.class 来自 log4j-core JAR 的文件。
环境变量选项不再被视为有效的补救或缓解措施。从技术上讲,它会稍微减少漏洞的暴露,但实际上不会修复任何东西。我在下面概述了补救信息。
- 更多资源
- Log4j 0day being exploited
- 这个有 吨 有用的信息,包括检测器、更多资源链接、非常容易理解的补救步骤等等
- Apache Log4j Vulnerability Guidance
- CISA Log4j (CVE-2021-44228) Vulnerability Guidance
- Apache Log4j Security Vulnerabilities
- Log4j 0day being exploited
修复:
CVE-2021-45046 ... CVE-2021-44228 ... CVE-2021-45105
- 遵循这些资源中的指导...它可能会改变,但是
截至 2021-12-18
基本上是
- 如果可能,删除 log4j-core JAR 文件
- 从两台 运行 机器上立即修复 和
- 在您的源代码/源代码管理文件中,以防止未来的构建/发布/部署覆盖更改
- 如果那不可能(由于依赖),升级它们
- 如果你是运行Java8,那么你可以升级到Log4j 2.17.0+
- 如果你是运行Java7,那么你可以升级到Log4j 2.12.3
- 如果您运行是Java的旧版本,那么您需要升级到Java的最新版本,然后使用最新版本的Log4J
- 同样,这些更改必须同时发生在 运行 机器和代码中
- 如果由于某种原因这些都不可能...那么有 非-补救停止间隙从 [=44] 中删除 JndiLookup.class 文件=]log4j-core JAR 文件。
- 在 Linux 上使用
zip
命令有一个止损选项,默认情况下与大多数 Linux 发行版一起打包。zip -q -d "$LOG4J_JAR_PATH" org/apache/logging/log4j/core/lookup/JndiLookup.class
- 在撰写本文时,Windows 上关于权宜之计选项的大多数在线指南都说要执行以下操作(再次...假设您不能执行删除 JAR 或升级选项之一多于):
- 安装类似 7-Zip 的东西
- 找到所有 log4j-core JAR 文件,对每个文件执行以下操作...
- 重命名 JAR 以将扩展名更改为
.zip
- 使用 7-Zip 解压缩 JAR 文件(现在具有
.zip
扩展名) - 从解压缩的文件夹中找到并删除 JndiLookup.class 文件
- 路径是
\path\to\unzippedFolder\org\apache\logging\log4j\core\lookup\JndiLookup.class
- 路径是
- 删除旧的 JAR 文件(现在扩展名为 .zip)
- 使用 7-Zip 重新-zip 文件夹
- 重命名新的 .zip 文件夹以将扩展名更改为
.jar
- 还有一些使用PowerShell的选项
- Reddit thread: log4j_0day_being_exploited
- Ctrl + F 用于“PowerShell”
- 在 Linux 上使用
如果您只有一个或两个 JAR 文件要处理并且您不介意安装 7-Zip 或您有可用的 PowerShell 来执行此操作,这很好。但是,如果您有很多 JAR 文件,或者如果您不想安装 7-Zip 并且无法访问 PowerShell,我创建了一个开源 VBScript script (.vbs) that will do it for you without needing to install any additional software. Windowslog4jClassRemover
阅读自述文件和发行说明 - Release: The light is really easy to read & follow now CrazyKidJack/Windowslog4jClassRemover
关于要使用的变量有很多混淆,log4j2.formatMsgNoLookups、log4j.formatMsgNoLookups 等。请记住,如 PropertySource.java,
/ **
* Converts a property name string into a list of tokens. This will strip a prefix of {@code log4j},
* {@code log4j2}, {@code Log4j}, or {@code org.apache.logging.log4j}, along with separators of
* dash {@code -}, dot {@code.}, underscore {@code _}, and slash {@code /}. Tokens can also be separated
* by camel case conventions without needing a separator character in between.
*
* @param value property name
* @return the property broken into lower case tokens
* /
您可以为变量使用不同的值,因为您可以使用此测试代码进行检查(不幸的是,您必须在静态块中指示系统的属性,以便测试不同的选项,您必须注释或取消注释测试的不同行)。
package org.apache.logging.log4j.core.pattern;
import org.apache.logging.log4j.core.util.Constants;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/ **
*
* /
public class Log4jParameterTest {
static {
// Test Ok. All working
// System.setProperty ("log4j2.formatMsgNoLookups", "true");
// System.setProperty ("log4j.formatMsgNoLookups", "true");
// System.setProperty ("Log4j.formatMsgNoLookups", "true");
// System.setProperty ("org.apache.logging.log4j.formatMsgNoLookups", "true");
// System.setProperty ("log4j2-formatMsgNoLookups", "true");
// System.setProperty ("log4j2_formatMsgNoLookups", "true");
System.setProperty ("log4j2 / formatMsgNoLookups", "true");
// Test KO. All fail
// System.setProperty ("log5j2.formatMsgNoLookups", "true");
// System.setProperty ("log5j2-formatMsgNoLookups", "true");
}
@Test
public void testLookupEnabledByDefault () {
assertTrue ("Lookups deactivated", Constants.FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS);
}
}
给谁用 log4j-xml-config-file:
- 在 PatternLayout 中将
- 添加系统属性 log4j.formatMsgNoLookups = true:
System.setProperty("log4j2.formatMsgNoLookups", "true");
%m
替换为 %m{nolookups}