- Book mode https://hackmd.io/@ncnu-opensource/book [TOC] # 電子郵件 ![image](https://hackmd.io/_uploads/B1vfT3pNke.png) ## 歷史發展 ### ARPANET 與首封電子郵件 (1970 年代) Ray Tomlinson 被譽為**電子郵件之父**,他在 1971 年首次實現跨電腦的電子郵件傳遞,也是首次使用 `user@host` 這樣的位址格式 :::info `@` 是指英文中 at 這個字的意思,意即某個使用者帳號在某個主機上 ::: ### 電子郵件標準化 (1980 年代) SMTP (Simple Mail Transfer Protocol) 在 1982 年誕生,由 RFC 821 定義,至今仍是電子郵件傳輸的核心協定,目前已修訂到 RFC 5321 POP (Post Office Protocol) 跟 IMAP (Internet Message Access Protocol) 相繼在 1984 以及 1986 年提出,主要用於電子郵件的接收和存取 而在 1992 年又提出了 MIME (Multipurpose Internet Mail Extensions) 讓電子郵件能夠支援純文字以外的內容,像是圖片、影片或附件 ### 現代電子郵件 (1990 年代至今) 1996 年,Hotmail 推出首個免費的**基於網頁**的電子郵件服務,Yahoo 和 Google 也相繼推出。目前電子郵件已成為全球最常用的通訊工具之一,根據 Radicati 的年度電子郵件統計報告,2021 年電子郵件的使用者已達 41 億人,且全球共發送了 3196 億封電子郵件 :::info 影片分享: [為什麼聰明人都用電子郵件 ?](https://www.youtube.com/live/5kXkcR6TKhc) ::: ## 系統組成 一個郵件伺服器由多個元件所組成。**MTA (Mail Transfer Agent)** 透過 **SMTP** 接收和傳送郵件。接收到並接受的郵件隨後會傳遞給 **MDA (Mail Delivery Agent)**,由 MDA 將郵件儲存在信箱中 (通常使用 mbox 或 Maildir 格式)。如果希望使用者可以透過 **MUA (Mail User Agent)** 遠端存取郵件,就需要 **POP3** 或 **IMAP** 伺服器 ### MUA (Mail User Agent, 郵件使用者代理) - 俗稱的電子郵件客戶端或 mail client - 使用 SMTP 傳送信件給 SMTP server - 使用 POP3 或是 IMAP 接收及管理信件 - e.g. thunderbird, Apple Mail, Gmail ### MTA (Mail Transfer Agent, 郵件傳送代理) - 主要使用 SMTP 來**轉送**信件 - 如果信件是要送給本機使用者,會將信送到該使用者的 mailbox (透過 MDA) - 如果信件是要送給外部使用者,會將信送給轉給下一台 MTA ### MDA (Mail Delivery Agent, 郵件遞送代理) - 主要將信件**投遞給本機使用者**的 mailbox - 可以依據信件內容過濾或是分類收到的信件 ### SMTP (Simple Mail Transfer Protocol, 簡單郵件傳輸協定) - 主要用來**傳送**電子郵件 - 內容基於純文字 (Text-based) - Request-Response model,請求與回應以簡單易懂的**指令**和**狀態碼**進行溝通 - 使用狀態碼來表示請求的結果,例如 `250` 表示成功,`550` 表示地址不存在 - SMTP server 通常監聽 `25`(預設)、`456`(SSL)、`587`(TLS) 這三個 port ### POP3 (Post Office Protocol, 郵局協定) - 從伺服器上**下載電子郵件到本地**設備的通訊協定 - 內容基於純文字 (Text-based) - Request-Response model,請求與回應以簡單易懂的**指令**和**狀態碼**進行溝通 - POP3 server 通常監聽 `110`(預設)、`559`(SSL/TLS) 兩個 port ### IMAP (Internet Message Access Protocol, 網際網路資訊訪問協定) - 在郵件伺服器上**存取和管理電子郵件**的協定 - 內容基於純文字 (Text-based) - Request-Response model,請求與回應以簡單易懂的**指令**和**狀態碼**進行溝通 - IMAP server 通常監聽 `143`(預設)、`993`(SSL/TLS) 兩個 port :::info #### IMAP vs POP3 | **特性** | **IMAP** | **POP3** | |:------------------ |:---------------------------------- |:-------------------------------- | | **存取方式** | 郵件保留在伺服器上,多裝置同步 | 下載郵件後預設刪除伺服器上的郵件 | | **同步能力** | 支援多裝置同步 | 無同步能力 | | **連接埠** | 143 / 993 | 110 / 995 | | **資料夾管理** | 支援多個郵件資料夾 | 不支援 | | **郵件狀態** | 支援郵件狀態同步 (像是已讀、未讀) | 本地設備無法同步郵件狀態 | | **適合的使用情境** | 多裝置存取、需要直接在線上管理郵件 | 單一裝置、需要離線存取 | ::: ## 運作流程 ![LSA Firewall Page 6](https://hackmd.io/_uploads/BkHQALxH1x.svg) ### 寄信 1. MUA 透過 SMTP 送信給自己的 MTA 2. MTA 檢查地址的 host 部分,如果是要送給自己就透過 MDA 放到對應使用者的 mailbox,如果不是就查詢 host 的 DNS MX record,知道下一個 MTA 的 host ![image](https://hackmd.io/_uploads/BklBuxgBJl.png) 3. 透過 MX 的 host 去查詢 A 紀錄拿到 IP 位置 ![image](https://hackmd.io/_uploads/rynKuegS1x.png) 4. 透過 SMTP 轉發信件到下一台 MTA 5. 2 ~ 4 直到送到收件者的 MTA :::info #### MX **M**ail e**X**changer,DNS 上的一種記錄,用來解析電子郵件地址 `user@host` 中 `@` 後的主機名稱。如果沒有設定好 MX record 就向某網域發送信件,會改為使用 A record 去嘗試送信 #### DKIM DomainKeys Identified Mail,透過 DNS 的 TXT 紀錄,傳送方會在電子郵件的 header 插入 `DKIM-Signature` 及相關數位簽章資訊。而接收方則透過 DNS 紀錄得到公開金鑰後進行驗證寄件者、主旨、內文、附件等部份有否被偽造或竄改 #### SPF Sender Policy Framework,透過 DNS 的 TXT 紀錄,可以設定某 IP 範圍或是網域是能夠代表此網域發送郵件的 #### DMARC Domain-based Message Authentication, Reporting and Conformance,透過 DNS 的 TXT 紀錄,DMARC 決定在對一封電子郵件進行 SPF 和 DKIM 記錄檢查後發生的情況。DMARC 決定當電子郵件未通過檢查時,會被標記為垃圾郵件、被封鎖,還是被傳遞給預定的收件者。SPF、DKIM、DMARC 成為一套電子郵件認證機制,可以檢測及防止偽冒身分、對付網路釣魚或垃圾電子郵件 假設垃圾郵件發信者從地址 `trustworthy@example.com` 傳送一封電子郵件,而他們本身無權從 `example.com` 網域傳送電子郵件。垃圾郵件發信者會透過將電子郵件中的**寄件者**標頭替換為 `trustworthy@example.com` 來做到這一點 —— 他們不會從實際的 `example.com` 電子郵件伺服器傳送電子郵件。接收此電子郵件的電子郵件伺服器可以使用 DMARC、SPF 和 DKIM 來發現這是未經授權的電子郵件,然後他們可以將該電子郵件標記為垃圾郵件或拒絕傳遞 ::: :::info #### Relay 原意是**接力**、**中繼**或**轉發**,尤其在通訊和運輸領域中用來表示**將資訊或物品從一個點傳遞到下一個點**。在郵件系統中,Mail Relay 指的就郵件**轉發**的過程 ::: ### 收信 1. MUA 透過 POP3 或是 IMAP 從伺服器上存取、管理信件 ## Lab ### 架設郵件伺服器 ![image](https://hackmd.io/_uploads/rkCiC6pEyl.png) Postfix 是一個被廣泛使用的開源 MTA,用於在網路上發送和接收電子郵件。由 Wietse Venema 開發,最初於 1998 年發行,目的是作為 Sendmail 的替代方案。Postfix 以其效能、安全性、對使用者友好的設定和維護而受到歡迎。 #### 安裝 postfix 1. `sudo apt install postfix` ![image](https://hackmd.io/_uploads/BJeTvFlSJg.png) ![image](https://hackmd.io/_uploads/rkYAwKxH1e.png) :::info **Internet Site** Postfix 能夠接收來自外部的郵件,並向外部郵件地址發送郵件 **Internet with smarthost** Postfix 接收本地郵件,並將要轉送出去的郵件轉交給一個上游的郵件伺服器 (smarthost) 來發送 **Satellite system** 只用於發送郵件,不接收郵件。所有郵件都通過一個上游的伺服器發送,並且不在本地儲存郵件 **Local only** 僅接收和發送本地系統內的郵件,不與外部網路連接 ::: 2. `sudo ss -tlnp` 看到 25 通訊埠正在被監聽就安裝成功了 ![image](https://hackmd.io/_uploads/SJHx9KxBke.png) :::info 主要的設定擋在 `/etc/postfix/main.cf` **myhostname** - 設定郵件伺服器的完整主機名稱 (FQDN, Fully Qualified Domain Name) - 若伺服器名稱是 `mail`,網域是 `example.com`,則完整名稱就是 `mail.example.com` ```shell myhostname = mail.example.com ``` **mydomain** - 設定郵件伺服器所屬的網域名稱,通常是 `myhostname` 去掉主機名稱部分後剩下的網域名稱 ```shell mydomain = example.com ``` **myorigin** - 設定本機使用者發送郵件的發信人網域,下方的設定就會讓發信人的地址變成 `alice@example.com` ```shell myorigin = $mydomain ``` **inet_interfaces** - 指定 Postfix 聽的網路介面,下方的設定會監聽所有網路介面 ```shell inet_interfaces = all ``` **mydestination** - 定義本地接收的網域,意即哪些網域的郵件應該被視為本地郵件,下方設定會讓伺服器接收發送給 `example.com` 和 `localhost` 的郵件 ```shell mydestination = $myhostname, example.com, localhost.localdomain, localhost ``` **relayhost** - 指定其他的郵件伺服器 (smarthost) 來發送郵件,不需要留空即可 ``` relayhost = ``` **home_mailbox** - 設定郵件存放的位置和格式,如果是資料夾 (`/`結尾) 就會是 Maildir 格式,檔案的話就會是 mbox 格式 ``` home_mailbox = Maildir/ home_mailbox = mailbox ``` ::: :::info **Maildir vs mbox** | **特性** | **Maildir** | **mbox** | |:------------ |:-------------------------------- |:----------------------------------- | | **存放方式** | 每封郵件存為一個單獨的檔案 | 所有郵件存放在一個單一檔案 | | **目錄結構** | `cur/`、`new/`、`tmp/` 子目錄 | 單一檔案,如 `/var/mail/{username}` | | **並行存取** | 支援並行存取,不易產生 lock 問題 | 並行存取時容易出現 lock 問題 | ::: 3. `sudo apt install mailutils` 4. `echo "Hello, this is a test email." | mail -s "Test Email" jtr860820@lsa-mail-server` 5. 可以在 `/var/mail/{username}` 看到郵件內容 ![image](https://hackmd.io/_uploads/SJL1H9xrJx.png) ### 使用 telnet 收發信件 #### 寄信 1. `telnet localhost 25` 2. `HELO lsa-mail-server` 3. `MAIL FROM:<jtr8608303@lsa-mail-server>` 4. `RCPT TO:<jtr8608303@lsa-mail-server>` 5. `DATA` 6. ``` Subject: Test Email via Telnet This is a test email sent using Telnet. . ``` 7. `QUIT` ![image](https://hackmd.io/_uploads/BkIqF5lSyg.png) :::info 安裝 POP3 跟 IMAP server `sudo apt install dovecot-imapd dovecot-pop3d` ::: #### POP3 1. `telnet localhost 110` 2. `USER jtr860830` 3. `PASS password` 4. `LIST` 5. `RETR 1` 6. `QUIT` ![image](https://hackmd.io/_uploads/SJlWh5gH1x.png) #### IMAP 1. `telnet localhost 143` 2. `a1 LOGIN jtr860830 password` 3. `a2 SELECT INBOX` 4. `a3 FETCH 1:* (FLAGS BODY[HEADER.FIELDS (SUBJECT FROM)])` 5. `a4 FETCH 1 BODY[TEXT]` 6. `a5 LOGOUT` ![image](https://hackmd.io/_uploads/rka865erye.png) ## Refs - https://wiki.archlinux.org/title/Mail_server - https://www.cloudflare.com/zh-tw/learning/email-security/dmarc-dkim-spf/ -