---
# System prepended metadata

title: LSA mail server
tags: ['1131']

---

- 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/
- 