系統維護之案發現場 — SMTP Exception

KAIYUAN LIU
appxtech
Published in
7 min readJan 16, 2023

SMTP / MailKit 疑難雜症

故事是這樣樣開始的,某一天收到客戶通知,提到系統原本寄信的功能似乎沒有運作,所以要請我們協助了解。

系統功能說明 :

此系統是客戶的內部管理系統,其中有一個功能整讓會員進行繳費,完成繳費動作後,系統會自動發信給內部以及會員。這功能我們是使用C# 搭配 MailKit,並且透過 Gmail STMP 來寄信。

系統維護背景說明 :

由於此系統已上線超過二年,功能已穩定,近期內程式碼部份 並無更新 ~
所以第一時間的想法會是 infra / 網路環境的改變 導至系統無法寄信
但是跟 IT/infra 人員確認後,發現 SMTP Server的部份 並沒看到任何log
而Application的log 也沒有發現任何錯誤訊息 ~~~ (*之前有出現過SMTP相關的錯誤訊息 如 SMTP timeout 等)

附上 修改之前的示意程式碼

原先正常運作的版本

圖裏的 mailServer, mailPort, sender, SenderPwd 都沒動過 (都是正確的值)

案發現場 / Crime Scene

同事開始debug後… 一步步執行,都沒有發生 Error Message, 當然也就沒有任何的 Error Log … 情況一度膠著…

我們也在Linux上,試著找 SMTP service(sendmail) log… 一樣也沒有看到特別的提示或是錯誤訊息

後來,就想一步步用硬底子的方式來測試,看到底是哪一段程式/系統出錯 ~第一個遇到的就是…要如何模擬 SMTP client 寄信 (而不寫程式)…找了很久有看到一個工具 名為 Swaks ,這工具就真的很像萬用瑞士刀(有很多功能),其中一個功能可以讓我們可以用命令列的指令來 測試SMTP連線,發送信件,就像使用 Telnet/Ssh 指令的方式。如下圖

類似下面的指令,來測試寄信SMTP主機 ~

$ echo "Hello world" | swaks -4 --server smtp.gmail.com:587 --from user@gmail.com --to user@example.net -tls --tls-protocol sslv3 --auth PLAIN --auth-user user@gmail.com --auth-password 7654321 --h-Subject "Test message" --body -

竟然發現 下面的訊息,certification error !!! 這給了我們一線希望 ~~~~
(*這部份,不好意思… 之前忘了截圖…現在一時間找不到錯誤訊息的文字
只好用正確版的結果 來補充~~~ (*節錄 重點部份,方便參考)

$ echo "Hello world" | swaks -4 --server smtp.gmail.com:587 --from user@gmail.com --to user@example.net -tls --tls-protocol sslv3 --auth PLAIN --auth-user user@gmail.com --auth-password 7654321 --h-Subject "Test message" --body -
=== Trying smtp.gmail.com:587...
=== Connected to smtp.gmail.com.
<- 220 smtp.gmail.com ESMTP h8sm76342lbd.48 - gsmtp
-> EHLO www.example.net
<- 250-smtp.gmail.com at your service, [193.243.156.26]
<- 250-SIZE 35882577
<- 250-8BITMIME
<- 250-STARTTLS
<- 250-ENHANCEDSTATUSCODES
<- 250-PIPELINING
<- 250-CHUNKING
<- 250 SMTPUTF8
-> STARTTLS
<- 220 2.0.0 Ready to start TLS
=== TLS started with cipher SSLv3:RC4-SHA:128
=== TLS no local certificate set
=== TLS peer DN="/C=US/ST=California/L=Mountain View/O=Google Inc/CN=smtp.gmail.com"
~> EHLO www.example.net
<~ 250-smtp.gmail.com at your service, [193.243.156.26]
<~ 250-SIZE 35882577
<~ 250-8BITMIME
<~ 250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
<~ 250-ENHANCEDSTATUSCODES

接著又做了些測試,確認客戶主機的憑證沒問題後,
剩下就是在程式中看如何能避開這樣的情形…
在Mailkit文件裏,找到 SMTPClient 的屬性說明
它有一個屬性 CheckCertificateRevocation,如下圖

在參考了許多文章,以及反覆測試了許多的範例,果然 !!!
下面的寫法,就可以解決我們目前遇到的問題 ~~~~ YEAH~~~~

原由

問題解決之後,不禁停下來思考…過去二年 都運作的好好的,到底是為什麼會發生這樣的情形 ??!!

後來有個SRE的朋友建議我們看一下 OS update的設定值
在GCP裏 Centos VM,它會有個 系統自動更新設定,可參考下圖

Waola ~~~~ 問題解決 !!! 準時下班 ~~~ (*雖然已過1800 XD)
我們下次案發現場見 ~

參考資料

--

--