郵箱基礎協議:SMTP/POP3/IMAP
目錄
- 電子郵件的組成:信封、首部和正文
- 郵件基礎協議
- SMTP
- SMTP 指令
- 使用 Telnet 模擬 SMTP 傳送郵件
- POP3
- POP3 的生命週期
- IMAP
- 標誌訊息屬性
- 狀態和流程圖
- IMAP 命令
- SMTP
電子郵件的組成:信封、首部和正文
電子郵件由三部分組成,下圖是 Client 傳送的整個資料:
信封(envelope)
信封是 MTA 用來交付的,在上例中由兩個 SMTP 命令指明;
MAIL From: [email protected]
RCPT To: [email protected]首部(header)
首部由使用者代理使用,上例中可以看到 9 個首部欄位:Recived、Message-Id、From、Date、Reply-To、X-Phone、X-Mailer、To 和 Subject
(以 X- 開頭的是使用者定義的欄位,其他是由 RFC 822 定義的,詳見 4.1 節)正文(body)
正文是傳送使用者發給接收使用者報文的內容,RFC 822 指定正文為 NVT ASCII 文字行,用 DATA 命令傳送的各行都必須小於 1000 位元組
使用者接收我們指定為正文的部分,加上一些首部欄位,並把結果傳到 MTA;MTA 加上一些首部欄位,加上信封,並把結果傳送到另一個 MTA
(更多實現細節,詳見 RFC 2821)
用 TCP 進行的郵件交換是由報文傳送代理 MTA(Message Transfer Agent)完成的。
TCP/IP 交換電子郵件示意圖:
郵件基礎協議
郵件基礎的網路協議有以下三個,一般我們使用 SMTP 協議來發送郵件,POP3 和 IMAP 協議來接收郵件(從服務端接收郵件至客戶端)
- 下表中 IMAP 協議支援傳送郵件並不是郵件投遞,而是通過 append 指令將郵件從客戶端上傳到服務端
協議 | 工作埠(括號內為 SSL) | 支援傳送郵件 | 支援接收郵件 |
---|---|---|---|
SMTP | 25(465) | True | False |
POP3 | 110(995) | False | True |
IMAP | 143(993) | True | True |
SMTP
兩個 MTA 之間通過 NVT ASCII 進行通訊,客戶向伺服器發出命令,伺服器用數字應答碼和可選的人可讀字串進行響應
下圖是 SMTP 的一個互動會話過程:
- 鍵入 mail -v 啟動使用者代理; 鍵入 subject(主題)和正文
- 主動開啟 port:25 ;等待從 Server 返回的問候報文(應答碼220)
- HELO:標識自己(引數必須是合格的主機名)
- MAIL:標識報文發起人
- RCPT:標識接收方(可發多次,標識多個接收方)
- DATA:郵件報文內容
- QUIT:結束郵件交換
下圖是傳送方 SMTP(Client)和接收方 SMTP(Server)之間的一個 SMTP 連線:
SMTP 指令
最小SMTP支援 8 個命令,除了上述 5 個命令還有:
- RSET:異常中止當前的郵件事務並使兩端復位。丟掉所有有關傳送方、接收方或郵件的儲存資訊
- VRFY:使客戶詢問傳送方以驗證接收方地址,而無需向傳送方傳送郵件(通常用與管理員查詢郵件交付差錯中使用)
- NOOP:強迫伺服器響應一個OK應答碼(200)
(另外還有一些附加可選命令)
SMTP 用半雙工的形式使用 TCP,客戶傳送一個命令後停止等待應答;實際上 Client 可以一次發多個命令,稱為流水線技術(pipelining)
如果使用了這種技術,Client 則不能丟棄報文直到所有的應答都已檢查過,確認報文被伺服器接收了
使用 Telnet 模擬 SMTP 傳送郵件
POP3
POP3 協議相對 SMTP/IMAP 要簡單一些,協議的指令也不多
POP3 的生命週期
POP3 命令以 CRLF 對結束,特定命令多行響應,以 CRLF.CRLF 結束
在伺服器開啟郵件後,它為每個訊息指定一個訊息號,並以八進位制表示每個訊息的長度。第一個訊息被指定為 1,第二個訊息被指定為 2,以此類推,第 N 個訊息被指定為 N
在POP3命令和響應中,所以的訊息號和長度以十進位制表示
AUTHORIZATION
- USER :客戶確認身份(引數:username)
- PASS :身份確認完成
- QUIT :終止 POP3 會話
- APOP :用於替代 USER 和 PASS 命令,它以 MD5 數字摘要的形式向POP3郵件伺服器提交帳戶密碼(引數:使用者名稱/金鑰)(該命令實現可選)
安全性:每個 POP3 會話都以 USER/PASS 互換開始,導致了使用者名稱和口令在網路上的顯式傳送,當服務連線頻率變大、時間間隔小,就會加大了洩密的可能
(使用APOP:隨著金鑰長度的增加,解讀的難度也會上升)
TRANSACTION
操作狀態下的命令:
- STAT :查詢郵箱中的統計資訊(郵件數量和所有郵件大小)
- LIST :列出郵箱中的所有郵件資訊(訊息號/大小)(引數:MSG 列出對應訊息號的郵件資訊)
- RETR :獲取某封郵件的內容(引數:MSG)
- DELE :將某封郵件標記為刪除(引數:MSG)(被標記的郵件直到當前會話進入 UPDATE 狀態才被刪除)
- NOOP :檢測連線狀況
- RSET :取消刪除標記
UPDATE
當客戶在 AUTHORIZATION 狀態下發送 QUIT 命令後,會話進入 UPDATE 狀態
如果會話因為 QUIT 命令以外的原因中斷,會話並不進入 UPDATE 狀態,也不從伺服器中刪除任何信件
(更多實現細節,詳見 RFC 1939)
IMAP
IMAP 協議通過 port:143 來提供電子郵件的收發服務,和 POP3 被用來提供電子郵件客戶端服務(從伺服器檢索電子郵件)
相對於 POP3,IMAP 支援多個電子郵件客戶端同時管理郵箱,並可以通過郵件的標籤/狀態,監測到其他使用者對於郵件的操作
IMAP 還支援線上/離線兩種操作模式,客戶端可以獲得郵件副本儲存在本地
標誌訊息屬性
與郵件關聯的有一個或多個 token list,將 flag 新增至列表可以設定郵件的屬性,每個 flag 可以設定為永久的或臨時的(當前會話)
\Seen | 郵件已閱讀 |
\Answered | 郵件已回覆 |
\Flagged | 郵件被標記為緊急/特別關注 |
\Delete | 郵件被標記刪除(to EXPUNGE) |
\Draft | 郵件被標記為草稿 |
\Recent | 郵件最近到達該郵箱(本次會話是首次收到當前郵件通知) |
具體的實現與伺服器相關
狀態和流程圖
Client 和 Server 建立好連線後,IMAP 連線處於四種狀態之一
最初的狀態在伺服器的 greeting 報文中標識,客戶端在不當狀態中嘗試的命令伺服器都將以 BAD/NO 響應(取決於實現)
- Not Authenticated State :未經認證的狀態,連線啟動時進入該狀態,除非已進行預驗證
- Authenticated State:認證狀態,可選擇郵箱進行訪問
- Selected State:選定狀態,已選擇一個郵箱訪問
- Logout State:退出狀態,連線正在終止(LOGOUT 命令)
伺服器必須傳送 BYE 響應來關閉連線,同樣的,客戶端應該傳送 LOGOUT 命令來關閉連線
如果伺服器檢測到客戶端單方面關閉了連線,則可以省略 BYE 響應
IMAP 命令
下面羅列一些常見的 IMAP 命令
客戶端命令 —— 任何狀態
- CAPABILITY:查詢伺服器實現的功能
- NOOP:檢測連線
- LOGOUT:終止當前連線
客戶端命令 —— 未經認證的狀態
- STARTTLS:與伺服器使用 TLS 進行互動
- AUTHENTICATE:與伺服器的認證機制
- LOGIN:鑑權登陸,輸入使用者名稱與密碼
客戶端命令 —— 認證狀態
- SELECT:選擇郵箱
- EXAMINE:以只讀方式選擇郵箱
- CREATE:建立一個郵箱
- DELETE:刪除一個郵箱
- RENAME:重新命名郵箱
- SUBSCRIBE:訂閱指定郵箱
- UNSUBSCRIBE:取消訂閱郵箱
- LSUB:返回訂閱郵箱列表
- APPEND:追加一個State,例如可以儲存一封新的郵件
客戶端命令 —— 選定狀態
- CHECK:檢查當前伺服器狀態(例如:磁碟,記憶體等)
- CLOSE:永久刪除所有訊息
- EXPUNGE:永久刪除所有訊息,與 CLOSE 不同的是,將返回每個訊息標識
- SEARCH:類似 find 命令,功能很強大可以按照不同條件搜尋郵件
- FETCH:檢索與訊息相關資料,例如:獲取正文
- STORE:改變與訊息相關資料,例如:設定郵箱已讀、刪除狀態等
- COPY:拷貝指定的訊息
- UID:返回 UID 列表用於 FETCH