SMTP

Posted by Adam on August 24, 2022
在 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`。 ---