共计 2357 个字符,预计需要花费 6 分钟才能阅读完成。
前言
部门有个我的项目波及到邮件发送,发送性能在本地测试能够胜利发送,然而打包部署到 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 内容,通过其余形式改,但临时又没其余思路,如果有更好的计划,大家能够留言告知