在 Java / Tomcat 環境中,SMTP 通常是透過 **JavaMail (Jakarta Mail)** 來發送郵件。要指定 Tomcat 中的應用程式使用 TLS 1.2,主要有兩種設定方式:**修改全域 JVM 參數**,或在 **Tomcat 的 `context.xml` 設定 JNDI Mail Resource**。
---
## 📌 核心知識
1. **SMTP 的加密方式**:
* **STARTTLS (通常為 Port 587)**:先建立明文連線,再透過 `STARTTLS` 指令升級為 TLS 加密。
* **Implicit TLS/SSL (通常為 Port 465)**:連線建立時即直接進行 TLS 握手與加密。
2. **JavaMail 的控制機制**:
JavaMail 預設會與伺服器協商支援的最高 TLS 版本。若要強制指定 TLS 1.2,必須透過 JavaMail 屬性 `mail.smtp.ssl.protocols` 設定。
---
## 🔸 設定方式
### 方法一:透過 Tomcat JNDI Resource 設定(推薦)
若你的應用程式是在 Tomcat 的 `conf/context.xml` 或 `META-INF/context.xml` 中設定 JNDI 郵件資源,可以直接在屬性中加上 TLS 1.2 的限制。
```xml
<Resource name="mail/Session"
auth="Container"
type="javax.mail.Session"
mail.smtp.host="smtp.your-server.com"
mail.smtp.port="587"
mail.smtp.auth="true"
mail.smtp.starttls.enable="true"
mail.smtp.ssl.protocols="TLSv1.2" />
```
> **說明**:
> * 針對 Port 587 (STARTTLS):設定 `mail.smtp.starttls.enable="true"` 與 `mail.smtp.ssl.protocols="TLSv1.2"`。
> * 針對 Port 465 (SSL/TLS):設定 `mail.smtp.ssl.enable="true"` 與 `mail.smtp.ssl.protocols="TLSv1.2"`。
>
>
---
### 方法二:修改 Tomcat 的 JVM 啟動參數(全域生效)
若想讓整個 Tomcat 內執行的 Java 應用程式預設都使用 TLS 1.2 連線,可以在啟動腳本中加入 JVM 參數。
* **Linux (`bin/setenv.sh`)**:
```bash
CATALINA_OPTS="$CATALINA_OPTS -Dmail.smtp.ssl.protocols=TLSv1.2 -Dhttps.protocols=TLSv1.2"
```
* **Windows (`bin/setenv.bat`)**:
```cmd
set "CATALINA_OPTS=%CATALINA_OPTS% -Dmail.smtp.ssl.protocols=TLSv1.2 -Dhttps.protocols=TLSv1.2"
```
---
## 📝 範例說明 (Java 程式碼片段)
如果你的應用程式是在程式碼中自行建立 `Properties` 並取得 Mail Session,設定範例如下:
```java
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.your-server.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
// 啟用 STARTTLS 加密
props.put("mail.smtp.starttls.enable", "true");
// 強制指定使用 TLS 1.2 協定
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password");
}
});
```
## 📌 核心知識
在進行 SMTP 測試時,主要使用的 Port 如下:
* **Port 25**:傳統 SMTP 連線(許多公有雲/ISP 會封鎖)。
* **Port 587**:傳送郵件主要使用的 Port,支援 **STARTTLS** 升級加密。
* **Port 465**:使用 **Implicit TLS/SSL** 的加密連線。
---
## 🔸 常用驗測工具與指令
### 使用 `openssl s_client`(最推薦,可測試 TLS 1.2 加密)
這是最精準的測試方式,可以直接指定使用 **TLS 1.2** 並檢查證書與加密回應。
#### 測試 Port 587 (STARTTLS + TLS 1.2)
```bash
openssl s_client -starttls smtp -connect smtp.your-server.com:587 -tls1_2
```
* **預期結果**:應看到 SSL 握手成功訊息(`CONNECTED`)、伺服器憑證鏈,最後停在 SMTP 狀態碼 `250`。
#### 測試 Port 465 (Implicit TLS + TLS 1.2)
```bash
openssl s_client -connect smtp.your-server.com:465 -tls1_2
```
* **預期結果**:建立連線後直接完成 TLS 握手,並顯示 `220 ... Service ready`。
---