基于 Docker 快速搭建 Maddy 邮箱服务

基于 Docker 快速搭建 Maddy 邮箱服务

    • Docker 搭建
      • 1. 申请 SSL 证书
      • 2. 创建 docker 持久化目录,引入配置文件
      • 3. Docker 启动 Maddy
      • 4. 云服务器的 DNS 设置
      • Maddy 命令行操作
    • 测试是否搭建成功
    • 域名解析配置基础知识
      • MX 记录
      • PTR 记录
      • SPF 记录
      • DKIM 记录
      • DMARC 记录
      • MTA-STS 和 TLS 报告
      • DNSSEC, DNAME, CAA
    • 参考

Docker 搭建

Maddy 是一个 GO 语言开发的 ALL-IN-ONE 邮件系统,主要功能是通过 SMTP 发送和接收邮件,通过 IMAP,客户端可以实现访问,也支持 DKIM、SPF、DMARC、DANE、MTA-STS 等邮件相关的安全和反垃圾协议。

通俗点讲就是部署特别方便, 资源占用少,非常适合个人使用的电子邮件服务器。

项目地址:maddy/maddy.conf at master · foxcpp/maddy (github.com)

前提:

  • 拥有一台有公网 IP 的服务器,并且有域名
  • 服务器开启以下端口:143,25,465,587,993

参考:常用邮件端口

以下用 example.com 这个域名作演示,实际中替换成真实域名。

1. 申请 SSL 证书

从 https://sslforfree.com 申请 mx1.example.com 证书,下载得到 certificate.crtprivate.key

certificate.crtprivate.key 分别重命名为 fullchain.pemprivkey.pem(配置文件中默认指定的名称)

2. 创建 docker 持久化目录,引入配置文件

从 maddy.conf 下载官方默认的配置文件,并修改其中内容:

(hostname) = mx1.example.com
(primary_domain) = example.com

创建一个目录 maddydata 用于存放容器内的数据映射,并且把上面的证书文件与 maddy.conf 放入

此时的 maddydata 目录结构如下:

maddydata
├── certs
│   └── mx1.example.com
│       ├── fullchain.pem
│       └── privkey.pem
└── maddy.conf

3. Docker 启动 Maddy

docker run \
  --name maddy \
  -e MADDY_HOSTNAME=mx1.example.com \
  -e MADDY_DOMAIN=example.com \
  -v /maddydata/certs:/etc/maddy/certs/ \
  -v /maddydata:/data \
  -p 25:25 \
  -p 143:143 \
  -p 587:587 \
  -p 993:993 \
  -d foxcpp/maddy:latest

如果 docker 服务启动失败,根据 docker logs maddy 查看日志寻找原因

4. 云服务器的 DNS 设置

更详细的解释可以参考官方文档 Installation & initial configuration - maddy

注意,example.com 应该改成你自己的域名

# A 记录
example.com.   A     10.2.3.4

# MX 记录
example.com.   MX    10 mx1.example.com.
# MX 域解析
mx1.example.org.  A     10.2.3.4

# SPF
example.com.   TXT   "v=spf1 mx ~all"
example.com.   TXT   "v=spf1 mx ~all"

# _dmarc
_dmarc.example.com.   TXT    "v=DMARC1; p=quarantine; ruf=mailto:[email protected]"

# _mta-sts. _smtp.tls
_mta-sts.example.com.   TXT    "v=STSv1; id=1"
_smtp._tls.example.com. TXT    "v=TLSRPTv1;rua=mailto:[email protected]"

# 设置的值项目运行后自动生成,cat maddydata/dkim_keys/example.com_default.dns
default._domainkey.example.com.    TXT   "v=DKIM1; k=ed25519; p=xxxxxxxxxxxx"

如果有 IPV6 地址,也可以配置上:

example.com.   AAAA  2001:beef::1 # IPV6 有就配置
mx1.example.org.  AAAA  2001:beef::1 # IPV6 有就配置

对于各个配置的详细解析可以参考后面部分。

Maddy 命令行操作

进入 maddy 容器中:

docker exec -it maddy sh

Maddy 使用虚拟用户,所以不像 postfix 和 dovecot 一样需要创建系统用户。它需要创建的登录账户和 IMAP 本地存储账户。(登录账户是 SMTP 和 IMAP 登录时的验证信息)

# 创建一个 [email protected] 的登录账户
$ maddyctl creds create [email protected]

# 查看登录账户列表
$ maddyctl creds list
# 创建一个 [email protected] 邮件储存账户
$ maddyctl imap-acct create [email protected]

# 查看刚存储账户列表
$ maddyctl imap-acct list
# 可以看到账户下的邮件分类
$ maddyctl imap-mboxes list [email protected]
INBOX   [\HasNoChildren]
Sent    [\Sent \HasNoChildren]
Trash   [\Trash \HasNoChildren]
Junk    [\Junk \HasNoChildren]
Drafts  [\Drafts \HasNoChildren]
Archive [\Archive \HasNoChildren]

# 可以查看当前账户对应分类接收到的邮件,一般收件在 INBOX 中
$maddyctl imap-msgs list [email protected] INBOX

测试是否搭建成功

登录上一个 Web 邮箱(例如 163),往你刚刚创建的 [email protected] 发送邮件

查看是否收到邮件:

$ maddyctl imap-msgs list [email protected] INBOX
UID 1:  <[email protected]> - =?utf-8?B?dGVzdEBoYWhhY29kZS5jbg==?=
  [\Recent], 2023-03-22 09:54:47 +0000 UTC

域名解析配置基础知识

无论邮箱系统用的什么软件,都绕不开邮件相关的域名解析,只要搞邮件就需配置以下域名解析:

  • MX 记录 :域名系统基础记录,指向邮件服务器
  • SPF 记录 :指定哪些服务器可以使用你的域名发送邮件
  • DKIM 记录 :防止发送的电子邮件内容篡改
  • DMARC 记录 :当 SPF 和 DKIM 验证失败时,指定接收方的处理策略并向指定邮箱报告
  • PTR 记录 :即 IP 反解析,根据 IP 反查域名,需供应商来做

MX 记录

收发邮件时,MX 记录指定了自己的邮件服务器地址,可以设置优先级,一般建议 2 条以上 mx 记录()

域名        类型   值           优先级
example.com mx  mx1.example.com  10

设置对应 MX 子域名的记录:

mx1.example.com  A  10.2.3.4

设置好后使用 dig 命令验证一下:

dig mx example.com

PTR 记录

将域名映射到 IP 地址是正向解析,从 IP 地址到域名的映射就是反向解析,在公网上,反向解析无法由 DNS 提供,因为 IP 地址的管理权限属于运营商,所以需要向运营商申请添加反向解析,运营商通过 PTR(Pointer Record)记录将 IP 地址指向域名。邮件服务器 IP 不做 PTR 记录,发送邮件后会有很大概率被当成垃圾邮件。

联系供应商加好后,可以用 dig 命令验证:

dig -x mx1.example.com

SPF 记录

SPF 全名是 发件人策略框架,主要作用是将发信的邮件服务器和发信域名进行绑定,防止伪造发件人。在 SPF 记录中使用 TXT 记录指定允许发信的服务器,当对方收到邮件后,系统会验证发信域名并读取 SPF 记录中的 IP,验证是否一致后采取进一步动作。

以谷歌 SPF 记录为例:

# dig txt gmail.com
gmail.com.        300    IN    TXT    "v=spf1 redirect=_spf.google.com"

# dig txt _spf.google.com
_spf.google.com.    300    IN    TXT    "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"

# dig txt _netblocks.google.com
_netblocks.google.com.    300    IN    TXT    "v=spf1 ip4:35.190.247.0/24 ip4:64.233.160.0/19 ip4:66.102.0.0/20 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:74.125.0.0/16 ip4:108.177.8.0/21 ip4:173.194.0.0/16 ip4:209.85.128.0/17 ip4:216.58.192.0/19 ip4:216.239.32.0/19 ~all"

SPF 记录以 v=spf1 开头,以 all 结尾,中间可以使用 ip4/ip6/a/mx/include/redirect 等关键字进行 ip 范围指定。SPF 记录的匹配机制会结合 限定词 来告诉服务器匹配记录时的动作。常见的限定词有:

  • + 放行,如果没有明确指定限定词,则为默认值。
  • - 硬拒绝,直接拒绝来自未经授权主机的邮件。
  • ~ 软拒绝,邮件可被接受,也可被标记为垃圾邮件。
  • ? 中性,不考虑邮件是否被接受。

个人邮件设置允许 mx 记录中的服务器发信即可,最终设置 SPF 记录为:

example.com  txt  "v=spf1 mx -all"

DKIM 记录

DKIM 记录主要作用也是防止邮件被恶意篡改,保证邮件内容的完整性,使用的方式是与 SSL 类似,服务器产生一个公私钥对,私钥为每一封外发的邮件签名并在邮件头中插入 DKIM 签名(DKIM-Signature 头),公钥则保存在域名的记录中,邮件接收方接收邮件时,通过 DNS 查询获得公钥,并使用公钥解密邮件签名, 从而验证邮件有效性和完整性。

Docker 运行 Maddy 启动后会自动生成 DKIM 私钥和需添加的 dns 记录,位置在:

  • dockerdata/dkim_keys/example.com_default.dns
default._domainkey.example.com  txt  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0......"

DMARC 记录

DMARC 基于现有的 SPF 和 DKIM 协议,并声明对验证失败邮件的处理策略。邮件接收方接收邮件时,首先通过 DNS 获取 DMARC 记录,再对邮件来源进行 SPF 验证和 DKIM 验证,对验证失败的邮件根据 DMARC 记录进行处理,并将处理结果反馈给发送方。

_dmarc.nixops.me  txt  "v=DMARC1; p=quarantine; ruf=mailto:[email protected]"
  • p:reject 拒绝该邮件;none 为不作处理;quarantine 标记为垃圾邮件。
  • ruf:检测到伪造邮件,接收方报告的邮箱地址

MTA-STS 和 TLS 报告

MTA-STS 是 MTA 严格传输安全协议,作用是确保发送给我们的电子邮件通过 TLS 安全地传输,防止中间人攻击。启用 MTA-STS 后,发送方邮件服务器只有在满足以下条件时,才会向我们发送邮件:

  • 使用有效的证书通过身份验证
  • 使用 TLS 1.2 或更高版本进行加密

当然如果发送方不支持 MTA-STS,仍然可以发送邮件(可能会有中间人攻击),主要是为了兼容。

启用 MTA-STS 所需条件:

  • 创建策略文件,并提供 HTTPS 方式访问
  • 通过 DNS 设置 txt 记录,告诉其它邮件服务商支持 MTA-STS

策略文件 mta-sts.txt 的内容为:

version: STSv1
mode: enforce
mx: mx1.nixops.me
mx: mx2.nixops.me
max_age: 86400

创建子域名并启用 https,最终的访问路径为:

https://mta-sts.nixops.me/.well-known/mta-sts.txt

配置 MTA-STS 的 TXT 记录:

_mta-sts.nixops.me TXT "v=STSv1; id=20211031T010101;"

一般 id 为时间戳。

DNSSEC, DNAME, CAA

启用了 MTA-STS 后,DANE 可以确保 TLS 证书是有效的,实际上是通过 DNS 的方式扮演了 CA 的角色。 DANE 通过 TLSA 记录,来声明某个证书的是可信的,由于 DANE 是基于 DNS 协议,可能会有被挟持的可能,因此需要启用 DNSSEC 来保障传输过程中不被修改。

  1. 启用 DNSSEC 需域名注册商及 dns 服务商都支持,在 DNS 服务商处选择开启 DNSSEC,然后将提供的 DS 记录填写到域名注册商即可
  2. 使用 TLSA 证书生成工具 及 PEM 格式的 TLS 证书生成 TLSA 记录
  3. 使用CAA Record Helper生成的 CAA 记录

为了保障 TLS 证书安全:

  1. DNSSEC 保障 DNS 记录传输过程中的安全
  2. DANE 在客户端侧阻止不当签发的证书
  3. CAA 指定域名允许哪个证书颁发机构为其颁发证书

此步为加强安全性,有能力推荐启用配置。

参考

参考文章:

  • Maddy 打造个人邮箱服务 - 阅心笔记 (nixops.me)
  • 开源邮件服务器 Maddy 部署教程 (lwebapp.com)

其他参考链接及有用的工具:

  1. https://mxtoolbox.com/
  2. https://www.mail-tester.com/
  3. https://aykevl.nl/apps/mta-sts/
  4. https://support.google.com/a/answer/10683907
  5. https://support.google.com/a/answer/2466563?hl=zh-Hans
  6. https://service.mail.qq.com/cgi-bin/help?id=16

你可能感兴趣的:(Golang,docker,容器,运维,邮箱服务)