乐趣区

关于docker:记一次部署在docker环境项目发送邮件出现No-appropriate-protocol

前言

部门有个我的项目波及到邮件发送,发送性能在本地测试能够胜利发送,然而打包部署到 docker 环境中,却呈现

No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

前面在网上搜寻了一下,查到了这篇文章

https://stackoverflow.com/questions/67742776/docker-container-error-javax-mail-messagingexception-no-appropriate-protocol

这篇文章有个答主提到,他应用的版本的 jdk 8u292,这个版本曾经禁用了不平安的 TLSv1&TLSv1.1,于是我就查了一下咱们部署的 docker 根底镜像 jdk 版本,为 jdk8u332。前面再搜寻了一下解决方案,大部分的解决方案都是通过 批改 java.security 文件中的 jdk.tls.disabledAlgorithms 配置,删除掉 TLSv1&TLSv1.1 来解决

然而这种计划给我的感觉,有那么点欠妥。毕竟 jdk 禁用 TLSv1&TLSv1.1 应该是通过考量的。所以一开始我就先把这个计划作为其余计划都无奈解决的时候,最终兜底计划。上面就来回顾 一下,我的解决历程

解决历程

计划一:将 mail.smtp.ssl.protocols 配置为 TLSv1.2

但改完后,报了如下异样

The server selected protocol version TLS10 is not accepted by client preferences [TLS12]

因为 server 端反对的 TLSv1.0,因而没招,mail.smtp.ssl.protocols 就不能改为 TLSv1.2

计划二:将 javax.mail 的包换成 com.sun.mail

        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.6.2</version>
        </dependency>

该计划是起源如下博文
https://blog.csdn.net/qq_33601179/article/details/123069499
他通过调整 mail 的 gav 解决,但我通过试验,发现该计划并没解决我的问题,依然会报

No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

计划三:进入 docker 容器外部,批改 java.security 文件中的 jdk.tls.disabledAlgorithms 配置,删除掉 TLSv1&TLSv1.1

网上查了材料,大多数都是通过宿主机去批改 java.security,通过 docker 去批改,基本上没看到。

不过咱们能够通过进入容器 docker 外部,进行批改。但要批改 java.security,首先就得晓得 java.security 文件的地位。不同的根底镜像,java.security 文件的地位可能是不一样的。

那如何晓得 java.security 的具体位置呢? 这边提供一个思路,如果是自制的根底镜像,能够去问公司自制这个镜像的作者,如果是私有的镜像,能够通过 docker hub,比方咱们这个我的项目的镜像是用到 skywalking-java-agent:8.11.0-java8,因而咱们就能够去 docker hub,搜寻该镜像,而后点开详情,外面有的会有 IMAGE LAYERS

由这个就能够晓得 java 的根本门路,而后进入容器外部

咱们就能够通过 vim 命令去批改 java.security 文件内容,不过失常批改的时候,要装下 vim

apt-get update
apt-get install vim

批改完重启一下容器,而后通过拜访 ip: 端口 /actuator/health,前提要引入 actuator

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

并配置

 endpoint:
      health:
        show-details: always

查看 mail 的衰弱状态

或者能够间接发送测试邮件,验证也能够

计划四:调整 Dockerfile

其实计划四的实现逻辑和计划三是一样的,外围也是批改 java.security 文件中的 jdk.tls.disabledAlgorithms 配置,删除掉 TLSv1&TLSv1.1。但计划三有个弊病是,每次发版后,都要从新进入 docker 容器外部批改。计划四的计划是
在 Dcokerfile 文件外面增加如下内容

RUN sed -i 's/jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1/jdk.tls.disabledAlgorithms=SSLv3/g' /opt/java/openjdk/lib/security/java.security

实质就是在构建业务镜像时,同时批改 java.security 内容,最终达到和计划三一样的成果

计划五:升高 jdk 版本

这种计划尽管也能够达到成果,然而不倡议就是,毕竟换了 jdk,可能会导致其余不可预知的问题

总结

这几种计划,因为 1,2 计划达不到目标,所以只能在 3,4,5 这三种计划选,基本上大多数都会抉择计划四。不过尽管是解决问题,然而始终感觉不是最佳计划,最佳计划可能是不改 jdk 内容,通过其余形式改,但临时又没其余思路,如果有更好的计划,大家能够留言告知

退出移动版