v0.1.0

SMTP 連線

本頁說明 SMTP.SendEmail() 依 port 選擇連線方式、認證條件,以及實際送出的信件格式。

前置檢查

SendEmail()(internal/service/smtp.go:28)在連線前依序檢查,任一失敗即回傳錯誤:

檢查 錯誤訊息
enabled 為 true 且 host 非空 SMTP not Enabled or Host is not set
to 至少一個收件者 no user email configured
host:port 在 5 秒內可建立 TCP 連線 failed to connect TCP (...)

連線方式

graph TB
    Probe[TCP 探測 5 秒] --> Plain[smtp.Dial 明文連線]
    Plain -->|成功| Port587{port = 587?}
    Plain -->|失敗且 port = 465| Implicit[tls.Dial 隱式 TLS]
    Plain -->|失敗且其他 port| Fail[回傳錯誤]
    Port587 -->|是且伺服器支援| StartTLS[STARTTLS 升級]
    Port587 -->|否| Auth
    StartTLS --> Auth{username 與 password 皆非空?}
    Implicit --> Auth
    Auth -->|是| Login[PLAIN 認證]
    Auth -->|否| Send
    Login --> Send[MAIL FROM / RCPT TO / DATA]
port 實際行為
465 先嘗試明文 SMTP;隱式 TLS 伺服器不會送出明文問候,明文嘗試要等伺服器關閉連線才失敗,之後才改以 tls.Dial 建立隱式 TLS 連線,因此寄信可能延遲
587 明文連線後,若伺服器宣告 STARTTLS 擴充則升級為 TLS;不支援時以明文繼續
其他(如 25) 只用明文連線,不升級 TLS

TLS 一律以 host 作為 ServerName 驗證伺服器憑證。

認證

username 與 password 都非空時才執行 smtp.PlainAuth;任一為空則略過認證,適用於內網免認證的轉信伺服器。Go 標準庫的 PLAIN 認證只允許在 TLS 連線或 localhost 上送出,因此在 25 等未加密 port 上設定帳密會認證失敗。

信件格式

標頭 值
From config.from
To config.to 以逗號串接
Cc config.cc;空值時填 config.from
Subject 告警或測試信主旨
Content-Type text/html; charset=UTF-8

RCPT TO 只對 to 清單中的地址送出,Cc 只寫在標頭,見 已知限制。

EN