The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何正確設定 SMTP 服務的日誌記錄與挑選適當的欄位

即便到了 Windows Server 2008 R2 微軟的 SMTP 服務還是執行在 IIS 6.0 之上,看起來作業系統這幾代的演進完全沒有撼動到 SMTP 服務的地位,我能說 SMTP 服務的確屬於 麻雀雖小、五臟俱全 的等級,一直以來我都期盼 SMTP 服務能有些改進,不過還是盼望不到,像是 SMTP 服務的紀錄就是其中一點,由於 W3C 擴充記錄檔格式 並不適用於 SMTP 通訊協定,而且完全沒有文件說明怎樣閱讀 SMTP 服務產生的紀錄(Log),最後也只好苦命一點自行研究摟!

一般來說 IIS 6.0 裡面預設的 SMTP 虛擬伺服器被建立的時候是沒有啟動日誌記錄的,如果你直接將日誌記錄勾選起來的話,也只會看到以下預設的紀錄欄位:

這些預設的紀錄幾乎對系統管理與維護來說沒什麼幫助,當我們要自行勾選記錄的欄位時,又會發現這些日誌紀錄的欄位看起來似乎是針對網站的站台所設計的 (如下圖示),無法直觀的看出到底這些欄位到底代表著什麼樣的紀錄,也因此必須多下一些功夫才能得知。 ( 註:要看懂這些記錄你必須先瞭解 SMTP 通訊協定的細節,這部分不在本文探討的範圍,有興趣的人可參考 RFC 821 文件 )

如果我們今天管理的是 SMTP 虛擬伺服器的話,我從微軟的官方文件找不太到各欄位的說明,所以自己整理了一下每個欄位所對應的資料,首先我整理出所有能勾選的欄位如下圖示,其他沒勾選的原因是這些欄位永遠不會有資料,所以勾選了也沒意義。

當這些欄位都勾選了之後,其記錄檔會變的非常詳細,如下圖示:

 

在說明各欄位的用途與格式細節之前必須先說明的是:這裡所記錄的資訊會包含兩台 SMTP 端點之間完整的 SMTP 通訊協定對話的內容 (除了郵件內容之外),所以每發出一封信或是每收到一封信,都會產生出多筆紀錄

以下是各欄位的詳細說明,千萬不要問我為什麼微軟要這樣記錄資訊,有些欄位的設計我也覺得挺納悶的,反正他資料就是這樣儲存,我們只要看懂這些記錄並顧好分析的工作即可:


日期 ( date )

  • 郵件收到或發出的時間點
  • 這裡記錄的時間點是透過 SMTP 傳遞訊息時所下達指令或接收訊息的時間點。

時間 ( time )

  • 郵件收到或發出的時間點
  • 這裡記錄的時間點是透過 SMTP 傳遞訊息時所下達指令或接收訊息的時間點。

用戶端 IP 位址 ( c-ip )

  • 這個欄位所記錄的是 SMTP 傳遞訊息的 非本地端的 IP 位址
  • 當別台伺服器或應用程式發信到這台伺服器時,該 IP 為 發信端 IP 地址
  • 當這台伺服器發信到遠端 SMTP 伺服器時 (Relay),該 IP 為 收信端 IP 地址

使用者名稱 ( cs-username )

  • 當別台伺服器或應用程式發信到這台伺服器時,該欄位固定為來源 IP 的網域名稱
  • 當這台伺服器發信到遠端 SMTP 伺服器時,此欄位固定為以下兩種名稱:
    • 當伺服器收到指令或訊息時為 OutboundConnectionResponse
    • 當伺服器發出指令到遠端時為 OutboundConnectionCommand

服務名稱 ( s-sitename )

  • 這個欄位所記錄的是在記錄檔所在的目錄名稱,而非你自己自訂的虛擬伺服器名稱:

伺服器名稱 ( s-computername )

  • 此欄位記錄的是本機電腦的名稱

伺服器 IP 位址 ( s-ip )

  • 當別台伺服器或應用程式發信到這台伺服器時,該 IP 為「本機 LISTEN 的 IP 地址」
  • 當這台伺服器發信到遠端 SMTP 伺服器時,此欄位不會有資料,並會以一個減號 ( – ) 替代

伺服器連接埠 ( s-port )

  • 當別台伺服器或應用程式發信到這台伺服器時,該欄位固定為 0
  • 當這台伺服器發信到遠端 SMTP 伺服器時,該欄位為連接到遠端的埠號 ( 通常是 25 Port )

方法 ( cs-method )

  • 當別台伺服器或應用程式發信到這台伺服器時,該欄位為 Client 端下達的指令
    • 例如: EHLO, MAIL FROM, RCPT TO, DATA, QUIT 等等
    • 注意:由於 IIS 會無法辨識這些指令的空白字元,所以只會紀錄到第一個字而已,所以當紀錄指令的過程如果該指令包含空白的話,在 IIS 記錄裡只會記錄到第一個字,也就是 MAIL FROM 只會記錄 MAIL、而 RCPT TO 只會紀錄到 RCPT 而已,遺漏掉的 FROM 與 TO 會被歸類在下一個欄位裡,所以在使用 LogParser 的時候要注意一下!
  • 當這台伺服器發信到遠端 SMTP 伺服器時,此欄的資料如下:
    • 當伺服器收到指令或訊息時,也就是 cs-username 為 OutboundConnectionResponse 時:
      • 此欄位不會有資料,並會以一個減號 ( – ) 替代
    • 當伺服器發出指令到遠端時,也就是 cs-username 為 OutboundConnectionCommand 時
      • 此欄位會記錄指令名稱,例如 EHLO, MAIL FROM, RCPT TO, DATA, QUIT 等等
      • 注意事項同上紅字部分。

URI 查詢 ( cs-uri-query )

  • 當別台伺服器或應用程式發信到這台伺服器時
    • 該欄位為 Client 端下達的指令的剩餘部分,也就是說這一行的完整指令裡,第一個空白之前會被紀錄到 cs-method 欄位去,而第一個空白之後會被紀錄到 cs-uri-query 欄位去,而且該欄位的內容會被 URLEncode 過
  • 當這台伺服器發信到遠端 SMTP 伺服器時,此欄的資料如下:
    • 當伺服器收到指令或訊息時,也就是 cs-username 為 OutboundConnectionResponse 時:
      • 此欄位會是從遠端 SMTP 回應的完整內容
    • 當伺服器發出指令到遠端時,也就是 cs-username 為 OutboundConnectionCommand 時
      • 該欄位為從我方對遠端 SMTP 下達指令的剩餘部分,也就是說這一行的完整指令裡,第一個空白之前會被紀錄到 cs-method 欄位去,而第一個空白之後會被紀錄到 cs-uri-query 欄位去,而且該欄位的內容會被 URLEncode 過
      • 也因此:
        • 如果 cs-method 為 EHLO,其 cs-uri-query 就會是用戶端宣告的 hostname
        • 如果 cs-method 為 MAIL,其 cs-uri-query 就會是 FROM: 加上寄件者地址
        • 如果 cs-method 為 RCPT,其 cs-uri-query 就會是 TO: 加上 收件者地址
        • 其他如果沒有資料的話,會以一個減號 ( – ) 替代

通訊協定狀態 ( sc-status )

  • 當別台伺服器或應用程式發信到這台伺服器時
    • 該欄位為這壹台 SMTP 伺服器所回應的狀態,若為 250 就代表正常
    • 詳細的 SMTP Relay Codes 請參考 RFC 8214.2. SMTP REPLIES
  • 當這台伺服器發信到遠端 SMTP 伺服器時
    • 該欄位永遠為 0

Win32 狀態 ( sc-win32-status )

  • 我其實猜不太到這個欄位的用途,但是的確有時後會有資料,如果有人知道麻煩通知我一下。

已傳送位元組 ( sc-bytes )

  • 當別台伺服器或應用程式發信到這台伺服器時
    • 該欄位為所發出指令的 bytes 數
  • 當這台伺服器發信到遠端 SMTP 伺服器時
    • 當伺服器收到指令或訊息時,也就是 cs-username 為 OutboundConnectionResponse 時:
      • 此欄位為遠端 SMTP 伺服器回應訊息的 bytes 數
    • 當伺服器發出指令到遠端時,也就是 cs-username 為 OutboundConnectionCommand 時
      • 此欄位為我方發出的指令的 bytes 數

已接收位元組 ( cs-bytes )

  • 當別台伺服器或應用程式發信到這台伺服器時
    • 該欄位為 SMTP Client 所送出的所有 bytes 數
  • 當這台伺服器發信到遠端 SMTP 伺服器時
    • 該欄位永遠為 0

花費時間 ( time-taken )

  • 完成這個 SMTP 指令所花費的時間

通訊協定版本 ( cs-version )

  • 此欄位的內容永遠為 SMTP,這個還不知道等幾年才會改過,此欄位可選擇不紀錄。
  • 附帶一提:RFC 821 是西元 1982 年 8 月制訂的,距離今天已經有 29 年了耶!

 

以下是一個 LogParser 語法供參考,其 WHERE 條件的地方你可以任意修改篩選出你想要的資料:

"C:\Program Files (x86)\Log Parser 2.2\logparser.exe" "SELECT date,time,c-ip,cs-username,s-sitename,s-computername,s-ip,s-port,cs-method,cs-uri-stem,cs-uri-query,sc-status,sc-win32-status,sc-bytes,cs-bytes,time-taken,cs-version FROM C:\Windows\System32\LogFiles\SMTPSVC1\ex*.log WHERE cs-username='OutboundConnectionResponse' and cs-uri-query not like '250%'" -o:DataGrid

 

相關連結