Mail Server 征服指南 (五) 第四章:安裝與設定 Dovecot (最後一塊拼圖)。

這就是我們的最後一塊拼圖:Dovecot

如果說 Postfix 是在大門口負責收發信件的「郵差」,那 Dovecot 就是在屋內負責管理的「全能管家」。它有兩個核心任務:

  1. 驗收與倉儲 (LMTP/Mail Location):把郵差收進來的信,依照收件人分門別類,整齊地存進硬碟的資料夾裡。
  2. 身分驗證與取信 (Auth/IMAP):幫郵差查驗寄信人的密碼 (SASL),並讓主人(你)能透過手機或電腦把信取出來看。

讓我們開始安裝並設定這位管家吧!

1. 建立系統專用帳號 (vmail)

在安裝軟體前,我們需要先解決一個 Linux 的權限問題。 雖然我們的使用者是「虛擬」的(在資料庫裡),但信件最終還是要存成硬碟上的「檔案」。Linux 的檔案系統需要有一個真實的擁有者來管理這些檔案。

我們建立一個名為 vmail 的系統帳號,專門用來持有所有人的信件檔案:

# 建立群組 vmail (GID 5000)
sudo groupadd -g 5000 vmail

# 建立使用者 vmail (UID 5000),並指定它的家目錄在 /var/mail/vmail
sudo useradd -g vmail -u 5000 vmail -d /var/mail/vmail -m

2. 安裝 Dovecot 套件

我們需要安裝核心服務、IMAP 服務、LMTP 服務(接收 Postfix 轉交的信),以及 MySQL 驅動。

sudo apt update
sudo apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql -y

3. 設定資料庫連線 (dovecot-sql.conf.ext)

這一步是讓 Dovecot 能夠讀取我們在第二章建立的資料庫。

備份並建立設定檔:

sudo cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.bak
sudo nano /etc/dovecot/dovecot-sql.conf.ext

請清空內容,貼上以下設定(請記得修改 password):

driver = mysql
connect = host=127.0.0.1 dbname=mailserver user=mailserver password=password

# [密碼加密方式]
# 目前我們先用 PLAIN (明碼) 方便測試。
# 未來若要加密,這裡改成 SHA512-CRYPT (那資料庫裡的密碼也要換成加密字串)
default_pass_scheme = PLAIN

# [驗證查詢]:Dovecot 用這行來檢查帳號密碼是否正確
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

# [使用者查詢]:驗證通過後,Dovecot 用這行知道信箱檔案要放在哪裡
# 這裡我們回傳了固定的 uid/gid (5000),以及動態的路徑 (domain/user)
user_query = SELECT 5000 as uid, 5000 as gid, 'maildir:/var/mail/vmail/%d/%n' as mail FROM virtual_users WHERE email='%u';

注意%d 代表網域 (mydomain.com),%n 代表使用者名稱 (user)。所以信件會存在 /var/mail/vmail/mydomain.com/user/ 裡面,結構非常清晰。

修改權限(保護密碼):

sudo chgrp dovecot /etc/dovecot/dovecot-sql.conf.ext
sudo chmod 640 /etc/dovecot/dovecot-sql.conf.ext

4. 設定 Dovecot 核心模組

Dovecot 的設定檔分散在 /etc/dovecot/conf.d/ 裡。我們需要修改其中的四個檔案。

A. 修改 10-auth.conf (啟用 SQL 認證)

sudo nano /etc/dovecot/conf.d/10-auth.conf


  • 找到 disable_plaintext_auth,確認它是 no (或是註解掉),因為我們之後會強制用 SSL,所以這裡設 no 沒關係,方便除錯。
  • 找到 auth_mechanisms,修改為:auth_mechanisms = plain login
  • 註解掉 (加上 #):!include auth-system.conf.ext (我們不用 Linux 系統帳號)
  • 取消註解 (拿掉 #):!include auth-sql.conf.ext (我們要用 SQL)

B. 修改 10-mail.conf (設定信箱位置)

sudo nano /etc/dovecot/conf.d/10-mail.conf


  • 找到 mail_location,修改為:
mail_location = maildir:/var/mail/vmail/%d/%n

  • 找到 mail_uidmail_gid,修改為我們剛建的 vmail 帳號 ID:
mail_uid = 5000 mail_gid = 5000


C. 修改 10-master.conf (打開與 Postfix 的溝通大門) 這是最重要的一步!

這裡定義了 Postfix 第三章設定檔裡寫的 private/authprivate/dovecot-lmtp 是什麼。

sudo nano /etc/dovecot/conf.d/10-master.conf

請找到 service lmtpservice auth 區塊,修改成下面這樣(小心大括號的位置):

# 1. 讓 Postfix 把信塞進來的接口 (LMTP)
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}

# 2. 讓 Postfix 來問密碼的接口 (Auth)
service auth {
  # 給 Postfix 用的 (SMTP Auth)
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  
  # 給 Dovecot 自己用的
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
  }
  user = dovecot
}

D. 修改 10-ssl.conf (掛載 Let’s Encrypt)

sudo nano /etc/dovecot/conf.d/10-ssl.conf
  • 找到 ssl,確認是 yesrequired
  • 修改憑證路徑(換成你的真實路徑):
ssl_cert = </etc/letsencrypt/live/mail.mydomain.com/fullchain.pem 
ssl_key = </etc/letsencrypt/live/mail.mydomain.com/privkey.pem

5. 權限修正與啟動

我們需要告訴 Dovecot 它的 SQL 設定檔在哪裡(因為我們剛剛是在 conf.d/10-auth.conf 裡 include 了 auth-sql.conf.ext,我們要去編輯那個檔案指向我們的 dovecot-sql.conf.ext)。

更簡單的做法,直接編輯 /etc/dovecot/conf.d/auth-sql.conf.ext

sudo nano /etc/dovecot/conf.d/auth-sql.conf.ext

確保內容如下:

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}

最後,重啟 Dovecot 並檢查狀態:

sudo systemctl restart dovecot
sudo systemctl status dovecot

如果看到綠色的 active (running),恭喜你!所有安裝步驟已全部完成!

最後我們將要進入驗收環節!

第一章:架構規劃與環境準備

第二章:基礎建設篇——DNS、SSL 與資料庫

第三章:郵差的武裝——安裝 Postfix 並連接資料庫

第四章:安裝與設定 Dovecot (最後一塊拼圖)。

第五章:驗收時刻——全流程測試

第六章:設定 AWS SES Relay (讓信件使命必達)

Mail Server 征服指南 (六) 第五章:驗收時刻——全流程測試

我們辛苦搭建的郵件伺服器即將迎來第一次實戰測試。

在這個章節,我們不只要看「結果」,更要學會看「過程」。我會教您如何用「駭客視角」(直接下指令)來測試伺服器,這能讓您清楚看到每一個環節是否正常運作。

第一階段:功能連通性測試 (使用明碼)

在這個階段,您的資料庫密碼應該是明碼的 123456,且 Dovecot 設定為 default_pass_scheme = PLAIN

1. 測試收信 (Telnet 模擬) 我們假裝自己是外部郵件主機,直接投遞信件。 在 視窗 B 輸入:

telnet localhost 25


依序輸入(注意:若打錯字請按 Enter 重來,不能按 Backspace):

EHLO gmail.com
MAIL FROM:<test@gmail.com>
RCPT TO:<user@mydomain.com>
DATA
Subject: Test 1 (Plaintext)

Hello, this is a test.
.
QUIT

驗收:看視窗 A,出現 saved mail to maildir:... 代表寫入成功。

2. 測試讀信 (IMAP) 打開您的手機或電腦郵件軟體 (Thunderbird/Outlook):

  • Protocol: IMAP
  • Email: user@mydomain.com
  • Hostname (Incoming): mail.mydomain.com
  • Port: 993 (SSL/TLS)
  • Username: user@mydomain.com (務必填完整 Email)
  • Password: 123456 (您在資料庫設定的密碼)

驗收:應該能成功登入,並看到剛剛那封 “Test 1″。

3. 測試寄信 (SMTP) 使用剛剛設定好的軟體寄一封信給您自己的 Gmail。

  • Protocol: SMTP
  • Hostname (Outgoing): mail.mydomain.com
  • Port: 587 (STARTTLS) —— 這裡很重要,不要選 25 或 465
  • Authentication: Normal Password (或 Plain)
  • Username: user@mydomain.com

驗收:視窗 A 出現 sasl_method=PLAIN, sasl_username=...status=sent (或是 AWS 逾時),只要沒出現 Access denied 就算成功。


第二階段:安全性升級 (啟用密碼加密)

確認系統能跑後,我們要來修補最大的安全漏洞:資料庫裡的明碼密碼

1. 產生加密密碼 我們使用 Dovecot 內建工具,產生強大的 SHA512-CRYPT 雜湊值。 在終端機輸入:

doveadm pw -s SHA512-CRYPT


  • 輸入兩次您的密碼 (例如 123456)。
  • 複製回傳的那串亂碼,例如:{SHA512-CRYPT}$6$xyz...

2. 更新資料庫 登入 MySQL,把這串亂碼存進去。

sudo mysql -u root -p servermail


— 請把下面那一長串換成你剛剛生成的亂碼


UPDATE virtual_users 
SET password = '{SHA512-CRYPT}$6$xyz...' 
WHERE email = 'user@mydomain.com';

離開資料庫 (exit)。

3. 修改 Dovecot 設定 告訴 Dovecot:「從現在開始,資料庫給你的不再是明碼,而是 SHA512 加密過的字串。」

編輯檔案:

sudo nano /etc/dovecot/dovecot-sql.conf.ext



將原本的 PLAIN 改掉:

# default_pass_scheme = PLAIN  <-- 註解或刪掉這行
default_pass_scheme = SHA512-CRYPT

4. 重啟 Dovecot

sudo systemctl restart dovecot


第三階段:最終驗收 (加密後測試)

現在,雖然您的密碼還是 123456,但在伺服器內部,它已經不再以明碼形式儲存了。我們必須確認 Dovecot 能正確解讀這串亂碼。

1. 再次測試收信 (IMAP)

  • 動作:在您的郵件軟體中,按一下「接收/傳送」或是重新登入。
  • 觀察
    • 如果成功:代表 Dovecot 成功將您輸入的 123456 加密後,跟資料庫裡的 $6$... 比對吻合。
    • 如果失敗 (Authentication failed):代表加密演算法沒對上 (例如您產生了 BLF-CRYPT 但設定檔寫 SHA512-CRYPT),或是複製時少複製了字元。

2. 再次測試寄信 (SMTP)

  • 動作:再寄一封信給 Gmail,主旨寫 “Test 2 (Encrypted DB)”。
  • 觀察:確認信件能順利寄出。

恭喜!您已完成正式部署

如果第三階段測試通過,您的 Mail Server 就已經達到 Production (生產環境) 的安全標準了:

  1. 傳輸加密:全程使用 TLS/SSL。
  2. 儲存加密:資料庫密碼使用 SHA512 雜湊保護。
  3. 身分驗證:收發信皆需帳號密碼。

現在這台機器已經固若金湯。下一步,我們要解決的是**「信寄出去會被當垃圾信」**的問題,這就需要 設定 AWS SES Relay (寄信中繼) 來幫忙了。

第一章:架構規劃與環境準備

第二章:基礎建設篇——DNS、SSL 與資料庫

第三章:郵差的武裝——安裝 Postfix 並連接資料庫

第四章:安裝與設定 Dovecot (最後一塊拼圖)。

第五章:驗收時刻——全流程測試

第六章:設定 AWS SES Relay (讓信件使命必達)

Mail Server 征服指南 (七) 第六章:設定 AWS SES Relay (讓信件使命必達) 沙盒解鎖攻略更新!

你可以把 Email 寄送的過程想像成**「古代送信」,而 SMTP(寄信協定)本身設計得非常老舊且沒有安全感,就像一個毫無防備的郵差**。

為什麼 Gmail、Outlook 會把你的信當垃圾信?核心原因只有一個:「身分不明,缺乏信任」。

以下是用最白話的方式解釋這「三大護法」加上「黑名單」的運作邏輯:


1. 根本原因:SMTP 的天生缺陷

SMTP 協定在幾十年前發明時,並沒有設計「驗證身分」的功能。

這意味著,任何人都可以躲在暗巷裡,寫一封信,然後在信封寄件人(From)填上 president@whitehouse.gov。郵差(SMTP)根本看不出來這是假的,照樣幫你送。

為了防止這種「冒名頂替」,現代郵件系統發展出了三道檢查關卡:

2. 第一關:SPF (Sender Policy Framework) —— 「警衛與訪客名單」

  • 概念:這是一份白名單
  • 運作:Gmail 收到你的信時,會去查你的 DNS(警衛室)問:「請問 IP 1.2.3.4 (這位郵差) 有資格代表 mydomain.com 送信嗎?」
    • 如果沒有 SPF:Gmail 覺得這個郵差是隨便路過的,可疑 –> 垃圾信
    • 如果有 SPF:確認這是在名單上的合法郵差 –> 通過

3. 第二關:DKIM (DomainKeys Identified Mail) —— 「完整的蠟封」

  • 概念:這是一個數位簽名(防偽標籤)
  • 運作:就算郵差是對的,信件內容有沒有在半路被駭客竄改過?或者這是不是別人偽造了你的信頭?DKIM 就像是在信封口蓋了一個**「獨一無二的火漆蠟封」**(私鑰加密)。
    • 沒有 DKIM:Gmail 收到信,發現信封沒封口,誰都能塞廣告進去 –> 垃圾信
    • 有 DKIM:Gmail 用你的公鑰檢查蠟封,發現完好無損 –> 確認是原廠出品,內容未被竄改

4. 第三關:DMARC —— 「老闆的指令」

  • 概念:這是一本指導手冊
  • 運作:如果有駭客偽造了你的信,導致 SPF 或 DKIM 檢查失敗了,Gmail 該怎麼辦?是直接丟掉?還是放進垃圾桶?還是通知你?DMARC 就是你(網域擁有者)告訴 Gmail:「如果有人冒充我(驗證失敗),請直接把它拒絕(Reject)!」
    • 沒有 DMARC:Gmail 雖然抓到了假信,但不知道怎麼處理,可能會為了怕誤判而勉強收下,但也降低了你網域的權威性。

5. 隱藏大魔王:IP 信譽 (IP Reputation) —— 「前科紀錄」

就算你上述三種證件都齊全了,為什麼還會進垃圾桶?

  • 原因:因為送信的那個 IP 位址(例如 AWS EC2 的 IP)可能有**「前科」**。
  • 情境:如果上一位租用這個 IP 的人是用來發送百萬封詐騙信的,這個 IP 就會在國際反垃圾組織(如 Spamhaus)的黑名單上。
  • 結果:Gmail 一看:「喔,這個 IP 是個慣犯!」不管你的證件多齊全,直接拒收。

總結

這就是為什麼我們要用 AWS SES

  1. 解決 IP 前科:Amazon 會維護 IP 的清潔度,確保它們不在黑名單上。
  2. 解決 SPF/DKIM:讓 Gmail 相信**「這封信真的是你寄的,而且你授權了 Amazon 幫你跑腿」。

下面讓我們詳細講述設定的流程

1. AWS SES 前置作業 (在 AWS Console 操作)

這部分需要在 AWS 網頁介面上完成,請確保您選對了 Region (區域)(選有支援 SES 的區域)。

A1. 驗證網域 (Verify Domain)

  1. 進入 SES Console -> Configuration -> Identities
  2. 點擊 Create identity -> 選擇 Domain
  3. 輸入您的網域 mydomain.com
  4. Publish DNS records to Route53: 請「不要」勾選此選項(保持未勾選狀態,除非您用Route53 管理您的網域)。
  5. Advanced DKIM settings: 選擇 Easy DKIM (預設值)。
  6. DKIM signing key length: 選擇 RSA_2048_BIT (比較通用) 或 1024 都可以。
  7. 點擊 Create identity

A2. 獲取 CNAME 紀錄 (DKIM)

建立完成後,畫面會跳轉到該網域的詳細資訊頁面。往下滑,您會看到一個 「DKIM DNS records」 的區塊。

這裡會有 3 組 CNAME 紀錄。AWS 會給您兩個欄位:

  • Name (主機名稱 / Host)
  • Value (內容 / Target)

A3. 到您的 DNS 託管商新增紀錄

現在,請開另一個分頁,登入您的 DNS 管理後台。

您需要將那 3 組 CNAME 逐一新增進去。

⚠️ 超級重要的陷阱 (請務必注意)

大多數 DNS 託管商(如 Cloudflare, GoDaddy)在輸入「Name (Host)」時,會自動幫您補上網域後綴

  • AWS 顯示的 Nameabcde12345._domainkey.mydomain.com
  • 您在 DNS 後台只需輸入abcde12345._domainkey

如果您把整串貼上去,就會變成 ...mydomain.com.mydomain.com,導致驗證失敗!


A4. 除了 CNAME,別忘了 SPF (重要!)

因為您要透過 AWS SES 寄信,您必須在 DNS 告訴全世界:「AWS SES 是我授權的寄件人」。

請在您的 DNS 後台檢查 TXT 紀錄 (SPF)

  • 如果本來沒有 SPF 紀錄: 新增一條 TXT 紀錄:
    • Host/Name: @
    • Value: v=spf1 include:amazonses.com ~all
  • 如果原本已經有 SPF 紀錄 (例如原本是設給 EC2 本機寄信): 請修改原本那條紀錄,把 AWS SES 加進去。
    • 舊的可能長這樣:v=spf1 mx ip4:1.2.3.4 ~all
    • 修改後v=spf1 mx ip4:1.2.3.4 include:amazonses.com ~all

(重點就是一定要出現 include:amazonses.com 這段文字)

設定完後,通常等待 5 分鐘到 1 小時,回到 AWS SES Console 重新整理頁面,當 Status 變成綠色的 Verified,就代表成功了!如果沒成功,請檢查你輸入的DNS資訊是否正確,任何微小的錯誤都會導致驗證失敗

B. 申請移出沙盒 (Production Access) 剛開通的 SES 處於「沙盒模式 (Sandbox)」,只能寄信給「已經驗證過」的 Email。您必須申請移出沙盒才能寄給外面的陌生人。

  1. 在 SES Console 首頁上方會看到一個藍色警告條。
  2. 點擊 Request production access
  3. 填寫用途(用英文寫:My mail server is for personal business communication, not for marketing spam…)。
  4. 通常需要等待數小時到一天審核。

在填寫用途這一欄,由於我是差不多十年前申請的,當時隨便填都會過。現在不一樣了,建議你參考以下模版:

Hello AWS Support Team,

I am requesting to move my Amazon SES account out of the sandbox. I use this domain for my personal IT blog and my personal email communications.

1. How I build my mailing list: I do not buy, rent, or use any marketing mailing lists. The emails are strictly for my personal 1-on-1 communications and a few users who explicitly register on my personal WordPress site.

2. What kind of emails I send: There are two main use cases:

Personal Email Routing: I use SES as an SMTP relay for my personal custom domain email (e.g., admin@thetmfamily.com) for daily 1-on-1 correspondence.

System Notifications: I use it to send transactional emails for my WordPress blog, such as password resets and comment notifications. I DO NOT send newsletters or marketing campaigns.

3. How I handle Bounces and Complaints: Protecting the SES sender reputation is my top priority.

I have enabled the SES Account-level suppression list to automatically stop sending emails to addresses that result in a hard bounce or complaint.

Since this is a personal domain, the outbound volume is extremely low and highly targeted. Any bounced email from my WordPress system will be manually investigated and removed from the database.

Thank you for your review.

個模版強調了三件事:

坦承「雙軌並行」:直接告訴審核員你有兩個用途(Personal Email Routing 與 System Notifications),這完美解釋了為什麼你的發信量可能很低,但又確實有對外發信的剛性需求。

強調「極低風險」:在第三點特別加入了「The outbound volume is extremely low and highly targeted (發信量極低且對象明確)」,這句話對 AWS 審核員來說是一顆超級定心丸,代表你絕對不可能成為發送海量垃圾信的源頭。

無敵護城河:「SES Account-level suppression list」這個底層防禦機制的關鍵字,確保能順利通過機器人的初步審查。

這裡面提到了Account-level suppression list這個東西,這是SES內建的防護機制,這個機制就像是一個「自動黑名單防火牆」。

沒有開啟以前:如果有個白目讀者亂填信箱 fake123@gmail.com,你的 WordPress 每次有新文章就寄給他,每次都被 Gmail 判定「查無此人 (Hard Bounce)」。連續幾次之後,Gmail 就會把你的網域列入黑名單,AWS 也會把你的 SES 帳號停權。

開啟這個機制後:第一次寄給 fake123@gmail.com 發生退信時,AWS SES 會立刻、默默地把這個信箱加入你的「帳戶黑名單」中。

保護生效:下次你的 WordPress 又傻傻地要把信寄給 fake123@gmail.com 時,信件一送到 AWS SES,SES 就會直接把它丟掉,根本不會寄出去給 Gmail。這樣就完美保護了你的發信信譽 (Reputation)!

Suppression list 開啟的方法如下:

登入 AWS Console,搜尋並進入 Amazon SES 儀表板。

在左側選單直接找 Suppression list (隱藏名單 / 抑制清單)

裡面會有一個區塊叫做 Account-level settings (帳戶層級設定)

點擊 Edit (編輯),確保Enabled 被勾選了、並且 suppression reasons 選擇 BOUNCE (退信)COMPLAINTS (客訴)

C. 取得 SMTP 帳號密碼 (關鍵!) 注意:這不是您登入 AWS 的 IAM 帳號,這是 SES 專用的。

  1. 進入 SES Console -> SMTP Settings
  2. 記下 SMTP Endpoint (例如:email-smtp.us-east-1.amazonaws.com)。
  3. 點擊 Create SMTP credentials
  4. AWS 會產生一組 IAM User NameSmtp UsernameSmtp Password
  5. 請務必下載 CSV 或複製下來! 這個長得很像亂碼的密碼只會顯示這一次。

2. 安裝 SASL 相依套件

Postfix 需要這個套件才能拿著帳號密碼去向 AWS SES 登入。

sudo apt update
sudo apt install libsasl2-modules postfix-pcre -y

3. 設定 Postfix 指定 Relay Host

我們要修改 main.cf,告訴 Postfix:「以後寄給外部的信,不要自己送,全部轉交給 AWS SES。」

開啟設定檔:

sudo nano /etc/postfix/main.cf


請找到 relayhost 這一行(預設可能是空的),並在檔案的最下方加入/修改以下設定區塊:

# ==============================
# AWS SES Relay Configuration
# ==============================

# 1. 指定 AWS SES 的伺服器 (請換成您在步驟 1-C 看到的 Endpoint)
# 注意:要把網址用中括號 [] 包起來,並指定 :587
# 中括號的意思是「不要查 MX 紀錄,直接連線」,這能加速連線
relayhost = [email-smtp.us-east-1.amazonaws.com]:587

# 2. 啟用 SASL 認證 (Postfix 作為客戶端向 SES 登入)
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = login

# 3. 強制使用 TLS 加密 (AWS 要求一定要加密)
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_note_starttls_offer = yes

# 4. 指定 CA 憑證位置 (確保能驗證 AWS 的 SSL 憑證)
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

存檔離開。


4. 建立密碼檔 (sasl_passwd)

我們要把剛剛從 AWS 拿到的 SMTP 帳號密碼寫入檔案。

建立新檔案:

sudo nano /etc/postfix/sasl_passwd


貼上以下內容(請替換成您自己的資料): 格式:[Endpoint]:587 Username:Password

[email-smtp.us-east-1.amazonaws.com]:587 AKIAIOSFODNN7EXAMPLE:AgGbq...VERY...LONG...PASSWORD...

(注意:前面的 Endpoint 也要加上中括號 [],必須跟 main.cf 裡寫的一模一樣)

存檔離開。


5. 雜湊密碼並保護檔案

這個檔案裡有明碼密碼,非常危險,我們要把權限鎖死,並轉換成 Postfix 讀得懂的 hash 檔。

# 1. 轉換成資料庫格式 (會產生 sasl_passwd.db)
sudo postmap hash:/etc/postfix/sasl_passwd

# 2. 將檔案的所屬群組改為 postfix (這樣 postfix 才有資格讀)
sudo chgrp postfix /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

# 4. 移除明碼檔案 (或是移到安全的地方備份)
# 這裡我們先改權限讓 root能讀寫 postfix能讀,確保安全
sudo chmod 0640 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

# 3. 重啟 Postfix
sudo systemctl restart postfix

6. 最終驗收:寄信到 Gmail

現在,請再次打開您的郵件軟體(手機或電腦),透過您的 Mail Server 寄一封信給您的 Gmail。

觀察重點:

  1. 檢查 Log (/var/log/mail.log): 您應該會看到類似這樣的訊息: status=sent (250 Ok ...) 且會顯示連線到 email-smtp.us-east-1.amazonaws.com
  2. 檢查 Gmail 收件匣: 打開收到的信,點擊「顯示原始郵件 (Show Original)」。
    • SPF: PASS
    • DKIM: PASS (如果您在 AWS 有開啟 DKIM)
    • DMARC: PASS (如果您 DNS 有設對)
    • Encryption: Standard encryption (TLS)

如果 Log 顯示 Authentication failed

  • 檢查 sasl_passwd 裡的帳號密碼是否填錯(是 SMTP 帳號,不是 IAM 帳號)。
  • 檢查 relayhostsasl_passwd 裡的中括號 [] 是否一致。
  • 記得每次改完 sasl_passwd 都要執行 sudo postmap hash:/etc/postfix/sasl_passwd

全系列總結

恭喜您!經過這長途跋涉,您已經完成了一項許多工程師都覺得頭痛的任務。

您現在擁有一台:

  • 獨立自主 的郵件伺服器 (Linux + Postfix + Dovecot)。
  • 資料庫管理 的虛擬帳號系統 (MariaDB + SHA512)。
  • 企業級 的傳輸安全性 (TLS + Let’s Encrypt)。
  • 高信譽 的寄信通道 (AWS SES)。

現在,您可以自由地開設無限個 Email 帳號,掌控自己的數據,並享受自架服務的樂趣了!另外特別推薦使用Roundcube webmail作為你的Webmail解決方案,這個老牌的Webmail解決方案不但更新頻繁,還有強大的社群以及外掛程式(例如兩步驟驗證2FA等等),絕對值得您一試!

第一章:架構規劃與環境準備

第二章:基礎建設篇——DNS、SSL 與資料庫

第三章:郵差的武裝——安裝 Postfix 並連接資料庫

第四章:安裝與設定 Dovecot (最後一塊拼圖)。

第五章:驗收時刻——全流程測試

第六章:設定 AWS SES Relay (讓信件使命必達)

Mail Server 征服指南(一) 前言:寫給業餘愛好者

精選內容

相信很多跟我一樣熱愛 Linux 的業餘玩家,都有過類似的經歷:我們興致勃勃地從零開始,成功架設了自己的 Web Server(無論是 Apache 還是 Nginx),搞定了 HTTPS 憑證,甚至進階到自己架設 DNS 服務。看著這些服務在網路上跑起來,那種成就感是無可比擬的。

然而,在這條「自託管 (Self-hosting)」的路上,總有一座公認難以跨越的高山,那就是—— Mail Server

比起 Web Server,架設 Mail Server 的難度幾乎是指數級上升的。它不僅僅是安裝軟體那麼簡單,你還得面對繁瑣的設定檔、複雜的 DNS 驗證(SPF, DKIM, DMARC)、以及如何避免自己的信件被 Gmail 或 Outlook 歸類為垃圾郵件。我曾經無數次在設定檔的迷宮中打轉,或者看著 Log 檔裡的錯誤訊息感到挫折。

這正是我寫這系列文章的初衷。

我不希望這只是一篇充滿「複製貼上」指令的教學。這系列文章的目標,是幫助像我這樣非科班出身、但充滿熱情的 Linux 愛好者,不僅是「照著做」,更能真正理解 Mail Server 的運作原理與架構。

為了讓這套系統更具備實用性與靈活性,我們不會使用傳統的 Linux 系統帳號來收發信,而是挑戰業界標準的**「虛擬使用者 (Virtual Users)」**架構——利用 MariaDB (MySQL) 資料庫來管理我們的網域、使用者與別名。這意味著未來你要新增信箱、修改密碼、甚至是多網域託管,都只需要修改資料庫,而無需更動系統核心設定。

最後,做個小小的「行前提醒」:

這系列文章是特別寫給已經對 Linux 伺服器運作有一定概念的朋友。如果你已經親手架設過 Web Server、熟悉 DNS 解析原理,並且對 SSH 指令列操作感到自在,那麼你就是這篇文章的最佳讀者。為了讓教學更流暢,我們將跳過基礎的 Linux 操作說明(例如如何使用 vim/nano 編輯檔案、基本的檔案權限管理等),直接切入 Mail Server 的核心配置,讓你把寶貴的精力集中在攻克這個最艱難的挑戰上。

如果你準備好了,請跟著我一起開始這趟旅程。

第一章:架構規劃與環境準備

第二章:基礎建設篇——DNS、SSL 與資料庫

第三章:郵差的武裝——安裝 Postfix 並連接資料庫

第四章:安裝與設定 Dovecot (最後一塊拼圖)。

第五章:驗收時刻——全流程測試

第六章:設定 AWS SES Relay (讓信件使命必達)

小型伺器記憶體不足解決方案 –AWS EC2 伺服器設定swap交換空間

我自己喜歡架設各種網路服務供自己自娛自樂,在一台AWS EC2虛擬機上上架設了 Nextcloud, WordPress, Postfix, Dovecot, MariaDB, Nginx, 等等的服務。由於我的機器只有1GB的ram, 常常會碰到記憶體不足MariaDB資料庫崩潰的情況。這時如果設定好swap交換空間,就能大大降低服務中斷的情況。雖然使用硬碟當成swap會降低快取的效能,不過因為是自用,這點效能降低換取服務不中斷,還是很划算的!

首先,你要在EC2 頁面上新增個磁盤空間,大小就設定為記憶體的兩倍就好。像我就是設成2GB。 接下來請把這個新建好的空間掛載(attach)到你的伺服器上。這些設定都在EC2 的界面上就能操作完成,我就不多展示了。

這時用SSH連線進入你的純文字後台,輸入

lsblk

你就會看見你新增的磁區

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS

nvme0n1     259:0    0    2G  0 disk
nvme1n1     259:1    0   15G  0 disk
└─nvme1n1p1 259:2    0   15G  0 part /

這是我的例子,其中nvme0n1就是我新增要用作SWAP的磁區。這時請輸入

sudo mkswap /dev/nvme0n1

其中nvme0n1請代換成你新增磁區的代號

然後再輸入

sudo swapon /dev/nvme0n1

如果這時你用 lsblk 看到

NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS

nvme0n1     259:0    0    2G  0 disk [SWAP]

在MOUNTPOINTS 有看到[SWAP] 就表示你已經將新增的磁區掛載上了。

此時你可以用 top 指令來看看是否swap有在運作

top

如果你看到下面這一行就代表成功了

MiB Swap:   2048.0 total,   2030.5 free,     17.5 used.    235.1 avail Mem

其中total 前面要顯示你新掛載磁區的大小才是正確的,掛載失敗total會顯示0

最後你要將開機就掛載設定好。

這時最好使用UUID 來掛載磁區,請用以下指令來查你剛掛上的磁區的UUID

sudo blkid

找到你剛掛上的磁區的UUID

接著請輸入

sudo nano /etc/fstab

並新增下面這一行

UUID=”YOURUUIDHERE” none swap sw 0 0

Ctrl + X 存檔。

這裡記得把雙引號中間的字串改成你自己的UUID,不然每次重開機都會出問題。

純IPv6伺服器如何與純IPv4伺服器建立連線

今年(2024)早些時候,Amazon AWS開始對所有的固定IP (IPv4)收費,一個月一個IP 要收$6,比我用的Amazon  Elastic Compute Cloud (EC2)都貴了。由於我只是架設私人使用的一些雲端服務,這筆費用能省就省。為了能完全擺脫IPv4,著實花了不少時間修改設定,包含DNS、強制EC2不獲取 public IPv4 (是的,就算是系統指派給你的外部IP,只要是public IPv4,都是要收費的…)等等,

但是其中最頭痛的當屬如何讓我的伺服器能與純IPv4的伺服器溝通。例如,wordpress的官網(wordpress.org)就只有IPv4,所以我的這個個人網站就無法連上wordpress官網進行更新了。在查了無數的資料後,我找到了一個解決方案:Public NAT64 service。這是一個由個人提供的DNS64 + NAT64服務。他的網站是

https://nat64.net

目前有一些大公司有提供DNS64服務,例如google,這服務能讓IPv6的伺服器能夠”找到/看到”純IPv4的伺服器。但是如果一個純IPv6的伺服器想與純IPv4的伺服器提供的服務建立連結,那就會需要NAT64。上面的網站提供了多個DNS64+NAT64 的服務位址,還是免費的!我試用了之後,發現不但Wordpress的更新正常了,這些DNS64+NAT64的名稱伺服器 (name server)也能用在一些對純IPv6伺服器不支援的服務上。例如Amazon Web Services (AWS) 提供的Amazon Simple Email Service (SES)。純IPv6的伺服器是無法與Amazon SES建立連結進而使用這項服務的。

以我自己的理解,DNS64服務可以幫助純IPv6伺服器查詢到純IPv4的位址 (一般DNS無法做到),NAT64則是能在得知這個IPv4位址後,與其建立連結,交換資訊。所以如果需要與只提供IPv4的伺服器建立連結 (例如瀏覽網頁),那這兩者缺一不可。如果想要了解更多信息,可以參考 https://docs.aws.amazon.com/zh_tw/vpc/latest/userguide/nat-gateway-nat64-dns64.html

下面我把我的操作流程分享給大家,我用的是AWS的Ubuntu,所以會以這個舉例,如果你用的是其他服務,可能會有差異,不過重點就是指定你的伺服器使用上面這網站提供的DNS64+NAT64的名稱伺服器。

為了取代ubuntu原本的DNS設定,你要先到 /etc/netplan裡

cd /etc/netplan

我沒有任何檔案在這資料夾中,所以我要新增一個檔案

sudo vi 99-custom-dns.yaml

在檔案中寫入下面的內容:

network:
    version: 2
    ethernets:
        eth0:
            nameservers:
              addresses: [2a01:4f8:c2c:123f::1, 2a00:1098:2c::1]
            dhcp4-overrides:
                    use-dns: false

這裡的eth0是你的網卡代號,如果你只有一張網卡,大概也是eth0,不過請照你的實際情況修改。我這裡只放了兩個名稱伺服器,你想要多放也是可以的。

接下來請執行下面的指令來把這些設定寫入並覆蓋原本的DNS設定。

sudo netplan generate

這時請重啟你的服務器來讓設定生效

sudo reboot

這時可以用下面指令來查看設定是否生效,一樣記得把eth0改成你的網卡的代號

sudo resolvectl status eth0

如果你能找到像下面這樣的描述,就是成功了

Current DNS Server: 2a01:4f8:c2c:123f::1

最後要感謝一下網路上這些願意免費提供服務的好心人!

參考資料:

https://nat64.net

https://docs.aws.amazon.com/zh_tw/vpc/latest/userguide/nat-gateway-nat64-dns64.html

https://repost.aws/knowledge-center/ec2-static-dns-ubuntu-debian

推薦雲端硬碟掛載軟體 ExpanDrive

好久沒有寫文章了。這次想要來推薦一款將雲端硬碟掛載並當做本地資料夾的軟體 ExpanDrive。

不知道有多少人跟我一樣,擁有不只一個雲端硬碟的帳號。我主要在用的有Google Drive和自己架設的Nextcloud。我原本只有一個現在學校提供的Google Drive 無限容量的空間,所以我用google 自家出的Backup & Sync 軟體來同步我的雲端空間到本地。最近成功大學開始提供畢業校友無限空間的Google Drive,我就開始遇到同步的問題了。

受限於Backup & Sync,我不能同時同步兩個帳號,所以就開始尋找可以同時同步兩個以上帳號的解決方案。我找到可以試用的兩大熱門雲端硬碟掛載軟體是NetDriveExpanDrive。 先來說說這類軟體共同的優點:

  1. 可以同時同步多個帳號:有些人可能需要同時同步同一家雲端硬碟的不同帳號,而通常這類服務供應商的軟體都只能讓你同時同步一個帳號,像我有兩個無限容量的Google Drive,一個是工作用,一個是放私人照片檔案。如果只用Backup & Sync 我就只能選擇其中一個帳號與本機同步,另一個帳號要透過瀏覽器來上傳與下載,很不方便。
  2. 不佔硬碟空間:尤其在台灣,現在很多學校都開始提供校友無限空間的Google Drive,這種情形下,我是很少刪檔案了,寧願把檔案放在雲端空間的某個角落就怕刪了後悔找不回來,這時候如果全部都要存在本機,會佔用很多的空間。家中的桌機還不一定有問題,如果想在筆電上也享受隨時存取的便利,這類軟體就非常有用了。
  3. 操作直覺:NetDrive 跟ExpanDrive都是將雲端硬碟當做外接硬碟一樣的掛載在電腦上,所以在存取檔案的時候,就跟在存取本地檔案一樣直覺,完全沒有學習曲線。

其實這類的軟體功能大同小異,可能在快取技術上各有自己的邏輯,不過對於使用者來說未必能感覺出來。另外因為這類軟體幾乎都是只同步檔案列表,當你真的要開啟某個檔案時才將該檔案下載到本地,所以多少都有點延遲。試用後我可能會使用ExpanDrive,下面列出我最後選擇ExpanDrive的原因,如果你需要下面兩個功能,那ExpanDrive是目前最好的選擇:

  1. 在所有功能類似的軟體中有著最強的跨平台能力:ExpanDrive可以在Windows, MacOS、和Linux上使用。同時支援三個平台的軟體是很少見的,因為要維護三種版本是很花資源的事,沒有對開源的Linux的愛,或是客群真的很大,我想很少公司會支援Linux版本。下面我截圖了三個平台上的ExpanDrive運作時的畫面(我三個平台都有在用),操作起來幾乎沒有區別,真的是非常強大了。
Windows 10
MacOS
Ubuntu 20.04

其中可以發現,Windows 10的中文支援是最差的 , 成大兩字顯示成兩個問號。

2. 選擇將特定檔案或資料夾存於本機(非快取,是下載至本機)。這個功能對我來說是非常有用的。我常常需要用Matlab等軟體來分析數據,每個要分析的檔案大小大約是數Mb。我會需要用程式批次處理(幾十到上百個檔案),而如果該檔案還沒被下載下來,整個分析數據的流程會被下載檔案這個動作拖慢。如果可以事先將要處理的檔案下載至本機,當要開始工作時就不會被下載檔案這件事搞的心情很差。雖然我很少剪片或處理相片,不過我相信這類工作如果能將檔案事先下載至本機都能讓工作更順暢。這個功能目前只在Windows 跟MacOS 上才有,我問過他們的客服,未來也會在Linux上實現這個功能。要實現本地存取也是非常簡單,就在右鍵的選單中就能直接操作,也可以反向操作(選擇不要本地存取)。下面是在MacOS 上的操作畫面,這功能在MacOS 上是最漂亮的,在資料夾或檔案的右下角會有一個大大的圖示告訴你這檔案目前的狀態。一朵雲表示檔案在雲端,一個綠色勾勾代表檔案被下載在本機了。Windows上則要在右鍵選單中確認檔案目前的狀態是在本機或是在雲端,希望他們能把MacOS 上的顯示方式搬到其他平台。

ExpanDrive只提供買斷的方式,一個授權是$49.95,終身免費升級再加$37.95。台灣我發現阿榮福利味居然有代理ExpanDrive,算一算比找官方買還便宜!而官方網站則是有提供七折的教育優惠。我覺得這類軟體是幾乎都會長期使用的,訂閱制是讓你還拿不定主意時用較低的價錢多試用一陣子,真的要用還是要買斷並買終身免費升級才划算。NetDrive 則提供訂閱一年$19.99,買斷則是$99。這樣算起來用超過五年訂閱就會比買斷還貴了。結論,試用後如果想買,直上買斷+終身免費升級最划算。如果你有發現更好用,或更便宜的決解方案,請留言給我建議,謝謝!

推薦筆記軟體 – Notion (二)

UPDATE: 感謝大家的愛護,我的推廣碼已經達到推薦上限,我已經無法拿到更多的試用額度了,我開放留言讓大家留下自己的推廣碼!另外現在Notion開放給學生教育工作者免費使用,所以我也不需要付錢使用了!

幾個月前我寫了一篇文章推薦Notion,當時只介紹了有關收集、編輯網路上找到的文章,以及這個軟體對於程式碼的友善。沒想到真的有人用我的推廣碼試用了這個軟體!很感動!在使用這個軟體的過程中,我也在網路上看了一些Youtuber介紹這個軟體。所以就想再多分享一些。如果你想試用Notion, 歡迎使用我的推廣碼可以使用留言裡的推廣碼(如果有的話), 你會得到10美金的試用額度,他會得到5美金。如果你完成Notion提供的一些小任務,還能得到另外26美金。Notion月費 $5,年費$48,所以這些獎勵相當於讓你免費使用全功能七個月左右。另外我會建議不急著把這$36 花掉,因為免費帳號已經可以試用絕大部份的功能了,等一定會用到付費功能再開始使用這$36。

首先我推薦下面這個youtuber的介紹,主要是介紹如何將Notion打造成一個個人的入口網站。

這是英文的介紹,可以順便練練聽力!如果聽不太懂也沒關係,看圖說故事也可以抓到很多重點!這個Youtuber甚至用Notion處理他的個人待辦事項,不過我覺得Todoist更適合做待辦事項軟體。而且他們針對學生以及教育工作者提供很高的折扣,值得一試!

下面這個圖是我在聽了這個youtuber介紹後自己建立的入口頁面。

我的美術天份不是很好,所以在顏色調配方面可能不太協調,我相信大家都能做出更美的入口頁面的!

接下來我要介紹一下一些細節,讓大家在做自己的入口頁面的時候可以少走一些彎路。有些也是參考其他人的做法的!

要做一個入口頁面,第一步就是建立一個空白的頁面。這個就是在最左邊的地方,private旁邊點那個加號就行了。

建立好後,可以在該頁面的最上面找到add cover選項,Notion 內建了非常多漂亮的圖片可以當你的封面,你也可以自己上傳自己的圖來當封面。如果這時候你已經有其他建立好的頁面,現在要整合進這個個人主頁,做法也很簡單,在右邊的private page那,將想要移動的頁面拖曳進這個剛建立好的頁面即可!跟你在你自己的電腦中移動資料夾一樣!

在封面的下面,是我自己放的一句金句來激厲自己,區塊的種類是”Quote”。這樣的文字會在最前面有的條直的粗線,代表這句話是直接引用於其他人的。接在Quote下面的就是我的Inbox了。這個是一個收集站,我在網路上用notion的外掛(插件)收集到的文章就是直接存到這個連結裡。點Inbox進去後就會看到一篇一篇的文章。如果你想要寫一些筆記,或是待辦事項,這個Inbox也可以是你所有想收集的資訊的第一站。等有時間的時候,再從你的Inbox裡面把東西歸到合適的資料夾中,一樣就是拖曳就行。

接下來就是如何讓所有的頁面排成你想要的結構。下面我自己錄了一段,看一下就知道一些小技巧,主要是如何建立兩列的目錄結構:

剩下的就是發揮大家的創意了!你可以嘗試各種排列,讓你的入口面頁賞心悅目!

利用免費的Google Cloud來建立私有雲(三)

更新:今天google 寄了一封信給用戶,從明年一月起,固定ip 要開始收費了。每個小時是0.004,這樣算起來就完全不划算了。我晚點會寫一篇教學文,教如何用 no-ip的服務來避免使用固定ip。

這是本系列的最後一篇文章,前面兩篇文章我整理了如何申請免費的Google Cloud伺服器,並用SSH連線進去。還有如何使用Snap來安裝Nextcloud。這篇文章要說的是如何讓自己的Nextcloud利用HTTPS安全連線來保護自己的服務和備份系統。用Snap安裝的Nexcloud要用HTTPS連線設定上非常簡單,只要先輸入下面這行指令確定Nextcloud服務是開啟的:

sudo snap start nextcloud

然後再輸入下面這行:

sudo nextcloud.enable-https lets-encrypt

系統會要求你輸入你的信箱做為日後出問題時的連絡方式,還有你想要設定HTTPS連線的網址。然後,就沒有然後了!這樣就設定完畢!現在你可以試試用https://開頭來連到你自己專屬的雲端硬碟了!

除了連線時的安全,你的資料的安全也很重要,誰都難保每一次系統更新都是順利的,也難保你哪天新血來潮想安裝什麼新軟體或服務,結果把電腦搞掛了。所以定期備份你的系統和資料也是很重要的。這點Google Cloud 也有很好的解決方案。在Computer Engine服務下,有一個快照的選項,裡面你可以建立快照排程,地區請選你的伺服器所在的地區,我建議快照位置選區域就夠了,如果你希望你的伺服器所在地區突然整個掛點的情況,你可以在其他區域馬上恢復你的服務,才選擇多地區,我想以自用來說,區域備份已經夠了。排程頻率要看你對還原的要求有多高,我自己是每天備份,並只留三天的備份。由於Google Cloud 的快照是差異備份,所以如果你的資料變動不大,每次備份的大小其實不會太大。另外要提醒的是,快照只有頭5 GB 是免費的,所以這部份是(幾乎)一定會被收取一些費用的,超過免費額度後每GB是美金0.026。所以如果你追求完全免費,大可以不做任何備份。

希望這系列的文章可以幫到一些人,如果有任何問題也歡迎跟我交流!

利用免費的Google Cloud來建立私有雲(二)

雖然不是必備,不過如果希望自己架設的私有雲可以比較安全,且透過一個網址被訪問,那一個網域名稱就很重要了!我自己是每年花$10美金買了一個網址,因為我有架設eMail server,這個需要許多進階的DNS服務,如果只是要架私有雲,那先找一個免費的網域名稱就可以了!我在電腦王阿達的網站上找到一個免費的選擇,大家可以參考一下,這種免費的通常限制都很多,可是如果只是私有雲的話,應該不會碰到什麼問題。有了網址,就可以將這個網址設定指向之前申請的固定IP,之後Nextcloud 的設定都可以使用你申請的網址。

有了網址以後,接下來就是要安裝Nextcloud了。這裡我建議直接用Nextcloud官方的snap 一鍵安裝。簡單到你的下巴會掉下來。

這個教學是按照這個網頁安裝的,請先修改下面兩個檔案,把電腦的hostname 設定好:

vim /etc/hosts

在這個檔案最前面加一行

123.123.123.123 your.domain.name  

請把數字的部份改成你自己的固定ip,your.domain. name改成你申請的domain name。接下來修改hostname這個檔案:

vim /etc/hostname

在最上面加上你的domain name。

執行下面這個指令來刷新hostname

hostname -F /etc/hostname

做完上面的動作,然後輸入下面三行指令:

sudo apt-get update
sudo apt install snapd
sudo snap install nextcloud

大功告成!現在你可以用你申請的網域名稱從瀏覽器進到你剛架好的Nextcloud 了。到這你可以開始設定你的root帳號,並且開始使用你的個人雲,Nextcloud幾乎在所有平台都有同步軟體,你可以像使用Dropbox一樣的使用它!用snap 安裝Nextcloud還有一個好處,每個服務都是由snap 直接控制,所以如果你要暫停或重新開始Nextcloud的服務,只需要用下面的命令:

sudo snap stop nextcloud #暫停
sudo snap start nextcloud # 開始

如果你想要更新Nextcloud到新的版本,也推薦使用snap 指令

sudo snap refresh nextcloud

但是!目前你架好的這個Nexcloud是用不安全的http連線,我建議要裝上certbot這個免費的https 加密服務來保護你的帳號密碼, 另外你還應該要讓系統每天自動幫你備份整個硬碟,以防你不小心把系統玩壞了,或是主硬碟無預警掛點。我會在下一篇文章教學這個部 份。