Week 15 (2024/12/19) 電子郵件 --- ![image](https://hackmd.io/_uploads/rJA7sLZSke.png) ## 有關的協定 - SMTP (Simple Mail Transfer Protocol) - POP (Post Office Protocol) - IMAP (Internet Message Access Protocol) - MIME (Multipurpose Internet Mail Extensions) ## 系統組成 ### MUA (Mail User Agent,郵件使用者代理) - 俗稱電子郵件客戶端 - 使用 SMTP 傳送信件給 SMTP Server - 使用 POP3 或是 IMAP 接收及管理信件 - 例如 - Apple Mail App - Thunderird ### MTA (Mail Transfer Agent,郵件傳送代理) - 主要將信件投遞給本機使用者的 mailbox - 可以依據信件內容過濾或是分類收到的信件 ### MDA (Mail Delivery Agent) - ### SMTP (Simple Mail Transfer Protocol,簡單郵件傳送協定) - 主要用來**傳送**電子郵件 - 內容基於純文字 ### POP3 (Post Office Protocol, 郵局協定) - 從伺服器上下載電子郵件到本地設備的通訊協第 - 內容基於純文字 ### IMAP (Internet Message Access Protocol, 網際網路資訊訪問協定) - 在郵件伺服器上**存取和管理電子郵件**的協定 - 內容基於純文字 - listen port : 143(default)、993(SSL/TLS) - 現代較常使用的 protocol ## 運作流程 ![image](https://hackmd.io/_uploads/Syn1JD-ryg.png) ### 寄信 1. MUA 透過 SMTP 送信給自己的 MTA 2. MTA 檢查地址的 host(`@` 後面),如果是要送給自己就透過 MDA 放到對應使用者的 mailbox,如果不是就查詢 host 的 DNS MX record,知道下一個 MTA 的 host > 如何查詢 host 的 DNS MX record? >> dig [host] MX - Relay : 原**接力、中繼、轉發** :::info #### MX Mail eXchanger,DNS 上的一種紀錄。用來解析電子郵件地址 `user@host` 中的主機名稱,如果沒有設定好則會查找 A record。 #### DKIM DomainKeys Identified Mail,透過 DNS 的 TXT 紀錄,傳送方會在 email 的 header 插入 `DKIM-Signature` 及相關數位簽章資訊。而接收方透過 DNS 紀錄得到公開金鑰進行驗證寄件者、主旨、內文、附件等部分有否被偽造或竄改。 #### SPF Sender Policy Framework,透過 DNS 的 TXT record,可以設定某 IP 範圍或是網域是能夠代表此網域發送郵件的 查詢一個網域的 SPF record 方法: `dig TXT josh-hsieh.tw` 後找到有寫 `v =spf include:....` 那行 ![範例](https://hackmd.io/_uploads/H1H8NDbHyg.png) #### DMARC Domain-based Message Authentication, Reporting and Conformance,透過 DNS 的 TXT 紀錄,DMARC 決定在對一封電子郵件進行 SPF 和 DKIM 紀錄檢查後發生的情況。DMARC 決定當 email 未通過檢查時,會被標記為垃圾郵件、被封鎖,還是被傳遞給預定地收件者。SPF、DKIM、DMARC 成為一套電子郵件認證機制,可以檢測及防止偽冒身分、對付網路釣魚或垃圾電子郵件。 假設垃圾郵件發信者要從地址 `trushworthy@example.com` 傳送一封電子郵件,而他們本身無權從 `@example.com` 網域傳送電子郵件。垃圾郵件發信者會透過將電子郵件中的**寄件者**標頭替換 `trushworthy@example.com` 來做到這一點 --- 他們不會從實際的 `example.com` 電子郵件伺服器傳送電子郵件。接收此電子郵件的電子郵件伺服器可以使用 DMARC、SPF、DKIM 來發現這是一封未經過授權的電子郵件,然後他們可以把它標記成垃圾郵件或拒絕傳遞 #### Relay 原意是接力、收信跟轉發 #### 為啥要這些安全措施 以前網路大家都非常互相信任,但後來有人偽造別人的身分亂寄信,造成錢財上的損失,甚至有人因此自殺。就想出來越來越多方法來阻止別人偽造。 ::: :::info #### DNSSEC & DNS Spoofing - 以前大家也都認為 DNS 很可靠,但後來被偽造,所以需要安全措施,叫 DNSSEC - DNS 是 UDP,只要有人偷聽到你的 query,再搶著回覆,就很容易 DNS Spoofing - 另一種做法是,假設攻擊者知道這間學校大家都用 163.22.2.1 這台 DNS relay,攻擊者就一直往這台送說例如 google.com 的 IP 是 1.2.3.4。等 163 這台的 cache 過期了,他相信說攻擊者發來的是真的,就一次汙染了整間學校的 DNS ::: :::warning #### BT 補充 - 查看 DNS 的 TXT record 中的 DKIM 紀錄 - `dig google._domainkey.bluet.org TXT` - 查看 DNS 的 TXT record 中的 SPF 紀錄 - `dig bluet.org TXT` - 查看 DNS 的 TXT record 中的 DMARC 紀錄 - `dig _dmarc.bluet.org TXT` - 查看 DNSSEC - https://dnssec-analyzer.verisignlabs.com/bluet.org - 因為學校環境,這兩個指令需要指定 server - `dig @1.1.1.1 bluet.org. DS` - `dig @1.1.1.1 bluet.org. DNSKEY` ::: ### 收信 1. MUA 透過 POP3 或是 IMAP 從伺服器上存取、管理信件。 ## Lab ### 架設郵件伺服器 Postfix 是一個被廣泛使用的郵件伺服器 #### 安裝 postfix - `sudo apt install postfix` - 選 Internet sites - `sudo ss -tlnp` - `sudo vim /etc/postfix/main.cf` :::info #### Internet Site Postfix 能夠接生來自外部的郵件,並向外部郵件地址發送郵件 #### Internet with smarthost Postfix 接本地郵件,並將 #### Satellite system #### Local only ::: #### 發送郵件 - `sudo apt install mailutils` - `echo "Hello, this is a test mail." | mail -s "Test Email" {要將郵件送到的主機位置:username@host}` - 可以在 `/var/mail/{username}` 看到郵件內容 - 也可以下 `mail` 查看 #### 利用 telnet 發送郵件 - 連線 : `telnet localhost 25` - 和 telnet 打招呼(一定要做,確認有在運作) : `HELO {username@host}` - 須回傳 `250 {username@host}` - 寄件人 : `MAIL FROM:<username@host>` - `<>` 這個要打 - 須回傳 `250 2.1.0 OK` - 收信人 : `RCPT TO:<username@host>` - `<>` 這個要打 - 須回傳 `250 2.1.0 OK` - 開始寫信 : `DATA` - 須回傳 `354 End data with <CR><LF>, <CR><LF>` - 此訊息說明內文輸入結束時,要如何結束,如下 - `Subject: {文件主旨}` - enter - 打內文 - enter - `.` - enter - 須回傳 `250 2.1.0 OK: queued as ...` - 退出 : `QUIT` #### POP3 收信 - 安裝 : `sudo apt install dovecot-imapd dovecot-pop3d` - 連線 :`telnet localhost 110` - 登入 :`USER {username}` - 回傳 `+OK` - `PASS {password}` - 回傳 `OK Logged in.` - 列出信件夾中的信件 :`LIST` - 回傳 `+OK {} messages` - 查看第一封 : `RETR 1` - 退出 :`QUIT` ### IMAP 收信 - `{an}` : `an` 依輸入命令編號,回傳訊息也可以知道是根據哪一個使用者命令回傳 - 可以是 `t1`、`b2`、`Q`、`ZEN`... - 連線 : `telnet localhost 143` - 登入 : `a1 LOGIN {username} {password}` - 查看信件夾 : `a2 SELECT INBOX` - 查看第一封到最後一封 :`a3 FETCH 1:* (FLAGS BODY[HEADER.FIELDS (SUBJECT FROM)])` - 查看第一封 : `a4 FETCH 1 BODY[TEXT]` - 退出 : `a5 LOGOUT`