20210713 unable to find valid certification path to requested target

之前使用openjdk alpine的镜像一直都正常。由于安全团队要求,必须要修复掉镜像里面的漏洞,索性就自己做了一个jdk8的镜像,然后开发在使用时候就出现这个问题

openjdk dockerhub地址:https://hub.docker.com/_/openjdk

openjdk官方镜像所有tag:https://github.com/docker-library/docs/blob/master/openjdk/README.md#supported-tags-and-respective-dockerfile-links

一、问题描述

出现这个问题根本原因:内网环境的域名证书全部都是自签的,java程序在请求内网域名的时候,没有找到可用的CA。

二、问题排查

那么为什么原来的镜像就是好的,重新做的镜像就有问题?

打包java程序的Dockerfile文件如下:

FROM xxx

COPY ./cert/* /usr/local/share/ca-certificates/
RUN update-ca-certificates

COPY xxx.jar /opt/
...

Dockerfile很简单,就是把CA文件和jar包放入镜像就好了。

openjdk alpine镜像可以自动识别系统级别的证书,但是自己做的镜像不行

通过询问开发和谷歌搜索问题报错,了解到开发人员在遇到此问题后需要通过keytool工具将CA证书导入到%JAVA_HOME%/jre/lib/security/这个目录下。

image-20210713141809734

于是我去观察了下我自己的镜像和openjdk alpine镜像,这个目录下的文件有什么区别:

发现官方的alpine镜像该目录下有个cacert文件是一个软链接,而我自己的没有:

image-20210713143350700
image-20210713144742622

通过google查得,想要通过update-ca-certificates来更新java keystore的话,需要做如下操作:

参考:https://github.com/anapsix/docker-alpine-java/issues/27

参考:https://askubuntu.com/questions/1004745/java-cant-find-cacerts

alpinelinux:

RUN apk add -U java-cacerts && ln -sf /etc/ssl/certs/java/cacerts $JAVA_HOME/jre/lib/security/cacerts

ubuntu:

RUN apt-get install ca-certificates-java -y && ln -sf /etc/ssl/certs/java/cacerts $JAVA_HOME/jre/lib/security/cacerts

然后就好了

三、修改好的dockerfile

FROM buildpack-deps:focal-curl

ARG JDK_FILE="https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz"
ENV JDK_VERSION=jdk1.8
ENV JAVA_HOME=/usr/local/$JDK_VERSION
ENV PATH=$JAVA_HOME/bin:$PATH
ENV LANG=C.UTF-8

RUN curl -O ${JDK_FILE} && \
    tar xf jdk-*-linux-x64.tar.gz -C /usr/local/ && \
    mv /usr/local/jdk* /usr/local/jdk1.8 && \
    rm -f jdk-*-linux-x64.tar.gz && \
    ln -sf  /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    apt update && \
    apt upgrade -y && \
    apt install ca-certificates-java -y && \
    update-ca-certificates && \
    ln -sf /etc/ssl/certs/java/cacerts $JAVA_HOME/jre/lib/security/cacerts

#update CA
#COPY ./CA/*.crt /usr/local/share/ca-certificates/
#RUN update-ca-certificates

四、关于openjdk官网镜像tag号

参考:https://medium.com/swlh/alpine-slim-stretch-buster-jessie-bullseye-bookworm-what-are-the-differences-in-docker-62171ed4531d

dockerhub地址:https://hub.docker.com/_/openjdk
Openjdk docker 镜像所有tag地址:https://github.com/docker-library/docs/blob/master/openjdk/README.md#supported-tags-and-respective-dockerfile-links

比如17-ea-29-jdk-buster:

  • 17是openjdk的版本,从openjdk的官网我看到,openjdk的版本很多:6,7,8,9,10,11,12,13,14,15,16,17,18
  • ea表示:easy access,抢先体验版,这肯定不能生产环境使用的
  • 最后的buster是表示基于debian10构建的,同理,stretch是debian 9,jessie是debian 8,alpine是alpinelinux
  • slim:slim翻译过来是瘦小的意思,这个镜像是基于debian-slim镜像制作的,debian-slim相比标准的debian镜像少了一些非必要的组件,可以参考:https://stackoverflow.com/questions/59794891/how-does-debian-differ-from-debian-slim

另外,关于jdk的奇数版本和偶数版本似乎官网也有说明,奇数版本的jdk可以生产环境直接使用,偶数版本包含了一些新特性,需要自行折腾然后再拿来使用