前言
部門有個專案涉及到郵件傳送,傳送功能在本地測試可以成功傳送,但是打包部署到docker環境中,卻出現
No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
後面在網上搜尋了一下,查到了這篇文章
這篇文章有個答主提到,他使用的版本的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內容,透過其他方式改,但暫時又沒其他思路,如果有更好的方案,大家可以留言告知