如何把kafka Log4j1.x升级到Log4j2.x ?
背景说明
官方于又于2021.12.13号官方已经发布稳定修复漏洞版本 https://logging.apache.org/log4j/2.x/download.html 「2.16.0」,看了一下提交记录,删除了Messge Lookups的方法。
大家以为的终极版本2.16.0出来后,又爆出DOS拒绝服务攻击漏洞,所以官方在「2021.12.17」又推出了最新版本 「2.17.0」
继官方推出2.17.0版本修复DOS拒绝服务攻击后,又出现远程代码执行 (RCE) 攻击的特征漏洞,官方于2021.12.28推出了 「2.17.1」 版本,虽然此漏洞的利用条件极高,需要可以控制配置文件,但是官方评分还是6.6分(https://logging.apache.org/log4j/2.x/security.html#),属于「中危漏洞」。
最近看官方,2022-02-23又升级到2.17.2了,但是看官方安全说明是正常迭代,不涉及修复关联漏洞。
利用Java语言开发的程序其实好多都在用Log4j日志框架,当然也包括我们常用的开源服务kafka、zookeeper、Nacos等。
比如这些开源的服务就有一个特征,就是当你线上使用是较老一点点的版本,基本里面引用的都是Log4j 1版本,虽然log4j 2的远程代码执行漏洞没有连累1.x版本,但是1.x版本也有漏洞(CVE-2020-9488 CVE-2019-17571), 而且1.x版本是EOL状态的版本,并且最新1.x版本的包是没有解决漏洞问题的。
从log4j2的官网https://logging.apache.org/log4j/2.x/了解到,log4j1.x和log4j2.x是存在一定的兼容性的,它们实现的都是SLF4J的API,理论上来说是可以通过替换Jar包切换的, 所以今天我这里介绍一下Kafka和Zookeepr替换修复的方法。
我这里还是以官方最新发布的2.17.2的版本为例子。
zookeeper从log4j1.x升级到log4j2.x
基本信息,kafka版本:3.4.14 操作系统:Centos7.9 Java版本:1.8.0_152 ,升级过程如下。
1、下载官方最新log4j 2.17.2版本包并解压
wget --no-check-certificate https://dlcdn.apache.org/logging/log4j/2.17.2/apache-log4j-2.17.2-bin.tar.gz
tar xf apache-log4j-2.17.2-bin.tar.gz
2、同时下载要替换的slf4j-api 1.7.32版本jar包
wget --no-check-certificate https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar
3、查询zookeeper引用信息
[root@labs zookeeper]# ls lib/ |grep -Ei 'log4j|slf'
log4j-1.2.17.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
然后分别删除slf4j-log4j12、slf4j-api和log4j三个包:
[root@labs kafka]# rm -f lib/{slf4j-log4j12-1.7.25.jar,slf4j-api-1.7.25.jar,log4j-1.2.17.jar}
4、替换新包
分别把apache-log4j-2.17.2-bin目录下的:
log4j-1.2-api-2.17.2.jar
log4j-api-2.17.2.jar
log4j-core-2.17.2.jar
log4j-slf4j-impl-2.17.2.jar
和slef4j-api-1.7.32.jar
同步到zookeeper安装目录下的lib目录下。
5、关闭jmx
如果不关闭jmx,zookeeper启动会报类(org.apache.log4j.jmx.HierarchyDynamicMBean
)找不到,详情如下:
[root@labs zookeeper]# cat /data/logs/zookeeper/zookeeper.out
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/jmx/HierarchyDynamicMBean
at org.apache.zookeeper.jmx.ManagedUtil.registerLog4jMBeans(ManagedUtil.java:51)
at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooKeeperServerMain.java:77)
at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:55)
at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:119)
at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:81)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.jmx.HierarchyDynamicMBean
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 5 more
如上源码可知前置条件是JMX开启才才会加载此类实例化,并不是直接import的, 因为zookeeper启动可以设置参数来控制是否启用jmx,所以简单粗暴的方式就是,直接修改启动脚本bin/zkServer.sh
,然后启动。
ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY -Dzookeeper.jmx.log4j.disable=true org.apache.zookeeper.server.quorum.QuorumPeerMain"
但是这有个问题,就是你全局禁用了,so,可能影响jmx监控数据的采集,所以可以看看源代码尝试完全修复 or 临时跳过,最简单:
if (Boolean.getBoolean("zookeeper.jmx.log4j.disable") == true) {
return;
}
改成:
if (1 == 1) {
return;
}
5、测试可用性
-
启动zookeeper服务,看看是否可以正常运行; -
然后利用zkCli.sh客户端连接,进行create,get等操作验证。
kafka从log4j1.x升级到log4j2.x
基本信息,kafka版本:2.2.2 操作系统:Centos7.9 Java版本:1.8.0_152 ,升级过程如下。
1、下载官方最新log4j 2.17.2版本包并解压
wget --no-check-certificate https://dlcdn.apache.org/logging/log4j/2.17.2/apache-log4j-2.17.2-bin.tar.gz
tar xf apache-log4j-2.17.2-bin.tar.gz
2、同时下载要替换的slf4j-api 1.7.32版本jar包
wget --no-check-certificate https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.32/slf4j-api-1.7.32.jar
3、查询kafka引用信息
[root@labs kafka]# ls libs/ |grep -Ei 'slf|log4j'
kafka-log4j-appender-2.2.2.jar
log4j-1.2.17.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
然后分别删除slf4j-log4j12、slf4j-api和log4j三个包:
[root@labs kafka]# rm -f libs/{slf4j-log4j12-1.7.25.jar,slf4j-api-1.7.25.jar,log4j-1.2.17.jar}
4、替换新包
分别把apache-log4j-2.17.2-bin目录下的:
log4j-1.2-api-2.17.2.jar
log4j-api-2.17.2.jar
log4j-core-2.17.2.jar
log4j-slf4j-impl-2.17.2.jar
和slef4j-api-1.7.32.jar
同步到kafka安装目录下的libs目录下。
5、测试可用性
-
启动kafka服务看看可以正常启动吗; -
利用自带生产者工具kafka-console-producer.sh和消费者工具kafka-console-consumer.sh测试功能。