0%

Karaf框架升级Lg4j历程

问题背景

karaf框架没有直接依赖log4j包,所以简单的升级项目中的log4j或实际项目中没有log4j,都无法解决最近发现的漏洞问题(CVE-2021-44228CVE-2021-45046CVE-2021-45046)。

分析过程

分析发现,karaf框架实际依赖的日志包是org.ops4j.pax.logging.xxx,而org.ops4j.pax.logging.xxx依赖了log4j,相当于做了一层包装。所以,要解决漏洞,有三种升级方式:

  1. 升级框架:这个影响就比较大了,而且框架的版本发布周期比较慢,目前还没有编译好的框架包,要升级框架就需要自己编译出所有的框架包,风险较大;
  2. 升级依赖包:影响较小,如果没有配置依赖包的地方,可能无法升级;(实际确认,无法单独升级)
  3. 修改当前版本依赖包并重新编译:影响较小,如果与最新版本跨度较大,可能修改点会很多;

综合比较,考虑使用第3个方案走走看,从参考资料[1]的代码提交记录看,org.ops4j.pax.logging为了解决log4j漏洞,仅涉及依赖包log4j的版本升级,版本跨度是从1.11.9升级到1.11.12,跨度不大,实际有哪些修改点,先编译看看有没有问题:

1
2
3
4
5
6
7
8
9
pom.xml
<version.org.apache.felix.configadmin>1.9.20</version.org.apache.felix.configadmin>
<version.org.apache.felix.framework>5.6.12</version.org.apache.felix.framework>
<version.org.apache.felix6.framework>6.0.3</version.org.apache.felix6.framework>
- <version.org.apache.logging.log4j>2.16.0</version.org.apache.logging.log4j>
+ <version.org.apache.logging.log4j>2.17.0</version.org.apache.logging.log4j>
<version.org.apache.servicemix.bundles.javax-inject>1_3</version.org.apache.servicemix.bundles.javax-inject>
<version.org.jboss.logging>3.4.1.Final</version.org.jboss.logging>
<version.org.mockito>3.7.7</version.org.mockito>

下载当前使用的版本,从源码的各模块看,可能需要jdk9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@node org.ops4j.pax.logging-logging-1.11.9]# ll
total 144
-rw-r--r-- 1 root root 939 Feb 23 2021 CONTRIBUTORS.txt
-rw-r--r-- 1 root root 755 Feb 23 2021 license-header.txt
-rw-r--r-- 1 root root 12525 Feb 23 2021 LICENSE.txt
drwxr-xr-x 4 root root 99 Dec 21 17:51 pax-logging-api
drwxr-xr-x 4 root root 46 Dec 21 17:51 pax-logging-api-java9
drwxr-xr-x 4 root root 46 Dec 21 17:51 pax-logging-it
drwxr-xr-x 6 root root 106 Feb 23 2021 pax-logging-it-karaf
drwxr-xr-x 4 root root 99 Dec 21 17:51 pax-logging-log4j2
drwxr-xr-x 4 root root 99 Dec 21 17:51 pax-logging-log4j2-extra
drwxr-xr-x 4 root root 99 Dec 21 17:51 pax-logging-logback
drwxr-xr-x 2 root root 21 Feb 23 2021 pax-logging-report
drwxr-xr-x 10 root root 166 Feb 23 2021 pax-logging-samples
drwxr-xr-x 4 root root 99 Dec 21 17:51 pax-logging-service
-rw-r--r-- 1 root root 46604 Dec 21 17:46 pom.xml
-rw-r--r-- 1 root root 67356 Feb 23 2021 readme.adoc
drwxr-xr-x 3 root root 18 Feb 23 2021 src

先下载个maven:3.3.9-jdk-9编译镜像试试:

1
2
3
4
5
6
7
[root@node]# docker pull maven:3.3.9-jdk-9
3.3.9-jdk-9: Pulling from library/maven
...
2ce3b259f3e2: Pull complete
Digest: sha256:ad6b04c52e7f83c05e8840e0b1de0c39ba097c1e40efb294e740db303468cbe8
Status: Downloaded newer image for maven:3.3.9-jdk-9
docker.io/library/maven:3.3.9-jdk-9

启动编译,先尝试编译原始版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@node]# docker run -it -v /home:/home docker.io/library/maven:3.3.9-jdk-9 bash
root@aae0956cb558:/home# cd org.ops4j.pax.logging-logging-1.11.9
root@aae0956cb558:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[WARNING] Error injecting: org.apache.maven.wagon.providers.http.HttpWagon
java.lang.ExceptionInInitializerError
at java.base/javax.crypto.JceSecurityManager.<clinit>(JceSecurityManager.java:66)
at java.base/javax.crypto.Cipher.getConfiguredPermission(Cipher.java:2610)
at java.base/javax.crypto.Cipher.getMaxAllowedKeyLength(Cipher.java:2634)
...
Caused by: java.lang.SecurityException: Can not initialize cryptographic mechanism
at java.base/javax.crypto.JceSecurity.<clinit>(JceSecurity.java:118)
... 96 more
Caused by: java.lang.SecurityException: Can't read cryptographic policy directory: unlimited
at java.base/javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:324)
at java.base/javax.crypto.JceSecurity.access$000(JceSecurity.java:73)
at java.base/javax.crypto.JceSecurity$1.run(JceSecurity.java:109)
at java.base/javax.crypto.JceSecurity$1.run(JceSecurity.java:106)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/javax.crypto.JceSecurity.<clinit>(JceSecurity.java:105)
... 96 more

参考资料[2],问题出在编译镜像的$JAVA_HOME/conf命令下找不到一个安全相关的配置文件,查看一下发现conf文件夹都不存在,说明编译镜像有问题:

1
2
3
4
5
6
7
8
root@aae0956cb558:/home/org.ops4j.pax.logging-logging-1.11.9# env
JAVA_HOME=/usr/lib/jvm/java-9-openjdk-amd64

root@aae0956cb558:/home/org.ops4j.pax.logging-logging-1.11.9# ls /usr/lib/jvm/java-9-openjdk-amd64
bin docs include jmods legal lib man src.zip

//正常情况下$JAVA_HOME/conf目录下有以下文件
java-9-openjdk logging.properties management net.properties security sound.properties

那就换个新版本试试,下载maven:3.6-openjdk-11编译镜像:

1
2
3
4
5
6
[root@node]# docker pull maven:3.6-openjdk-11
3.6-openjdk-11: Pulling from library/maven
...s
Digest: sha256:1d29ccf46ef2a5e64f7de3d79a63f9bcffb4dc56be0ae3daed5ca5542b38aa2d
Status: Downloaded newer image for maven:3.6-openjdk-11
docker.io/library/maven:3.6-openjdk-11

启动编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@node]# docker run -it -v /home:/home maven:3.6-openjdk-11 bash
root@ff2407bc2d9e:/# cd /home/org.ops4j.pax.logging-logging-1.11.9
root@ff2407bc2d9e:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
Downloading from knopflerfish: http://resources.knopflerfish.org/repo/maven2/release/org/ops4j/master/4.3.0/master-4.3.0.pom
...
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ pax-logging-api-java9 ---
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M1:enforce (enforce-maven) @ pax-logging-api-java9 ---
[INFO]
[INFO] --- maven-toolchains-plugin:3.0.0:toolchain (default) @ pax-logging-api-java9 ---
[INFO] Required toolchain: jdk [ version='[9, )' ]
[ERROR] No toolchain found for type jdk
[ERROR] Cannot find matching toolchain definitions for the following toolchain types:
jdk [ version='[9, )' ]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for OPS4J Pax Logging (Build POM) 1.11.9:
[INFO]
[INFO] OPS4J Pax Logging (Build POM) ...................... SUCCESS [ 35.399 s]
[INFO] OPS4J Pax Logging - API (Java9) .................... FAILURE [ 10.045 s]
...
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-toolchains-plugin:3.0.0:toolchain (default) on project pax-logging-api-java9: Cannot find matching toolchain definitions for the following toolchain types:
[ERROR] jdk [ version='[9, )' ]
[ERROR] Please make sure you define the required toolchains in your ~/.m2/toolchains.xml file.

第一个问题解决了,但从报错信息看,应该是要求jdk9的版本,那就再换一个maven:3.5-jdk-9-slim镜像:

1
2
3
4
5
6
7
[root@node]# docker pull maven:3.5-jdk-9-slim
3.5-jdk-9-slim: Pulling from library/maven
...
7afb9733d3e4: Pull complete
Digest: sha256:f5d85a2b5498c0a36a6515722e108969ff2fcfec5bef6c8ef83c8ebc4b671af1
Status: Downloaded newer image for maven:3.5-jdk-9-slim
docker.io/library/maven:3.5-jdk-9-slim

继续编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@node]# docker run -it -v /home:/home docker.io/library/maven:3.5-jdk-9-slim  bash
root@895be557c3cd:/# cd /home/org.ops4j.pax.logging-logging-1.11.9
root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
Downloading from knopflerfish: http://resources.knopflerfish.org/repo/maven2/release/org/ops4j/master/4.3.0/master-4.3.0.pom
...
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ pax-logging-api-java9 ---
[INFO]
[INFO] --- maven-enforcer-plugin:3.0.0-M1:enforce (enforce-maven) @ pax-logging-api-java9 ---
[INFO]
[INFO] --- maven-toolchains-plugin:3.0.0:toolchain (default) @ pax-logging-api-java9 ---
[INFO] Required toolchain: jdk [ version='[9, )' ]
[ERROR] No toolchain found for type jdk
[ERROR] Cannot find matching toolchain definitions for the following toolchain types:
jdk [ version='[9, )' ]
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] OPS4J Pax Logging (Build POM) 1.11.9 ............... SUCCESS [01:27 min]
[INFO] OPS4J Pax Logging - API (Java9) .................... FAILURE [ 17.560 s]
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-toolchains-plugin:3.0.0:toolchain (default) on project pax-logging-api-java9: Cannot find matching toolchain definitions for the following toolchain types:
[ERROR] jdk [ version='[9, )' ]
[ERROR] Please make sure you define the required toolchains in your ~/.m2/toolchains.xml file.

当前编译镜像已经符合要求了,但依然报错,参考资料[3],需要在~/.m2/目录下创建toolchains.xml文件并做相关配置:

通过env命令查看java的相关环境变量:

1
2
3
4
5
6
root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# env
...
JAVA_HOME=/docker-java-home
JAVA_VERSION=9.0.4+12
JAVA_DEBIAN_VERSION=9.0.4+12-4
...

修改versionjdkHome字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# cat ~/.m2/toolchains.xml
<?xml version="1.0" encoding="UTF-8"?>
<toolchains xmlns="http://maven.apache.org/TOOLCHAINS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/TOOLCHAINS/1.1.0 http://maven.apache.org/xsd/toolchains-1.1.0.xsd">
<toolchain>
<type>jdk</type>
<provides>
<version>9</version>
<vendor>oracle</vendor>
</provides>
<configuration>
<jdkHome>/docker-java-home</jdkHome>
</configuration>
</toolchain>
</toolchains>

继续编译:

1
2
3
4
5
6
7
8
9
10
11
root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 19 modules...
[INFO] Installing Nexus Staging features:
[INFO] ... total of 19 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] Reactor Summary:
[INFO]
[INFO] OPS4J Pax Logging (Build POM) 1.11.9 ............... SUCCESS [ 0.335 s]
[INFO] OPS4J Pax Logging - API (Java9) .................... SUCCESS [ 40.867 s]
[INFO] OPS4J Pax Logging - API ............................ SUCCESS [ 51.690 s]
[INFO] OPS4J Pax Logging - API tests ...................... FAILURE [02:11 min]

失败在test模块,测试模块不影响,修改pom.xml注释掉即可;

再编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] OPS4J Pax Logging (Build POM) 1.11.9 ............... SUCCESS [ 0.275 s]
[INFO] OPS4J Pax Logging - API (Java9) .................... SUCCESS [ 1.873 s]
[INFO] OPS4J Pax Logging - API ............................ SUCCESS [ 4.672 s]
[INFO] OPS4J Pax Logging - Log4Jv1 implementation ......... SUCCESS [ 39.435 s]
[INFO] OPS4J Pax Logging - Log4Jv2 implementation ......... SUCCESS [ 8.208 s]
[INFO] OPS4J Pax Logging - Log4j v2 Extra packages ........ SUCCESS [ 0.131 s]
[INFO] OPS4J Pax Logging - Logback implementation ......... SUCCESS [ 15.241 s]
[INFO] OPS4J Pax Logging - Integration Tests .............. SUCCESS [01:48 min]
[INFO] OPS4J Pax Logging - Karaf .......................... SUCCESS [ 0.014 s]
[INFO] OPS4J Pax Logging - Karaf KAR Logger ............... SUCCESS [ 0.148 s]
[INFO] OPS4J Pax Logging - Karaf KAR ...................... SUCCESS [ 28.098 s]
[INFO] OPS4J Pax Logging - Karaf Distribution ............. SUCCESS [ 2.002 s]
[INFO] OPS4J Pax Logging - Karaf Integration Tests 1.11.9 . SUCCESS [ 36.557 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 04:07 min
[INFO] Finished at: 2021-12-21T09:45:18Z
[INFO] ------------------------------------------------------------------------

不容易,终于成功了!开始修改pod.xml,把依赖的log4j包升级上去:

1
2
- <version.org.apache.logging.log4j>2.14.0</version.org.apache.logging.log4j>
+ <version.org.apache.logging.log4j>2.17.0</version.org.apache.logging.log4j>

编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 13 modules...
[INFO] Installing Nexus Staging features:
[INFO] ... total of 13 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
...
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /home/org.ops4j.pax.logging-logging-1.11.9/pax-logging-log4j2/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java:[85,54] cannot find symbol
symbol: variable EMPTY_THROWABLE_PROXY_ARRAY
location: class org.apache.logging.log4j.core.impl.ThrowableProxyHelper
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] OPS4J Pax Logging (Build POM) 1.11.9 ............... SUCCESS [ 0.302 s]
[INFO] OPS4J Pax Logging - API (Java9) .................... SUCCESS [ 1.836 s]
[INFO] OPS4J Pax Logging - API ............................ SUCCESS [ 10.592 s]
[INFO] OPS4J Pax Logging - Log4Jv1 implementation ......... SUCCESS [ 2.017 s]
[INFO] OPS4J Pax Logging - Log4Jv2 implementation ......... FAILURE [ 4.279 s]

又报错了,找到官方升级过log4j的版本,发现ThrowableProxy方法的构造方法里suppressedProxies字段的赋值有变化,老版本是ThrowableProxyHelper.EMPTY_THROWABLE_PROXY_ARRAY,而新版本变成了ThrowableProxy.EMPTY_ARRAY。问题不大,改一下就行;

1
2
3
4
5
6
7
8
9
10
11
12
src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java
public class ThrowableProxy implements Serializable {
static final ThrowableProxy[] EMPTY_ARRAY = {};
ThrowableProxy() {
this.throwable = null;
this.name = null;
this.extendedStackTrace = ExtendedStackTraceElement.EMPTY_ARRAY;
this.causeProxy = null;
this.message = null;
this.localizedMessage = null;
this.suppressedProxies = ThrowableProxy.EMPTY_ARRAY;
}

再次编译:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
root@895be557c3cd:/home/org.ops4j.pax.logging-logging-1.11.9# mvn clean install -Dmaven.test.skip=true
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 13 modules...
[INFO] Installing Nexus Staging features:
[INFO] ... total of 13 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] OPS4J Pax Logging (Build POM) 1.11.9 ............... SUCCESS [ 0.290 s]
[INFO] OPS4J Pax Logging - API (Java9) .................... SUCCESS [ 1.819 s]
[INFO] OPS4J Pax Logging - API ............................ SUCCESS [ 4.717 s]
[INFO] OPS4J Pax Logging - Log4Jv1 implementation ......... SUCCESS [ 2.057 s]
[INFO] OPS4J Pax Logging - Log4Jv2 implementation ......... SUCCESS [ 2.654 s]
[INFO] OPS4J Pax Logging - Log4j v2 Extra packages ........ SUCCESS [ 0.144 s]
[INFO] OPS4J Pax Logging - Logback implementation ......... SUCCESS [ 0.908 s]
[INFO] OPS4J Pax Logging - Integration Tests .............. SUCCESS [ 4.402 s]
[INFO] OPS4J Pax Logging - Karaf .......................... SUCCESS [ 0.012 s]
[INFO] OPS4J Pax Logging - Karaf KAR Logger ............... SUCCESS [ 0.138 s]
[INFO] OPS4J Pax Logging - Karaf KAR ...................... SUCCESS [ 1.588 s]
[INFO] OPS4J Pax Logging - Karaf Distribution ............. SUCCESS [ 2.114 s]
[INFO] OPS4J Pax Logging - Karaf Integration Tests 1.11.9 . SUCCESS [ 0.163 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 23.440 s
[INFO] Finished at: 2021-12-21T09:51:37Z
[INFO] ------------------------------------------------------------------------

升级log4j的版本编译成功。

解决方案

把新编译的pax-logging-apipax-logging-log4j替换到依赖仓库中,重新编译交付件,验证漏洞解决,日志功能正常。

参考资料

  1. https://github.com/ops4j/org.ops4j.pax.logging
  2. https://github.com/docker-library/openjdk/issues/101
  3. https://blog.csdn.net/yiqiu3812/article/details/103298980