问题背景
karaf
框架没有直接依赖log4j
包,所以简单的升级项目中的log4j
或实际项目中没有log4j
,都无法解决最近发现的漏洞问题(CVE-2021-44228、CVE-2021-45046、CVE-2021-45046)。
分析过程
分析发现,karaf
框架实际依赖的日志包是org.ops4j.pax.logging.xxx
,而org.ops4j.pax.logging.xxx
依赖了log4j
,相当于做了一层包装。所以,要解决漏洞,有三种升级方式:
- 升级框架:这个影响就比较大了,而且框架的版本发布周期比较慢,目前还没有编译好的框架包,要升级框架就需要自己编译出所有的框架包,风险较大;
- 升级依赖包:影响较小,如果没有配置依赖包的地方,可能无法升级;(实际确认,无法单独升级)
- 修改当前版本依赖包并重新编译:影响较小,如果与最新版本跨度较大,可能修改点会很多;
综合比较,考虑使用第3个方案走走看,从参考资料[1]的代码提交记录看,org.ops4j.pax.logging
为了解决log4j
漏洞,仅涉及依赖包log4j
的版本升级,版本跨度是从1.11.9
升级到1.11.12
,跨度不大,实际有哪些修改点,先编译看看有没有问题:
1 | pom.xml |
下载当前使用的版本,从源码的各模块看,可能需要jdk9
:
1 | [root@node org.ops4j.pax.logging-logging-1.11.9]# ll |
先下载个maven:3.3.9-jdk-9
编译镜像试试:
1 | docker pull maven:3.3.9-jdk-9 |
启动编译,先尝试编译原始版本:
1 | docker run -it -v /home:/home docker.io/library/maven:3.3.9-jdk-9 bash |
参考资料[2],问题出在编译镜像的$JAVA_HOME/conf
命令下找不到一个安全相关的配置文件,查看一下发现conf
文件夹都不存在,说明编译镜像有问题:
1 | root@aae0956cb558:/home/org.ops4j.pax.logging-logging-1.11.9# env |
那就换个新版本试试,下载maven:3.6-openjdk-11
编译镜像:
1 | docker pull maven:3.6-openjdk-11 |
启动编译:
1 | docker run -it -v /home:/home maven:3.6-openjdk-11 bash |
第一个问题解决了,但从报错信息看,应该是要求jdk9
的版本,那就再换一个maven:3.5-jdk-9-slim
镜像:
1 | docker pull maven:3.5-jdk-9-slim |
继续编译:
1 | docker run -it -v /home:/home docker.io/library/maven:3.5-jdk-9-slim bash |
当前编译镜像已经符合要求了,但依然报错,参考资料[3],需要在~/.m2/
目录下创建toolchains.xml
文件并做相关配置:
通过env
命令查看java
的相关环境变量:
1 | root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# env |
修改version
和jdkHome
字段:
1 |
|
继续编译:
1 | root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true |
失败在test
模块,测试模块不影响,修改pom.xml
注释掉即可;
再编译:
1 | root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true |
不容易,终于成功了!开始修改pod.xml
,把依赖的log4j
包升级上去:
1 | - <version.org.apache.logging.log4j>2.14.0</version.org.apache.logging.log4j> |
编译:
1 | root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true |
又报错了,找到官方升级过log4j
的版本,发现ThrowableProxy
方法的构造方法里suppressedProxies
字段的赋值有变化,老版本是ThrowableProxyHelper.EMPTY_THROWABLE_PROXY_ARRAY
,而新版本变成了ThrowableProxy.EMPTY_ARRAY
。问题不大,改一下就行;
1 | src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java |
再次编译:
1 | root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true |
升级log4j
的版本编译成功。
解决方案
把新编译的pax-logging-api
和pax-logging-log4j
替换到依赖仓库中,重新编译交付件,验证漏洞解决,日志功能正常。