mailcow 是一个使用 Docker 部署的邮件服务器。

注意(我踩过的坑):

家庭宽带的动态公网 IP 发出的邮件会被主流邮件服务商拦截(如微软outlook、谷歌gmail),这是因为反垃圾邮件联盟会将家庭宽带的 IP 段列入黑名单,而邮件服务商会直接根据反垃圾邮件联盟的黑名单来拒收邮件。

如果你用的家庭宽带,并且想自建邮件服务器后能够正常发送邮件,那么就需要有一个云服务器作为邮件中继服务器,又因为需要设置 PTR 记录来增加 IP 的信誉,所以如果要买云服务器的话,在国内推荐买华为云的,可以自己在控制台设置 PTR 记录,阿里云的话需要联系人工客服设置,腾讯云的话买了云服务器不能设置 PTR,需要再花 1500 RMB 买(真实服了 TX)。

1. 环境要求

1.1 设备

不能在群晖/威联通等NAS设备上安装,也不能在 OpenVZ、LXC或其他容器平台上安装。

可以在 KVM, PVE, ESX, Hyper-V 或其他完全虚拟化的平台中安装。

最低的硬件配置:

资源mailcow: dockerized
CPU1 GHz
内存最小 6 GB + 1 GB 交换区
硬盘20GB(不包含邮件)
系统x86_64

ClamAV(反病毒)Solr(全局搜索) 会使用较多的内存 ,可以在配置文件 mailcow.conf 中通过 SKIP_CLAMD=ySKIP_SOLR=y来关闭它们。

1.2 内存

官方描述

单个 SOGo(mailcow 使用的 webmail)会使用大概350MB的内存,使用过后会被清除,并释放这些内存。同一时间活动的连接越多,就需要越大的内存。

50个 IMAP 连接需要 16 GB 内存。

5 - 10 用户需要 8GB 内存。

实际使用

实际部署测试时,在 4G 内存电脑上也可以部署成功,部署完成后总共使用了 3G 内存,每登录一个 邮件客户端,内存就多占用 100M。

如果预计给500个用户使用,在一个人只登录一个客户端的情况下,64G 的内存应该是够的。

1.3 系统

系统兼容性
Alpine 3.17+ and older部分兼容(需手动调整)
Centos 7完全兼容
Debian 10, 11完全兼容
Ubuntu 18.04, 20.04, 22.04完全兼容
Alma Linux 8完全兼容
Rocky Linux 9完全兼容

其他没有经过官方测试的系统也可能能够正常使用。

1.4 端口

部署前需要检查 mailcow 的端口是否被占用

ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'
# or:
netstat -tulpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'

如果你的服务器有防火墙,需要打开以下端口来确保邮件服务能够正常使用。 如果使用家庭网络,需要配置好端口映射

服务协议端口容器对应配置文件中的变量
Postfix SMTPTCP25postfix-mailcow${SMTP_PORT}
Postfix SMTPSTCP465postfix-mailcow${SMTPS_PORT}
Postfix SubmissionTCP587postfix-mailcow${SUBMISSION_PORT}
Dovecot IMAPTCP143dovecot-mailcow${IMAP_PORT}
Dovecot IMAPSTCP993dovecot-mailcow${IMAPS_PORT}
Dovecot POP3TCP110dovecot-mailcow${POP_PORT}
Dovecot POP3STCP995dovecot-mailcow${POPS_PORT}
Dovecot ManageSieveTCP4190dovecot-mailcow${SIEVE_PORT}
HTTP(S)TCP80/443nginx-mailcow${HTTP_PORT} / ${HTTPS_PORT}

2. 安装

需要已经安装 Docker >= 20.10.2Docker Compose > =2.0

切换到 root,并查看 umask 必须为 0022.

# su
# umask
0022

切换到 /opt 目录,将 docker-compose 文件克隆到本地,然后切换到 mailcow-dockerized目录

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

初始化 mailcow,有三个地方需要手动确认: hostname: 用于访问网页邮箱的域名,如 mail.leftblue.top Timezone [Asia/Shanghai]: 服务器所在时区,如: Asia/Shanghai Choose the Branch with it´s number [1/2]: 安装的分支,选 1

初始化完成后会生成一个 mailcow.conf 配置文件

如果你想使用反向代理,可以在mailcow.conf中修改如下配置

HTTP_BIND=127.0.0.1

HTTPS_BIND=127.0.0.1

启动 mailcow

docker-compose pull
docker-compose up -d

此时你可以通过网页访问 mailcow,默认用户 admin 密码 moohoo

这时已经可以通过网页邮箱发送邮件了,继续配置 DNS,完成后将可以接收邮件。

3. DNS设置

以域名 leftblue.top 为例

3.1 最小设置

mail.leftblue.top 为邮件服务器 IP 对应的域名,将 1.2.3.4 改为你的服务器IP地址

主机记录记录类型记录值
mailA1.2.3.4
autodiscoverCNAMEmail.leftblue.top
autoconfigCNAMEmail.leftblue.top
@MXmail.leftblue.top

3.2 SPF, DKIM, DMARC 和 PTR

  • SPF(Sender Policy Framework)

发件人策略框架是一种反垃圾邮件方案,以下记录表示只允许MX记录指向的服务器发送邮件:

主机记录记录类型记录值
@TXTv=spf1 mx a -all
  • DKIM(DomainKeys Identified Mail)

域名密钥识别用于邮件域名验证,存储了电子邮件签名的公钥。其可以在 System > 配置 > 选项 > ARC/DKIM 密钥 中查看

1685516706478.png

主机记录记录类型记录值
dkim._domainkeyTXTv=DKIM1; k=rsa; t=s; s=email; p=...
  • DMARC(Domain-based Message Authentication, Reporting & Conformance)

基于域的消息身份验证、报告和一致性用于防止他人伪造域名,以下例子使用 DMARC Assistant 生成。将 admin@leftblue.top 改为你的邮件服务器中的邮件地址即可。

主机记录记录类型记录值
_dmarcTXTv=DMARC1; p=reject; rua=mailto:admin@leftblue.top
  • PTR(Pointer Record)/ RDNS

域名反向解析可以使用IP地址解析为域名,用于提升服务器 IP 及域名的信誉度,可以减少被识别为垃圾邮件的概率。

腾讯云太坑了,PTR 服务还要单独购买,这里就不设置了。 1685517510685.png

如果要设置的话,将服务器IP指向邮件服务器的 hostname,同时 hostname也要指向邮件服务器的IP。

3.3 高级设置

以下与各服务默认的端口相同,可以不设置。

SRV记录可以为域名中的特定协议指定服务器。如果要显式说明没有提供某个服务,使用 "." 保存为记录值。

SRV 记录格式: 优先级+空格+权重+空格+端口+空格+主机名,如 5 0 5269 xmpp-server.l.google.com

主机记录记录类型记录值
_autodiscover._tcpSRV0 1 443 mail.example.com
_caldavs._tcpSRV0 1 443 mail.example.com
_caldavs._tcpTXTpath=/SOGo/dav/
_carddavs._tcpSRV0 1 443 mail.example.com
_carddavs._tcpTXTpath=/SOGo/dav/
_imap._tcpSRV0 1 143 mail.example.com
_imaps._tcpSRV0 1 993 mail.example.com
_pop3._tcpSRV0 1 110 mail.example.com
_pop3s._tcpSRV0 1 995 mail.example.com
_sieve._tcpSRV0 1 4190 mail.example.com
_sieve._tcpSRV0 1 465 mail.example.com
_submission._tcpSRV0 1 587 mail.example.com

4. 测试评分

部署好邮件服务器后,邮件测试是不可少的,如果评分过低,发送的邮件会被认为是垃圾邮件。

打开 https://www.mail-tester.com/ ,使用自己的邮箱发送一封邮件到给出的邮箱,就能查看得分了。

可以看到除了没有设置域名反向解析,其他都通过了,得了 8.9 分。 64cfbb5f5fba4.png

到这里就全部完成了,可以使用我们自己域名的邮箱了。

5. SSL 配置

如果 ssl 配置不正确,将无法通过 https、smtps、pop3s 和 imaps 协议访问邮箱。

mailcow 使用 Let's EncryptHTTP-01 验证方式获取 ssl 证书,这种方式要求服务必须在 80 端口上提供 http 服务来完成验证。

mailcow 还有自己的校验,申请证书时,mailcow 会校验 mail.leftblue.topautoconfig.leftblue.topautodiscover.leftblue.top 这三个域名的 IP 是否和邮件服务器的 IP 相同,然后校验这三个域名的 80 端口是否可以访问 mailcow 的网页。

5.1 云服务器 ssl 配置

如果云服务器配置高,可以在云服务器直接部署 mailcow,只要可以使用 80 端口访问网页邮箱,mailcow 会自动帮我们进行证书的申请。

5.2 家庭网络 ssl 配置

由于家庭网络通常屏蔽了 80 和 443 端口,mailcow 无法自动申请证书。

5.2.1 有云服务器:使用内网穿透

云服务器性能拉跨,邮件服务器部署在家庭网络,使用内网穿透完成 Let's Encrypt 的验证。

  1. mailcow.conf 中修改 SKIP_IP_CHECK=ySKIP_IP_CHECK=y 跳过 mailcow 的 IP 校验和 HTTP 服务校验。
  2. mail.leftblue.topautoconfig.leftblue.topautodiscover.leftblue.top 指向云服务器地址,将 MX 记录指向家庭公网 IP,其他三个记录指向云服务器的 IP。
主机记录记录类型记录值
mailA5.6.7.8(云服务器IP)
autodiscoverCNAMEmail.leftblue.top
autoconfigCNAMEmail.leftblue.top
@MX1.2.3.4(家庭公网 IP)
  1. 重启 docker compose up -d

5.2.2 没有云服务器:手动设置 ssl 证书

如果使用自己的证书,到期需要手动更换。

前往云服务商申请证书,华为云、阿里云、腾讯云等都提供免费的证书,期限1年。

申请好之后,下载 nginx 的证书,将 .crt 文件命名为 cert.pem.key 文件命名为 key.pem,上传这两个文件到 mailcow 目录的 data/assets/ssl 替换原文件。

mailcown.conf 中修改 SKIP_LETS_ENCRYPT=y

重启服务:

docker restart $(docker ps -qaf name=postfix-mailcow)
docker restart $(docker ps -qaf name=nginx-mailcow)
docker restart $(docker ps -qaf name=dovecot-mailcow)

5.3 验证ssl

在 shell 执行以下命令,能够连接上则表示证书正常

# Connect via SMTP STARTTLS (587)
openssl s_client -starttls smtp -connect mail.leftblue.top:587 | openssl x509 -noout -text
# Connect via SMTP (465)
openssl s_client -connect mail.leftblue.top:465 | openssl x509 -noout -text

# Connect via IMAP STARTTLS (143)
openssl s_client -starttls imap -connect mail.leftblue.top:143 | openssl x509 -noout -text
# Connect via IMAP (993)
openssl s_client -connect mail.leftblue.top:993 | openssl x509 -noout -text

# Connect via HTTPS (443)
openssl s_client -connect mail.leftblue.top:443 | openssl x509 -noout -text

6. 使用

修改管理员密码

System > 配置 > 权限管理 > 管理员 中找到需要修改密码的记录,点击编辑即可修改

添加邮件域名

右上角点击 E-Mail > 配置

在标签页找到 域名 > 域名 > 添加域名

页面自定义

右上角点击 System > 配置

在标签页找到 选项 > 页面自定义

7. 遇到的问题

7.1 Cannot match your IP x.x.x.x against hostname autodiscover.xxxx.com (DNS returned y.y.y.y)

邮件服务器的 IP 与域名指向的 IP 不一样,可以修改配置文件 SKIP_IP_CHECK=y 来忽略校验

7.2 Confirmed A record with IP x.x.x.x, but HTTP validation failed

邮件服务器的 IP 校验通过了,但无法通过80端口访问到 http 服务,可以修改配置文件 SKIP_IP_CHECK=y 来忽略

7.3 ValueError: Error getting directory: Url: https://acme-v02.api.letsencrypt.org/directory

网络不稳定造成的,重启 acme 所在的容器再次尝试