mailcow 完整建置指南:在 Ubuntu Server 上打造專業郵件伺服器

本篇文章更新時間:2026/02/07
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知或向一介資男的 LINE 社群反應。
如果本站內容對你有幫助,歡迎贊助支持


內容目錄

一、前言:為什麼選擇 mailcow?

自架郵件伺服器的動機

在雲端服務當道的時代,為什麼還要自己架設郵件伺服器?以下幾個理由值得考慮:

  • 隱私掌控:你的郵件資料完全由自己保管,不經過第三方服務商。對於處理敏感業務資訊的企業或個人來說,這是最重要的考量。
  • 完全控制權:你可以自訂過濾規則、配額、網域數量,不受服務商方案限制。需要 100 個別名?沒問題。想要自訂反垃圾郵件規則?隨你設定。
  • 長期成本優勢:一台 VPS 每月幾百元台幣就能服務數十個信箱,相比商業方案每人每月的費用,規模越大省越多。
  • 學習價值:深入理解電子郵件的運作原理,包括 SMTP、DNS、加密、反垃圾郵件等核心網路技術。

mailcow: dockerized 是什麼?

mailcow: dockerized 是一套基於 Docker 容器的完整郵件伺服器解決方案。它把架設郵件伺服器需要的所有元件打包在一起,透過 Docker Compose 一鍵部署。你不需要手動設定每個元件的組態檔,mailcow 已經幫你處理好元件之間的串接。

mailcow 的核心元件包括:

元件 角色 說明
Postfix MTA(郵件傳輸代理) 負責郵件的發送與接收,是 SMTP 協定的實作
Dovecot MDA(郵件投遞代理) 負責郵件儲存與 IMAP/POP3 存取,讓用戶端讀取信件
Rspamd 反垃圾郵件 高效能的垃圾郵件過濾器,取代傳統的 SpamAssassin
ClamAV 防毒掃描 掃描郵件附件中的惡意程式(可選擇停用以節省資源)
SOGo Webmail / 群組協作 提供網頁版郵件介面,支援行事曆和通訊錄
Unbound DNS 解析器 內建的 DNS 快取解析器,支援 DNSSEC 驗證
Nginx Web 伺服器 提供管理介面和 Webmail 的 HTTPS 存取
MariaDB 資料庫 儲存使用者帳號、網域設定等結構化資料
Redis 快取 為 Rspamd 和其他元件提供高速快取
Olefy / Oletools 文件分析 分析 Office 文件中的巨集等潛在威脅
acme-mailcow SSL 憑證 自動申請和更新 Let's Encrypt SSL 憑證
Netfilter 防護 類似 Fail2Ban 的暴力破解防護機制
Watchdog 監控 監控各容器健康狀態並發送告警

適用情境 vs 不適用情境

適合使用 mailcow 的情境:

  • 中小企業需要自主管理的郵件系統
  • 個人或團隊想要完全掌控郵件隱私
  • 已有 VPS 或專用主機,想充分利用資源
  • 需要多網域郵件代管服務

不適合的情境:

  • VPS 供應商封鎖了 Port 25(部分供應商預設封鎖,需申請開通)
  • 僅需一兩個信箱,用 Google Workspace 或 Zoho Mail 更省事
  • 沒有基本的 Linux 和 Docker 知識且不願學習
  • 使用 NAS(Synology/QNAP)、OpenVZ 或 LXC 容器等不支援的環境

二、環境準備與系統需求

硬體需求

mailcow 對系統資源有一定要求,特別是 ClamAV 防毒引擎會消耗較多記憶體:

項目 最低需求 建議配置(5-10 用戶) 進階配置(ActiveSync + 大量連線)
CPU 1 GHz 2+ 核心 4+ 核心
記憶體 6 GiB + 1 GiB swap 8 GiB 16 GiB
磁碟 20 GiB 40+ GiB SSD 100+ GiB SSD

省資源小技巧:如果記憶體有限,可以在 mailcow.conf 中設定 SKIP_CLAMD=y 停用 ClamAV 防毒(約省 1.5-2 GiB RAM)以及 SKIP_FTS=y 停用全文搜尋(Flatcurve/Solr)。這兩個元件是最吃資源的,對小規模使用來說停用影響不大。

作業系統與架構

  • 推薦:Ubuntu Server 22.04 LTS 或 24.04 LTS
  • 支援架構:x86_64(amd64)和 ARM64(aarch64)
  • 不支援的環境:Synology/QNAP NAS、OpenVZ 容器、LXC 非特權容器(Docker 需要完整的核心支援)

時間同步確認

郵件伺服器對時間準確性要求很高,特別是啟用 TOTP 雙重認證時,時間偏差超過 30 秒就會導致驗證碼失效。執行以下指令確認 NTP 同步狀態:

timedatectl status

確認輸出中 System clock synchronized: yesNTP service: active。如果未啟用:

timedatectl set-ntp on

安裝必要軟體

首先更新系統並安裝 mailcow 安裝腳本所需的基礎工具:

# 更新套件清單並安裝基礎工具
apt update && apt install -y git openssl curl gawk coreutils grep jq

這些工具的用途:

  • git:下載 mailcow 原始碼和後續更新
  • openssl:SSL 憑證操作和驗證
  • curl:下載檔案和 API 測試
  • gawkcoreutilsgrepjq:安裝與管理腳本的相依工具

安裝 Docker

mailcow 需要 Docker 24.0.0 或更新版本。使用官方安裝腳本是最簡單的方式:

# 使用 Docker 官方安裝腳本
curl -sSL https://get.docker.com/ | CHANNEL=stable sh

# 設定 Docker 開機自動啟動並立即啟動
systemctl enable --now docker

# 驗證安裝版本
docker version

重要:不要使用 Ubuntu 預設倉庫中的 docker.io 套件,版本通常較舊。請使用 Docker 官方倉庫安裝。

安裝 Docker Compose Plugin

mailcow 使用 Docker Compose v2(以 docker compose 指令操作,注意中間是空格不是連字號):

# 安裝 Docker Compose 外掛
apt install -y docker-compose-plugin

# 驗證版本
docker compose version

必要埠號

以下埠號必須未被其他服務佔用,且防火牆(如有)需放行:

埠號 協定 用途 說明
25 TCP SMTP 接收來自其他郵件伺服器的信件(必須開放
465 TCP SMTPS 加密的 SMTP 提交(隱式 TLS)
587 TCP Submission 用戶端寄信用的 SMTP 提交(STARTTLS)
143 TCP IMAP 用戶端讀信(STARTTLS)
993 TCP IMAPS 用戶端讀信(隱式 TLS,最常用
110 TCP POP3 用戶端讀信(較舊的協定)
995 TCP POP3S 加密的 POP3
4190 TCP ManageSieve 伺服器端郵件過濾規則管理
80 TCP HTTP Let's Encrypt 驗證和 HTTP 重導向
443 TCP HTTPS Web 管理介面和 Webmail

快速檢查埠號是否被佔用:

ss -tlnp | grep -E ':(25|465|587|143|993|110|995|4190|80|443)\s'

防火牆注意事項

Docker 會直接操作 iptables 規則,繞過 ufwfirewalld 等前端工具。這意味著即使你在 ufw 中封鎖了某個埠號,Docker 映射的埠號仍然可以被外部存取。

建議做法

  • 如果這台主機專門做郵件伺服器,可以直接停用 ufw:ufw disable
  • 如果需要防火牆,使用 Docker 的 DOCKER-USER iptables chain 來管理規則
  • 或者透過雲端供應商的安全群組(Security Group)來管理存取控制

三、DNS 設定(最關鍵的步驟)

為什麼 DNS 設定至關重要

DNS 設定是自架郵件伺服器成敗的關鍵。設定不正確的結果就是:你寄出的信直接進入對方的垃圾郵件匣,甚至被拒收。這是因為收件伺服器會透過 DNS 記錄來驗證你的郵件伺服器身份。

以下說明假設你的郵件伺服器主機名稱(FQDN)為 mail.example.com,請替換為你自己的域名。

必要 DNS 記錄

記錄類型 名稱 說明
A mail.example.com 你的伺服器 IPv4 郵件伺服器的 IP 位址
AAAA mail.example.com 你的伺服器 IPv6 如有 IPv6 才需要設定
MX example.com 10 mail.example.com 告訴其他伺服器「寄給 example.com 的信要送到 mail.example.com」
TXT (SPF) example.com v=spf1 mx a -all 聲明「只有 MX 和 A 記錄指向的 IP 可以代表此域名寄信」
TXT (DKIM) dkim._domainkey.example.com (安裝後從 UI 取得) 郵件數位簽章的公鑰
TXT (DMARC) _dmarc.example.com v=DMARC1; p=reject; rua=mailto:[email protected] 告訴收件伺服器如何處理驗證失敗的郵件
CNAME autodiscover.example.com mail.example.com Outlook 等用戶端自動設定
CNAME autoconfig.example.com mail.example.com Thunderbird 等用戶端自動設定

SPF、DKIM、DMARC 詳解

這三個機制合稱為「郵件驗證三兄弟」,是現代郵件伺服器的必備設定:

SPF(Sender Policy Framework):在 DNS 中宣告哪些 IP 有權代表你的域名寄信。收件伺服器收到信後,會查詢寄件域名的 SPF 記錄,比對寄件 IP 是否在授權清單中。

# 建議的 SPF 記錄(-all 表示嚴格模式,未授權的 IP 寄出的信應被拒絕)
v=spf1 mx a -all

# 如果你同時用 Google Workspace 或其他服務寄信:
v=spf1 mx a include:_spf.google.com -all

DKIM(DomainKeys Identified Mail):對每封寄出的信進行數位簽章。收件伺服器用你 DNS 中的公鑰來驗證簽章,確認信件未被竄改。DKIM 金鑰在 mailcow 安裝完成後,從管理介面生成並取得 DNS 記錄值。

DMARC(Domain-based Message Authentication, Reporting & Conformance):整合 SPF 和 DKIM 的驗證結果,並告訴收件伺服器當驗證失敗時該怎麼做(放行/隔離/拒絕)。同時可以設定報告接收信箱,收到其他伺服器回傳的驗證報告。

# DMARC 記錄說明
v=DMARC1;          # 版本
p=reject;           # 政策:reject(拒絕)、quarantine(隔離)、none(僅報告)
rua=mailto:[email protected]  # 彙總報告接收信箱

建議:初期可先用 p=none 觀察報告,確認正常運作後再改為 p=quarantinep=reject

PTR 反解記錄

PTR 記錄(反向 DNS)是將 IP 位址反查回主機名稱。這是郵件伺服器信譽的重要指標,幾乎所有主流郵件服務都會檢查 PTR 記錄

PTR 記錄必須由你的 VPS/主機供應商設定(因為 IP 位址是他們管理的)。請聯繫供應商,要求將你伺服器 IP 的 PTR 記錄設定為 mail.example.com(必須與 MAILCOW_HOSTNAME 一致)。

大多數 VPS 供應商(如 Vultr、Linode、DigitalOcean、Hetzner)都可以在管理面板中自行設定 PTR 記錄。

SRV 記錄(進階)

SRV 記錄可讓部分郵件用戶端自動發現伺服器設定,但並非所有用戶端都支援:

_autodiscover._tcp.example.com  SRV  0 1 443 mail.example.com
_imaps._tcp.example.com         SRV  0 1 993 mail.example.com
_submission._tcp.example.com    SRV  0 1 587 mail.example.com

DNS 驗證

設定完成後,使用以下工具驗證:

  • MX Toolbox:檢查 MX、SPF、DKIM、DMARC、PTR 等所有記錄
  • mail-tester.com:寄一封測試信到它提供的地址,取得 1-10 分的評分和改善建議
  • 命令列工具:dig MX example.comdig TXT example.com

四、安裝 mailcow

下載 mailcow

建議安裝在 /opt 目錄下。umask 0022 確保建立的檔案權限正確:

# 設定正確的檔案權限遮罩
umask 0022

# 切換到 /opt 目錄
cd /opt

# 下載 mailcow
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized

產生設定檔

./generate_config.sh

腳本會詢問以下問題:

  1. Mail server hostname (FQDN):輸入你的郵件伺服器完整域名,例如 mail.example.com。這個值會成為 MAILCOW_HOSTNAME,必須與 DNS A 記錄和 PTR 記錄一致。
  2. Timezone:選擇你的時區,例如 Asia/Taipei

腳本會自動產生 mailcow.conf 設定檔。

mailcow.conf 重要參數詳解

產生的 mailcow.conf 中有幾個關鍵參數值得了解:

# 郵件伺服器主機名稱(最重要的設定,不要在安裝後更改)
MAILCOW_HOSTNAME=mail.example.com

# 密碼雜湊演算法(預設 BLF-CRYPT 即 bcrypt,安全且高效)
MAILCOW_PASS_SCHEME=BLF-CRYPT

# 停用 ClamAV 防毒(省記憶體,設為 y 停用)
SKIP_CLAMD=n

# 停用全文搜尋(省記憶體,設為 y 停用)
SKIP_FTS=n

# IPv6 支援(如無 IPv6 位址請保持 n)
ENABLE_IPV6=n

# SMTP 埠號(通常不需更改)
SMTP_PORT=25

# HTTP/HTTPS 埠號(使用反向代理時需要修改,見後文)
HTTP_PORT=80
HTTP_BIND=
HTTPS_PORT=443
HTTPS_BIND=

# 額外的 SSL 憑證域名(用逗號分隔)
ADDITIONAL_SAN=

# 固定外送 IP(多 IP 主機時指定寄信用的 IP)
SNAT_TO_SOURCE=

# API 金鑰(供外部程式呼叫 mailcow API 用)
API_KEY=
API_ALLOW_FROM=

注意MAILCOW_HOSTNAME 在安裝後不應更改。如果真的需要更改,必須重新產生設定檔。

拉取映像與啟動

# 下載所有需要的 Docker 映像(首次約需下載 2-3 GB)
docker compose pull

# 以背景模式啟動所有容器
docker compose up -d

啟動過程約需 1-3 分鐘,所有容器就緒後就可以存取管理介面了。可以用以下指令確認所有容器狀態:

docker compose ps

所有容器的 STATUS 欄位應顯示 UpUp (healthy)

首次登入

開啟瀏覽器前往:

https://mail.example.com

管理介面登入資訊:

  • 網址https://mail.example.com(右上角選「管理員」登入)
  • 帳號admin
  • 密碼moohoo

⚠️ 登入後請立即更改預設密碼!前往 System → Admin accounts 修改密碼,或是直接在下拉選單中的編輯管理員功能來變更密碼。

五、SSL/TLS 憑證設定

預設行為:自動 Let's Encrypt

mailcow 內建的 acme-mailcow 容器會自動處理 Let's Encrypt SSL 憑證的申請和續期。前提是 Port 80 必須從外部可以連到你的伺服器,因為 Let's Encrypt 使用 HTTP-01 驗證方式。

預設情況下,acme 會為 MAILCOW_HOSTNAME 和所有新增的郵件域名自動申請憑證。

額外域名

如果你希望 smtp.example.comwebmail.example.com 等額外域名也包含在 SSL 憑證中,在 mailcow.conf 中設定:

ADDITIONAL_SAN=smtp.example.com,webmail.example.com,imap.example.com

修改後需要重啟 acme 容器:

docker compose restart acme-mailcow

SNI 支援

如果你託管超過 100 個網域,Let's Encrypt 單一憑證最多只能包含 100 個 SAN。啟用 SNI 模式讓每個域名使用獨立憑證:

# 在 mailcow.conf 中
ENABLE_SSL_SNI=y

使用自訂憑證

如果你使用反向代理且由反向代理處理 SSL,或者使用購買的憑證,可以停用自動憑證並手動設定:

# 在 mailcow.conf 中停用 Let's Encrypt
SKIP_LETS_ENCRYPT=y

將憑證檔案放到指定位置:

# 複製憑證(注意:不可使用 symlink,必須是實體檔案)
cp /path/to/your/fullchain.pem data/assets/ssl/cert.pem
cp /path/to/your/privkey.pem data/assets/ssl/key.pem

# 重啟相關服務
docker compose restart nginx-mailcow dovecot-mailcow postfix-mailcow

驗證憑證

安裝完成後,驗證各服務的 SSL 憑證是否正確:

# 驗證 HTTPS (443)
echo | openssl s_client -connect mail.example.com:443 -servername mail.example.com 2>/dev/null | openssl x509 -noout -dates -subject

# 驗證 IMAPS (993)
echo | openssl s_client -connect mail.example.com:993 -servername mail.example.com 2>/dev/null | openssl x509 -noout -dates -subject

# 驗證 SMTPS (465)
echo | openssl s_client -connect mail.example.com:465 -servername mail.example.com 2>/dev/null | openssl x509 -noout -dates -subject

# 驗證 SMTP STARTTLS (587)
echo | openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com 2>/dev/null | openssl x509 -noout -dates -subject

六、初始設定與郵件域管理

新增郵件域(Domain)

登入管理介面後,前往 Configuration → Mail Setup → Domains,點選 Add domain

  1. 輸入你的域名(例如 example.com
  2. 設定預設配額(每個信箱的預設容量上限)
  3. 設定最大信箱數量(0 = 無限制)
  4. 點選 Add domain and restart SOGo

設定 DKIM 簽章

這是郵件驗證三兄弟中唯一需要安裝後才能設定的

  1. 前往 Configuration → ARC/DKIM Keys
  2. 在你新增的域名旁,選擇金鑰長度(建議 2048 bit
  3. DKIM selector 保持預設 dkim
  4. 點選 Generate
  5. 複製產生的 DNS TXT 記錄值
  6. 到你的 DNS 管理面板新增 TXT 記錄:
    • 名稱:dkim._domainkey.example.com
    • 值:mailcow 產生的內容(以 v=DKIM1;k=rsa;t=s;s=email;p=... 開頭)

建立信箱(Mailbox)

前往 Configuration → Mail Setup → Mailboxes,點選 Add mailbox

  1. 輸入使用者名稱(@前面的部分)
  2. 選擇所屬域名
  3. 設定密碼(建議使用強密碼)
  4. 設定配額(0 = 使用域名預設值)
  5. 點選 Add

建立後,使用者可以用以下方式存取信箱:

  • Webmail(SOGo)https://mail.example.com/SOGo
  • IMAP 用戶端:伺服器 mail.example.com,埠號 993(SSL/TLS)
  • SMTP 寄信:伺服器 mail.example.com,埠號 587(STARTTLS)或 465(SSL/TLS)

設定別名(Alias)

前往 Configuration → Mail Setup → Aliases,可以設定:

啟用雙重認證(2FA/TOTP)

強烈建議為管理員帳號啟用 2FA:

  1. 登入管理介面
  2. 點選右上角使用者名稱 → Edit
  3. 往下找到 Two-Factor Authentication
  4. 選擇 TOTP,用手機 App(Google Authenticator、Authy 等)掃描 QR Code
  5. 輸入驗證碼確認後儲存

再次提醒:TOTP 需要伺服器時間準確,請確認第二節中的 NTP 同步設定。

七、反向代理設定(兩種情境)

情境 A:mailcow 獨立運行(不需反向代理)

如果這台主機專門做郵件伺服器,不需要和其他 Web 服務共享 Port 80/443,那麼不需要做任何額外設定。mailcow 內建的 Nginx 容器會直接處理 HTTPS 連線,acme-mailcow 會自動管理 Let's Encrypt 憑證。

這是最簡單也最推薦的部署方式。

情境 B:與現有 Nginx 反向代理共存

如果主機上已經有 Nginx(或 Apache)在運行其他網站,Port 80/443 已被佔用,就需要設定反向代理。以下以主機上已安裝 Nginx 為例。

Step 1:修改 mailcow 綁定埠號

編輯 mailcow.conf,讓 mailcow 的 Web 服務只監聽 localhost 的非標準埠號:

HTTP_PORT=8080
HTTP_BIND=127.0.0.1
HTTPS_PORT=8443
HTTPS_BIND=127.0.0.1

為什麼綁定 127.0.0.1?這樣外部無法直接存取 8080/8443 埠號,所有流量必須經過前端 Nginx 反向代理。

Step 2:設定 TRUSTED_PROXIES(如需要)

如果反向代理和 mailcow 在同一台主機上,通常不需要額外設定。但如果反向代理在不同的機器或 Docker 網路中,需要在 mailcow.conf 中設定信任的代理 IP,讓 mailcow 能正確識別用戶端的真實 IP:

# 如果反向代理在不同子網,加入其 IP 或 CIDR
# 多個值用逗號分隔
TRUSTED_PROXIES=172.22.1.1,10.0.0.0/24

Step 3:主機 Nginx 設定檔

在主機的 Nginx 中建立 mailcow 的反向代理設定:

server {
    listen 80;
    server_name mail.example.com autodiscover.example.com autoconfig.example.com;

    # HTTP 301 重導向到 HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name mail.example.com autodiscover.example.com autoconfig.example.com;

    # SSL 憑證設定(由主機管理,例如 certbot)
    ssl_certificate /etc/letsencrypt/live/mail.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mail.example.com/privkey.pem;

    # SSL 安全設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # 上傳大小限制(郵件附件)
    client_max_body_size 100m;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket 支援(SOGo 需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Buffer 設定(SOGo 需要較大的 buffer)
        proxy_buffering on;
        proxy_buffer_size 64k;
        proxy_buffers 64 512k;
        proxy_busy_buffers_size 512k;
    }

    # Microsoft ActiveSync 需要較長的超時時間
    location /Microsoft-Server-ActiveSync {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # ActiveSync 長連線,超時設定 3650 秒
        proxy_connect_timeout 3650s;
        proxy_send_timeout 3650s;
        proxy_read_timeout 3650s;

        proxy_buffering off;
    }
}

注意:使用反向代理時,SSL 憑證由主機 Nginx 管理(例如用 certbot),而非 mailcow 內建的 acme-mailcow。你需要在 mailcow.conf 中設定 SKIP_LETS_ENCRYPT=y,避免衝突。不過,mailcow 的 SMTP/IMAP 等非 HTTP 服務仍需要 SSL 憑證,可以將主機的憑證複製到 mailcow 的 data/assets/ssl/ 目錄,或者讓 acme-mailcow 繼續管理這些服務的憑證(此時 Port 80 的驗證請求需要能正確轉發到 acme-mailcow)。

Step 4:重新啟動服務

# 重啟 mailcow(讓新的埠號設定生效)
cd /opt/mailcow-dockerized
docker compose down && docker compose up -d

# 測試並重新載入主機 Nginx
nginx -t && systemctl reload nginx

八、安全強化與監控

8.1 Netfilter(內建防暴力破解)

mailcow 內建了類似 Fail2Ban 的防護機制,稱為 Netfilter。它會監控登入失敗的嘗試,自動封鎖可疑 IP。

設定位置:管理介面 → Configuration → Fail2ban parameters

主要設定項目:

  • Max. ban time (s):最長封鎖時間(預設 86400 秒 = 24 小時)
  • Ban time (s):封鎖時間,每次被封鎖會遞增(預設 3600 秒 = 1 小時)
  • Max. attempts:封鎖前允許的最大失敗次數(預設 20 次)
  • Retry window (s):在此時間窗口內累計失敗次數(預設 600 秒 = 10 分鐘)
  • Netfilter ban list:可查看當前被封鎖的 IP 清單,也可手動解除封鎖

提醒:如果你在外部使用了如 Cloudflare 等代理服務,記得將代理的 IP 段加入白名單,否則會誤封。mailcow 也支援匯出被封鎖的 IP 清單,方便整合外部防火牆。

8.2 Watchdog 監控

Watchdog 是 mailcow 的內建健康監控系統,會持續檢查各服務的運作狀態。它監控多達 16 項服務,包括:Nginx、Unbound、Redis、MariaDB、Postfix、Dovecot、ClamAV、Rspamd、SOGo、ACME 等。

mailcow.conf 中可以設定監控閾值:

# Watchdog 通知信箱(收到告警通知)
[email protected]

# 郵件佇列監控
# 當佇列信件數超過此值時告警
MAILQ_CRIT=30
# 連續超過此次數才真正發送告警(避免瞬間高峰誤報)
MAILQ_THRESHOLD=5

# Watchdog 各服務告警閾值(連續失敗次數)
WATCHDOG_NOTIFY_BAN=y

設定後重新建立 Watchdog 容器:

docker compose up -d watchdog-mailcow

8.3 Rspamd 反垃圾郵件管理

Rspamd 是 mailcow 的反垃圾郵件引擎,提供了豐富的 Web 管理介面。

存取方式https://mail.example.com/rspamd(使用管理員帳號登入)

常用功能:

  • Dashboard:查看垃圾郵件統計、通過率、拒絕率
  • History:檢視每封信的評分細節和觸發的規則
  • Symbols:管理評分規則和權重

自訂 Rspamd 設定應放在 data/conf/rspamd/local.d/ 目錄下。例如,調整歷史記錄保存數量:

# data/conf/rspamd/local.d/history_redis.conf
nrows = 2500;

設定 DMARC 彙總報告

如果你想讓 mailcow 自動發送 DMARC 報告給其他域名的管理員,需要做以下設定:

首先,建立 Rspamd 的 DMARC 設定檔:

# 建立 data/conf/rspamd/local.d/dmarc.conf
reporting {
    enabled = true;
    email = [email protected];
    domain = example.com;
    org_name = "Your Organization";
    helo = mail.example.com;
    smtp = postfix;
    smtp_port = 25;
    from_name = "DMARC Reporter";
}

接著,在 docker-compose.override.yml 中加入 Ofelia 排程器設定,讓系統每天自動發送報告:

services:
  ofelia:
    image: mcuadros/ofelia:latest
    restart: always
    depends_on:
      - rspamd-mailcow
    labels:
      ofelia.enabled: "true"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - mailcow-network

  rspamd-mailcow:
    labels:
      ofelia.enabled: "true"
      ofelia.job-exec.rspamd_dmarc_report.schedule: "0 0 2 * * *"
      ofelia.job-exec.rspamd_dmarc_report.command: "/usr/bin/rspamadm dmarc_report"
      ofelia.job-exec.rspamd_dmarc_report.no-overlap: "true"

最後建立一個專用的 [email protected] 信箱來處理退信。

8.4 ClamAV 防毒

ClamAV 預設啟用,會自動掃描所有進出的郵件附件。病毒碼定義檔會自動更新(透過 freshclam)。

如果你的伺服器記憶體有限(低於 4 GiB 可用),可以停用 ClamAV:

# 在 mailcow.conf 中
SKIP_CLAMD=y

停用後執行:

docker compose up -d

九、備份與還原策略

9.1 使用內建備份腳本

mailcow 提供了完整的備份腳本,位於 helper-scripts/backup_and_restore.sh

# 備份所有元件,並自動刪除 3 天前的舊備份
MAILCOW_BACKUP_LOCATION=/backup/mailcow \
  /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all --delete-days 3

可備份的元件包括:

  • vmail:所有信箱的郵件資料
  • crypt:加密金鑰
  • redis:Redis 資料庫(Rspamd 統計等)
  • rspamd:Rspamd 設定和學習資料
  • postfix:Postfix 設定
  • mysql:MariaDB 資料庫(帳號、域名、設定等)

也可以只備份特定元件:

# 只備份資料庫和郵件
MAILCOW_BACKUP_LOCATION=/backup/mailcow \
  /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup mysql
MAILCOW_BACKUP_LOCATION=/backup/mailcow \
  /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup vmail

啟用多執行緒加速備份:

THREADS=4 MAILCOW_BACKUP_LOCATION=/backup/mailcow \
  /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all

設定自動備份排程

使用 crontab 設定每日自動備份:

# 編輯 root 的 crontab
crontab -e

# 每天凌晨 3 點執行備份,保留 7 天
0 3 * * * MAILCOW_BACKUP_LOCATION=/backup/mailcow /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all --delete-days 7 >> /var/log/mailcow-backup.log 2>&1

9.2 還原流程

還原操作會互動式地讓你選擇要還原的元件和備份時間點:

MAILCOW_BACKUP_LOCATION=/backup/mailcow \
  /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh restore

注意:還原操作會覆蓋現有資料,建議在還原前先做一次完整備份。

9.3 Borgmatic 加密備份(進階)

對於需要異地備份的場景,mailcow 支援整合 Borgmatic(基於 BorgBackup 的自動備份工具),提供加密和去重功能。

docker-compose.override.yml 中加入 borgmatic 服務:

services:
  borgmatic-mailcow:
    image: ghcr.io/borgmatic-collective/borgmatic
    restart: always
    dns: ${IPV4_NETWORK:-172.22.1}.254
    volumes:
      - vmail-vol-1:/mnt/source/vmail:ro
      - crypt-vol-1:/mnt/source/crypt:ro
      - redis-vol-1:/mnt/source/redis:ro
      - rspamd-vol-1:/mnt/source/rspamd:ro
      - postfix-vol-1:/mnt/source/postfix:ro
      - ./data/conf/borgmatic/etc:/etc/borgmatic.d:Z
      - ./data/conf/borgmatic/ssh:/root/.ssh:Z
      - ./data/conf/borgmatic/borgmatic:/root/.borgmatic:Z
      - ./data/conf/borgmatic/cache:/root/.cache/borg:Z
    environment:
      - TZ=${TZ}
      - BORG_PASSPHRASE=你的加密密碼
    networks:
      mailcow-network:
        aliases:
          - borgmatic

你需要設定 SSH 金鑰和遠端 Borg 儲存庫,具體步驟請參考 mailcow 官方 Borgmatic 文件

9.4 遷移伺服器

有兩種方式可以將 mailcow 遷移到新伺服器:

方法一:備份 → 新機安裝 → 還原

  1. 在舊機執行完整備份
  2. 在新機安裝 mailcow(使用相同的 MAILCOW_HOSTNAME
  3. 將備份檔案複製到新機
  4. 執行還原

方法二:rsync 直接同步

  1. 在舊機停止 mailcow:docker compose down
  2. 使用 rsync 同步整個 /opt/mailcow-dockerized 目錄到新機
  3. 在新機啟動:docker compose pull && docker compose up -d

注意事項

  • 如果新舊主機架構不同(例如 x86 → ARM),rspamd 快取可能不相容,建議排除 data/conf/rspamd/local.d/ 中的快取檔案
  • 遷移後記得更新 DNS 記錄(A 記錄、PTR 記錄)
  • 如果新機 IP 不同,更新 mailcow.conf 中的 SNAT_TO_SOURCE

十、第三方整合

10.1 Roundcube Webmail

雖然 mailcow 內建 SOGo 作為 Webmail,但有些使用者偏好 Roundcube 的簡潔介面。mailcow 官方支援兩種 Roundcube 整合方式:

整合式安裝(推薦):

將 Roundcube 作為 Docker 容器加入 mailcow 的 docker-compose.override.yml

services:
  roundcube-mailcow:
    image: roundcube/roundcubemail:latest
    restart: always
    depends_on:
      - mysql-mailcow
      - dovecot-mailcow
    volumes:
      - ./data/assets/ssl:/etc/ssl/mail/:ro
      - ./data/conf/roundcube/custom/:/var/roundcube/config/custom/:ro
    environment:
      - ROUNDCUBEMAIL_DEFAULT_HOST=tls://dovecot-mailcow
      - ROUNDCUBEMAIL_DEFAULT_PORT=143
      - ROUNDCUBEMAIL_SMTP_SERVER=tls://postfix-mailcow
      - ROUNDCUBEMAIL_SMTP_PORT=587
      - ROUNDCUBEMAIL_DB_TYPE=mysql
      - ROUNDCUBEMAIL_DB_HOST=mysql-mailcow
      - ROUNDCUBEMAIL_DB_NAME=roundcubemail
      - ROUNDCUBEMAIL_DB_USER=roundcube
      - ROUNDCUBEMAIL_DB_PASSWORD=自訂一個強密碼
    networks:
      mailcow-network:
        aliases:
          - roundcube

Roundcube 的實用外掛:

  • password:允許使用者透過 mailcow API 修改密碼
  • carddav:與 SOGo 的 CardDAV 通訊錄同步
  • managesieve:管理伺服器端郵件過濾規則

10.2 Nextcloud 整合

mailcow 可以作為 Nextcloud 的 OAuth2 認證提供者,讓使用者用郵件帳號登入 Nextcloud。

在 mailcow 中設定 OAuth2 Client:

  1. 登入 mailcow 管理介面
  2. 前往 Configuration → Access → OAuth2 Clients
  3. 點選 Add OAuth2 Client
  4. 輸入:
    • Client name:Nextcloud
    • Redirect URI:https://nextcloud.example.com/apps/sociallogin/custom_oidc/mailcow
  5. 記下產生的 Client IDClient Secret

在 Nextcloud 中設定:

  1. 安裝 Social Login app
  2. 前往 管理設定 → Social login
  3. 新增 Custom OpenID Connect provider
  4. 填入:
    • Internal name:mailcow
    • Title:Mailcow
    • Authorize url:https://mail.example.com/oauth/authorize
    • Token url:https://mail.example.com/oauth/token
    • User info URL:https://mail.example.com/oauth/profile
    • Client ID 和 Client Secret:填入上一步取得的值

10.3 SOGo Webmail 客製化

SOGo 是 mailcow 預設的 Webmail 和群組協作介面,存取路徑為 https://mail.example.com/SOGo

常見的客製化項目:

  • 啟用密碼修改:在 data/conf/sogo/sogo.conf 中設定 SOGoPasswordChangeEnabled = YES;
  • 品牌客製化:替換 data/conf/sogo/ 中的 favicon 和 logo 檔案
  • 域名可見性:控制每個域名的使用者是否能看到其他域名的全域通訊錄

修改 SOGo 設定後需要重啟:

docker compose restart sogo-mailcow

十一、維護與更新

11.1 更新 mailcow

mailcow 提供了方便的更新腳本:

cd /opt/mailcow-dockerized

# 檢查是否有可用更新
./update.sh --check

# 執行更新
./update.sh

更新腳本的常用選項:

  • --check:僅檢查是否有更新,不實際執行
  • --skip-start:更新後不自動啟動容器(適合需要先修改設定的情況)
  • --stable:強制使用穩定版本
  • --nightly:使用每夜版本(不建議在正式環境使用)

如果更新後出現問題,可以回滾到之前的版本:

# 查看更新歷史
git log --oneline -20

# 回滾到指定的 commit
git checkout [commit-id]
docker compose pull
docker compose up -d

更新 Hook 腳本

mailcow 支援在更新過程中執行自訂腳本:

  • pre_commit_hook.sh:在 git commit 之前執行
  • post_commit_hook.sh:在 git commit 之後執行
  • pre_update_hook.sh:在更新開始前執行
  • post_update_hook.sh:在更新完成後執行

這些腳本放在 mailcow 根目錄下,例如可以用 post_update_hook.sh 來自動重新套用你的自訂設定。

11.2 日誌管理

查看各服務的日誌:

# 查看特定服務日誌(-f 持續追蹤)
docker compose logs -f postfix-mailcow
docker compose logs -f dovecot-mailcow
docker compose logs -f rspamd-mailcow
docker compose logs -f nginx-mailcow

# 查看所有服務日誌(最後 100 行)
docker compose logs --tail=100

設定日誌輪替(Log rotation),建立 /etc/logrotate.d/mailcow

/var/lib/docker/containers/*/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}

如果需要將日誌送到外部收集系統(如 Graylog、ELK),mailcow 支援 Graylog GELF 和 Syslog 格式的日誌輸出。

11.3 docker-compose.override.yml 最佳實踐

永遠使用 docker-compose.override.yml 來客製化設定,不要直接修改 docker-compose.yml。原因是每次更新 mailcow 時,docker-compose.yml 會被覆蓋,你的修改會遺失。

mailcow 在 helper-scripts/docker-compose.override.yml.d/ 目錄下提供了多種 override 範本,包含 Roundcube、Borgmatic 等常見整合的設定範例。

基本的 override 檔案結構:

# docker-compose.override.yml
services:
  # 覆寫現有服務的設定
  nginx-mailcow:
    # 你的自訂設定

  # 新增額外服務
  roundcube-mailcow:
    image: roundcube/roundcubemail:latest
    # ...

十二、常見問題疑難排解

寄出的信被退回或進垃圾郵件

依序檢查:

  1. PTR 記錄dig -x 你的IP 確認反解為 mail.example.com
  2. SPF 記錄dig TXT example.com 確認 SPF 記錄存在且正確
  3. DKIM:在 mailcow UI 確認 DKIM 已啟用,用 dig TXT dkim._domainkey.example.com 確認 DNS 記錄
  4. DMARCdig TXT _dmarc.example.com
  5. 寄一封信到 mail-tester.com 取得詳細評分報告

無法收信

  • 確認 Port 25 未被 ISP 封鎖(在外部用 telnet mail.example.com 25 測試)
  • 確認 MX 記錄正確指向你的伺服器
  • 檢查 Postfix 日誌:docker compose logs postfix-mailcow | tail -50
  • 確認防火牆已放行 Port 25

容器不健康或啟動失敗

# 查看所有容器狀態
docker compose ps

# 查看問題容器的日誌
docker compose logs [容器名稱]

# 強制重新建立容器
docker compose up -d --force-recreate [容器名稱]

SSL 憑證取得失敗

  • 確認 Port 80 從外部可達(Let's Encrypt HTTP-01 驗證需要)
  • 確認 DNS A 記錄已正確指向伺服器 IP
  • 檢查 acme 容器日誌:docker compose logs acme-mailcow
  • 如果使用反向代理,確認 /.well-known/acme-challenge/ 路徑能正確轉發

SOGo 登入失敗

  • 確認帳號格式為完整的電子郵件地址(例如 [email protected]
  • 如果使用了 SNAT 且更換了 IP,需要更新 SNAT_TO_SOURCE 設定
  • 檢查 SOGo 日誌:docker compose logs sogo-mailcow

mail-tester.com 分數優化

目標是 10/10 滿分。常見的扣分項目和解法:

  • SPF 未通過:檢查 SPF 記錄是否涵蓋了你的伺服器 IP
  • DKIM 未簽署:確認 DKIM 金鑰已生成且 DNS 記錄已設定
  • 無 DMARC 記錄:新增 DMARC TXT 記錄
  • PTR 不匹配:確認 PTR 記錄與 MAILCOW_HOSTNAME 一致
  • 被列入黑名單:到 Spamhaus 等網站查詢你的 IP 是否在黑名單中,如果是共享 IP 可能前一個使用者留下的問題
  • 內容問題:避免在測試信中使用過多垃圾郵件常見詞彙

十三、結語

完成後驗證清單

依照以下清單逐一確認你的郵件伺服器已正確設定:

  • ☐ 所有 Docker 容器狀態為 healthy
  • ☐ 可以透過 Webmail (SOGo) 登入
  • ☐ 可以透過 IMAP 用戶端連線讀信
  • ☐ 可以成功寄信到 Gmail、Outlook 等主流郵件服務
  • ☐ 可以成功收到來自外部的信件
  • ☐ SPF 記錄驗證通過
  • ☐ DKIM 簽章驗證通過
  • ☐ DMARC 記錄已設定
  • ☐ PTR 反解記錄正確
  • ☐ SSL 憑證在所有服務埠號上有效
  • ☐ mail-tester.com 評分達 9/10 或以上
  • ☐ 管理員密碼已從預設更改
  • ☐ 2FA 已啟用
  • ☐ 自動備份排程已設定
  • ☐ Watchdog 告警信箱已設定

後續優化方向

  • 效能調校:根據實際使用量調整 Postfix/Dovecot 的連線數限制
  • 進階安全:設定 MTA-STS(SMTP TLS 強制策略)和 DANE(DNS-based Authentication of Named Entities)
  • 監控整合:將 Watchdog 的告警整合到 Slack、Telegram 或其他通知管道
  • 信件歸檔:設定郵件保留政策和自動歸檔

參考資源

自架郵件伺服器是一項需要持續維護的工作,但 mailcow 已經大幅降低了這個門檻。定期更新、監控日誌、維護備份,你的郵件伺服器就能穩定運行。祝你架設順利!


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon