一次郵件發送協議SMTP問題排查


項目中需要用到smtp協議來發送郵件告警,后端的技術棧主要是Java和C++,Java項目里直接在網上找的現成的類完美實現,163郵箱,騰訊郵箱和阿里郵箱均測試通過,不幸的是C++的項目也需要使用smtp協議來發送郵件,慣例先度娘,CSDN逛了一圈,例程也不少但是每個下邊留言都有這樣和那樣的問題,copy過來直接運行,163郵箱完美測試通過,我們用的釘釘全家桶,測試釘釘郵箱時發現不能發送郵件,認證都有問題。好吧,還是先老老實實的學習遍SMTP協議吧

 

WireShark抓取一次完整的郵件交互過程(關閉ssl):

流程如下:

第一步:發送EHLO指令,申明身份,表示自己身份需要驗證,注意這部分需要通過Telnet驗證一下,是user@example.com還是user,否則會出錯。

第二步:發送AUTH LOGIN指令,登錄郵箱,這一部分一般要用base64加密。

第三步:發送MAIL指令,這個命令用來開始傳送郵件,它的后面跟隨發件方郵件地址(返回郵件地址)。它也用來當郵件無法送達時,發送失敗通知。為保證郵件的成功發送,發件方的地址應是被對方或中間轉發方同意接受的。這個命令會清空有關的緩沖區,為新的郵件做准備。

第四步:發送RCPT指令,這個命令告訴收件方收件人的郵箱。當有多個收件人時,需要多次使用該命令RCPT TO,每次只能指明一個人。如果接收方服務器不同意轉發這個地址的郵件,它必須報550錯誤代碼通知發件方。如果服務器同意轉發,它要更改郵件發送路徑,把最開始的目的地(該服務器)換成下一個服務器。

第五步:發送DATA指令,收件方把該命令之后的數據作為發送的數據。數據被加入數據緩沖區中,以單獨一行是”.”的行結束數據。結束行對於接收方同時意味立即開始緩沖區內的數據傳送,傳送結束后清空緩沖區。如果傳送接受,接收方回復OK。

第六步:發送QUIT指令,SMTP要求接收放必須回答OK,然后中斷傳輸;在收到這個命令並回答OK前,收件方不得中斷連接,即使傳輸出現錯誤。發件方在發出這個命令並收到OK答復前,也不得中斷連接。

 

分析:

掌握了基本的流程和抓取了數據包,只要C++也按照這種數據格式發送即可,認證不通過,首先懷疑用戶名和密碼傳輸的數據有問題,抓取C++發送的數據包,果然User數據BASE64的值不一樣,Pass的值是一樣的,解Base64后發現一個是user@example.com,一個是user,顯然問題出在這,163郵箱要求是user,釘釘郵箱要求是user@example.com,改正后認證成功,接着發送郵件也OK,完事大吉,然而。。。一周后項目完成交給測試人員,告訴我告警郵件發不過來,怎么可能,運行工程,打臉了,只能發送一次,接着就發不出去郵件了,難道釘釘給屏蔽了,Java測試了下,沒問題,好吧,繼續抓包,認證是沒問題的,發送過去就是收不到。

 

Java發送抓取的DATA數據部分如下:

C++發送抓取的DATA數據部分如下:

很明顯差別太大了,From,To的格式不對,Content-Type也不對,但是明顯差別的是少了Message-ID字段,所以重點先分析Message-ID,又抓取了多次比對后每次的Message-ID都是不同的,懷疑這給C++只能發送一次成功有關系,C++中增加了如下代碼:

    email = "From: ";
    email += user;
    email += "\r\n";

    email += "To: ";
    email += targetAddr;
    email += "\r\n";

    //新增
    email += "Message-ID: ";
    email += “1”;
    email += "\r\n";

    email += "Subject: ";
    email += title;
    email += "\r\n";

    email += "MIME-Version: 1.0";
    email += "\r\n";

    email += "Content-Type: multipart/mixed;boundary=qwertyuiop";
    email += "\r\n";
    email += "\r\n";

運行果然成功了,但是在運行又不成功了,把Message-ID值改為2又成功了,問題果然出在這里,大功告成,最終Message-ID改為:機器名+隨機數。

總結:

        WireShark是個很好的工具,善於使用它分析網絡傳輸協議,抓包能夠說明一切,讓問題一目了然。

Java架構師之路,一個匯聚十萬技術人的圈子,讓學習之路更有趣!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM