← 返回博客

自建邮件服务器 Mailu 方案分析:在阿里云上安全地收发邮件

你以为建个博客就完了,但互联网上的扫描器可不这么想。上次分析完博客安全,这次我盯上了另一个”自建”大坑——邮件服务器。


一、为什么想自建邮箱

市面上企业邮箱不少,腾讯、阿里、Google Workspace,注册就能用。但自建邮箱有几个绕不开的吸引力:

  • 数据主权:邮件内容存在自己服务器上,不经过第三方
  • 完全控制:域名、存储、规则、反垃圾策略,全在自己手里
  • 技术挑战:邮件系统涉及 DNS、TLS、SPF、DKIM、DMARC、反垃圾……搞明白了,对系统架构的理解会上一个台阶

但邮件服务器和 Web 服务不一样——它有一套自己的”潜规则”,一不小心就会进垃圾邮件箱,甚至被拉黑。


二、服务器环境

先看看我手头有什么:

项目配置
系统Rocky Linux 9.7
CPU / 内存x86_64 / 14Gi RAM
磁盘80GB SSD,剩余 41GB
公网 IP阿里云 ECS(已隐藏)
域名自有域名(已隐藏)
已有服务Nginx(HTTP,托管静态博客)+ Docker
Dockerv29.4.3,Compose v5.1.3

Docker 环境现成,磁盘空间够用,内存充裕。看起来条件不错——直到我测了一下 25 端口。


三、第一道坎:25 端口被封

测试过程

自建邮件服务器要能给别人发邮件,必须通过标准 SMTP 端口连接对方的 MX 服务器投递。我分别测了 Gmail、QQ 邮箱和 163 邮箱:

nc -v -w 5 <对方 MX 服务器地> 25
# → TIMEOUT

三个主流邮箱,全部超时。原因很明确:

阿里云 ECS 默认封禁了 25 端口的出站流量。

这是国内云厂商的通用做法——防止云服务器被当作垃圾邮件跳板。你可以提工单申请解封,但通过率不高,而且就算解封了,云服务器 IP 段的信誉也普遍偏低,发出去的邮件进垃圾箱的概率很大。

这对自建邮箱意味着什么?

方向端口阿里云限制结果
别人给我发邮件(入站)25不限✅ 只要安全组放行就行
我给别人发邮件(出站)25封禁❌ 无法直连对方 MX

所以,如果你只收不发,25 出站被封不影响。但如果要发信,就必须绕道。


四、发信的出路:587 和 465

SMTP 有三个常用端口,各有各的定位:

端口名称设计用途认证加密阿里云出站
25SMTP服务器→服务器投递可选 STARTTLS❌ 封禁
587Submission客户端→服务器提交必须强制 STARTTLS✅ 开放
465SMTPS客户端→服务器提交(隐式TLS)必须连接即 TLS✅ 开放

标准 SMTP 端口是服务器之间的”快递通道”,不需要认证,靠 IP 信誉和 SPF/DKIM 建立信任。但因为它没有认证机制,也成了垃圾邮件的重灾区——所以云厂商直接封了。

Submission 和 SMTPS 是用户提交邮件的”柜台窗口”,必须登录认证,全程加密。这两个端口阿里云完全放行。

所以自建邮箱的发信方案就一条路:本地邮件服务器通过 587/465 端口连接到 SMTP 中继服务,由中继代投。


五、SMTP 中继服务对比

服务587465免费额度注册门槛适合场景
SMTP2GO1,000 封/月邮箱注册即用个人首选,开箱即用
SendGrid100 封/天需信用卡验证开发者友好
Amazon SES62,000 封/月AWS 账号 + 审核量大最便宜
Brevo300 封/天邮箱注册欧洲隐私合规
Mailgun前 3 月 5,000 封信用卡开发者 API 强
阿里云邮件推送200 封/天阿里云账号国内生态

个人用量一个月几十封到几百封,SMTP2GO 的 1,000 封免费额度绰绰有余。配置上就是在 Mailu 的 .env 里加三行:

RELAYHOST=smtp.<中继服务域名>:587
RELAY_LOGIN=your_user
RELAY_PASSWORD=***

六、Mailu 方案分析

为什么选 Mailu

自建邮件服务器有几个主流选择:

方案复杂度资源占用Web 面板适合
Mailcow~3.5GB✅ SOGo多人多域名
Mailu~500MB-1.5GB✅ SnappyMail个人/小团队
Postfix + Dovecot 手工<200MB技术极客
Modoboa~1GB中等规模

我选 Mailu 的理由:

  • 轻量:去掉 ClamAV 只要 ~500MB 内存,对主流配置的云服务器毫无压力
  • Docker 原生:一套 docker-compose.yml 搞定,和我现有环境完全匹配
  • 功能完整:Postfix + Dovecot + Rspamd + Webmail + 管理面板,该有的都有
  • 文档清晰:官方文档覆盖从 DNS 配置到中继设置的完整流程

Mailu 架构

Mailu 用 Docker Compose 部署,核心容器如下:

┌─────────────────────────────────────────┐
│              docker compose              │
│                                          │
│  frontend (Nginx)    ← HTTP/S, SMTP, IMAP│
│       │                                  │
│       ├── admin      ← Web 管理面板       │
│       ├── webmail    ← Roundcube/Snappy   │
│       ├── postfix    ← SMTP 收信          │
│       ├── dovecot    ← IMAP 邮件存储      │
│       ├── rspamd     ← 反垃圾/SPF/DKIM    │
│       └── redis      ← 缓存              │
│                                          │
│  (可选) clamav       ← 病毒扫描 (~1GB)    │
└─────────────────────────────────────────┘

DNS 配置

自建邮件服务器的 DNS 记录是重中之重,少一个都可能收不到信或者进垃圾箱:

# 邮件服务器地址
A          mail    →    <服务器公网 IP>

# MX 记录(告诉世界你的邮件服务器在哪)
MX         @     →    mail.<你的域名>.  优先级 10

# SPF(声明哪些 IP 可以代表你的域名发信)
TXT        @     →    v=spf1 mx ~all

# DKIM(邮件签名,证明邮件确实来自你)
TXT        dkim._domainkey  →  v=DKIM1; k=rsa; p=<Mailu 自动生成的公钥>

# DMARC(告诉收件方如何处理伪造你的邮件)
TXT        _dmarc  →  v=DMARC1; p=none; rua=mailto:dmarc@<你的域名>

其中 DKIM 密钥由 Mailu 自动生成,DMARC 策略初期用 p=none(只报告不拒收),确认正常后改为 p=quarantinep=reject


七、端口冲突与解决方案

问题

我现有的 Nginx 占了 HTTP 标准端口(托管静态博客),而 Mailu 自带的前端 Nginx 也需要标准 HTTP/HTTPS 端口。

方案对比

方案做法可行性
A. 博客改端口博客从 HTTP 标准端口改到非标准端口,Mailu 独占标准端口✅ 推荐
B. Nginx 反代现有 Nginx 反代到 Mailu 后端❌ Mailu 内部路由复杂,官方不推荐
C. Mailu 非标准端口Mailu 用非标准 SMTP 端口❌ MX 记录只支持标准 SMTP 端口,改端口无法收信

方案 A 是最干净的解法。个人博客只有我自己看,用非标准端口完全不影响。而且 Mailu 自带 Let’s Encrypt 证书自动续期,用标准端口才能正常工作。


八、安全风险评估

自建邮件服务器 = 在互联网上开几个固定端口,等着别人连。安全分析是必须的。

攻击面

                    互联网

          ┌────────────┼────────────┐
          ▼            ▼            ▼
       25端口       443端口      993端口
       (SMTP)      (Web/HTTPS)   (IMAPS)
          │            │            │
     ┌────┴────┐   ┌───┴───┐   ┌───┴───┐
     │ Postfix │   │ Nginx │   │Dovecot│
     │ 收信队列 │   │ Webmail│   │ 邮箱存储│
     └─────────┘   └───────┘   └───────┘

各端口风险

端口风险等级主要威胁缓解措施
SMTP(入站)🟡 中垃圾邮件投递、缓冲区溢出Rspamd 反垃圾、Postfix 连接数限制
HTTPS🔴 高Web 面板暴力破解、注入攻击HTTPS + fail2ban + 强密码
IMAPS🟡 中IMAP 暴力破解Dovecot 认证限制、fail2ban
Submission不发信就不开完全关闭

最大威胁:Web 管理面板

Mailu 的管理面板可以通过 https://mail.<你的域名>/admin 访问,这是最容易被自动化工具攻击的入口。

缓解措施:

  1. 强密码:admin 账户必须用强密码
  2. fail2ban:已有 fail2ban 运行中,加入 Mailu 登录失败规则
  3. IP 白名单(可选):只允许自己的 IP 访问 /admin
  4. 双因素认证:如果后续 Mailu 版本支持

只收不发的安全优势

如果只做”收邮件”,不发邮件,安全风险会显著降低:

  • 不会被当作垃圾邮件源:不发信 = 不会有人举报你发垃圾
  • 不需要 SPF/DKIM 发信策略:减少了 DNS 配置复杂度
  • 不需要 SMTP 中继账号:减少了一个攻击面
  • 587/465 端口完全关闭:攻击面又少一块

安全加固清单

级别措施
必做强密码、HTTPS、fail2ban、关闭 587 端口、邮箱配额
推荐管理面板 IP 白名单、只开 993 关 143(强制 SSL)、定期备份
可选反垃圾规则调优、审计日志、容器资源限制

九、数据目录规划

<邮件服务目录>/
├── docker-compose.yml
├── .env                    # 核心配置
├── certs/                  # Let's Encrypt 证书(自动生成)
├── data/
│   ├── postfix/            # 邮件队列
│   ├── dovecot/            # 邮箱存储(Maildir 格式)
│   ├── rspamd/             # 反垃圾学习数据
│   └── redis/              # 缓存
└── overrides/              # 自定义配置

邮件数据存在 <邮件服务目录>/data/dovecot/,按用户目录结构组织,格式是标准的 Maildir,随时可以迁移到其他系统。

备份策略

# 简单但有效的备份方案
tar czf <备份目>/mailu-$(date +%Y%m%d).tar.gz <邮件服务目>/data/
# 加上 cron 定时执行 + 远程存储

十、资源占用预估

组件内存磁盘
Frontend (Nginx)~30MB
Postfix~20MB队列 < 50MB
Dovecot~50MB邮件存储(按实际量)
Admin~100MB
Webmail~100MB
Rspamd~200MB~100MB
Redis~20MB
ClamAV(可选)~1GB
合计~520MB(无 ClamAV)按需

对于一台主流配置的云服务器,Mailu 的开销几乎可以忽略。即使加上 ClamAV,也才 ~1.5GB。


十一、最终方案

经过分析,我的最终落地方案是:

┌──────────────────────────────────────────────────┐
│              阿里云 ECS                           │
│                                                   │
│  个人博客 :<非标准端口>  ← 静态 Astro 站点         │
│                                                   │
│  Mailu ← Docker Compose                           │
│     ├── 收信: SMTP 入站(不受出站封禁影响)         │
│     ├── Webmail: HTTPS 访问                       │
│     ├── IMAP: IMAPS(强制 SSL)                    │
│     └── 发信: 通过 Submission → SMTP2GO 中继代发   │
│                                                   │
│  DNS: mail.<你的域名> → <服务器公网 IP>            │
│  MX: <你的域名> → mail.<你的域名>                  │
│  SPF/DKIM/DMARC: 全部配置                          │
│  fail2ban: 保护各暴露端口                          │
└──────────────────────────────────────────────────┘

一句话总结:Mailu Docker 部署 + SMTP2GO 中继发信 + fail2ban 防护 + 个人博客改到非标准端口让出标准端口。


十二、还没开始

分析做完了,方案也确定了。但截至目前——还没有部署

原因很简单:邮件服务器一旦上线,就需要持续的运维——DNS 不能错、证书不能过期、磁盘不能满、日志要看、备份要做。在决定投入这份运维成本之前,先把方案想清楚,比冲动 docker compose up -d 更重要。

等哪天真的需要了,按这个方案走就行。


—— 分析于 2026-05-18,待实施。