Maddy打造个人邮箱服务
Maddy Mail Server 是一个 GO 语言开发的 ALL-IN-ONE 邮件系统,实现了 Mail Transfer agent (MTA), Mail Delivery Agent (MDA), Mail Submission Agent (MSA), IMAP server 等,说人话就是可以替换 Postfix、Dovecot、Opendkim、OpenSPF、OpenDmarc 等传统软件,主要功能是通过 SMTP 发送和接收邮件,通过 IMAP 实现客户端访问,也支持 DKIM、SPF、DMARC、DANE、MTA-STS 等邮件相关的安全和反垃圾协议。对比配置传统软件,即使是像 MailCow、Mail-in-a-Box 等基于 docker 的现成方案,安装、配置也足够简单、开箱即用,可以说是懒人必备。
一、准备工作
需要准备以下:
二、安装及配置 Maddy mail server
2.1 下载和安装
建议使用 docker 安装 Maddy,安装和配置起来更简单。github release 中已经有编译好的各平台可执行文件, 也可以从 github 下载最新版解压使用:
wget https://github.com/foxcpp/maddy/releases/download/v0.7.1/maddy-0.7.1-x86_64-linux-musl.tar.zst
zst 后缀需要安装 zstd 进行解压:
yum install zstd -y
tar -I zstd -xvf maddy-0.7.1-x86_64-linux-musl.tar.zst
解压之后的目录有5个文件,安装 Maddy:
mv maddy maddyctl /usr/local/bin/
mkdir /etc/maddy && mv maddy.conf /etc/maddy/
mv systemd/*.service /usr/lib/systemd/system/
mv man/*.1 /usr/share/man/man1/ && mv man/*.5 /usr/share/man/man5/
2.2 配置 maddy mail server
2.2.1 添加用户
官方不建议 root 权限运行,先添加一个不可登录的普通用户:
useradd -mrU -s /sbin/nologin -c "maddy mail server" maddy
添加完用户,设置一下相关的目录及文件的权限:
chown -R maddy:maddy /usr/local/bin/maddy* /etc/maddy
2.2.2 更改配置文件
默认配置文件在 /etc/maddy/maddy.conf ,里面已经有一个开箱即用的配置,只需修改几个参数即可使用。
$(hostname) = mx1.opswill.com mx2.opswill.com
$(primary_domain) = opswill.com
$(local_domains) = $(primary_domain) other.domain.com
tls file /etc/maddy/certs/$(hostname)/fullchain.pem /etc/maddy/certs/$(hostname)/privkey.pem
state_dir /etc/maddy/state
runtime_dir /etc/maddy/runtime
log syslog /var/log/maddy.log
按需修改以上内容即可,如果创建的普通用户未指定 home 目录,配置文件中的 state_dir、runtime_dir 需先创建目录并给权限。
2.2.3 申请 ssl 证书
SMTPs 和 IMAPs 服务需要 TLS 证书,建议使用 Let's Encrypt 的泛域名证书,具体申请方法就不介绍了。
证书需放入 /etc/maddy/certs/$(hostname) 中,在配置文件中指定时,需先写公钥(.crt),在写私钥 (.key)
证书需设置一下权限:
sudo setfacl -R -m u:maddy:rX /etc/maddy/certs/
2.2.4 创建用户
maddy 使用虚拟用户,所以不像 postfix 和 dovecot 一样需要创建系统用户。maddy 需要创建登录账户和 IMAP 的本地存储账户,登录账户是 SMTP 和 IMAP 登录时的验证信息:
maddyctl creds create will@opswill.com
创建本地储存账户:
maddyctl imap-acct create will@opswill.com
查看是否创建成功:
maddyctl creds list
maddyctl imap-acct list
2.3 启动服务
以上全部做好后,即可启动服务:
systemctl daemon-reload
systemctl start maddy
正常启动后,会开放以下端口:
- 25 SMTP Transfer->Exchange ClearText
- 465 SMTPs User->Submission TLS
- 587 ESMTP User->Submission ClearText/STARTTLS
- 143 IMAP Delivery->User ClearText
- 993 IMAPs Delivery->User TLS
防火墙放行:
firewall-cmd --permanent --add-port={25/tcp,465/tcp,587/tcp,143/tcp,993/tcp}
firewall-cmd --reload
从外网 telnet 验证一下服务器公网 IP 是否开放以上端口。尤其需注意25端口是否能够访问
服务器端就配置好了,可以用手机或 outlook 等客户端进行连接测试。接下来为了收发邮件,还需配置域名解析才行。
三、域名解析配置
无论邮箱系统用的什么软件,都绕不开邮件相关的域名解析,只要搞邮件就需配置以下域名解析:
- MX记录 :域名系统基础记录,指向邮件服务器
- PTR记录 :即IP反解析,根据IP反查域名,需供应商来做
- SPF记录 :指定哪些服务器可以使用你的域名发送邮件
- DKIM记录 :防止发送的电子邮件内容篡改
- DMARC记录 :当SPF和DKIM验证失败时,指定接收方的处理策略并向指定邮箱报告
3.1 MX 记录
收发邮件时,mx 记录指定了自己的邮件服务器地址,可以设置优先级,建议2条以上 mx 记录
域名 类型 值 优先级
opswill.com mx mx1.opswill.com 10
opswill.com mx mx2.opswill.com 20
设置对应MX子域名的记录:
mx1.opswill.com A 1.1.1.1
mx2.opswill.com A 2.2.2.2
设置好后使用dig命令验证一下:
dig mx opswill.com @1.1.1.1
dig a mx1.opswill.com @1.1.1.1
dig a mx2.opswill.com @1.1.1.1
3.2 PTR 记录
将域名映射到 IP 地址是正向解析,从 IP 地址到域名的映射就是反向解析,在公网上,反向解析无法由 DNS 提供,因为IP地址的管理权限属于运营商,所以需要向运营商申请添加反向解析,运营商通过 PTR(Pointer Record)记录将 IP 地址指向域名。邮件服务器IP不做PTR记录,发送邮件后会有很大概率被当成垃圾邮件。
联系供应商加好后,可以用 dig 命令验证:
dig -x 1.1.1.1
3.3 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 记录为:
opswill.com txt "v=spf1 mx -all"
3.4 DKIM 记录
DKIM 记录主要作用也是防止邮件被恶意篡改,保证邮件内容的完整性,使用的方式是与 SSL 类似,服务器产生一个公私钥对,私钥为每一封外发的邮件签名并在邮件头中插入 DKIM 签名(DKIM-Signature头),公钥则保存在域名的记录中,邮件接收方接收邮件时,通过 DNS 查询获得公钥,并使用公钥解密邮件签名, 从而验证邮件有效性和完整性。
Maddy 第一次启动后已经自动生成 DKIM 私钥和需添加的 dns 记录,位置在 state dir(/etc/maddy/state)下的 /dkim_keys/_default.dns 中,添加 txt 记录:
default._domainkey.opswill.com txt "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0...省略..."
3.5 DMARC 记录
DMARC 基于现有的 SPF 和 DKIM 协议,并声明对验证失败邮件的处理策略。邮件接收方接收邮件时,首先通过 DNS 获取 DMARC 记录,再对邮件来源进行 SPF 验证和 DKIM 验证,对验证失败的邮件根据 DMARC 记录进行处理,并将处理结果反馈给发送方。
添加 DMARC 记录:
_dmarc.opswill.com txt "v=DMARC1; p=quarantine; ruf=mailto:report@ipip.dev"
p:reject 拒绝该邮件;none为不作处理;quarantine 标记为垃圾邮件。
ruf:检测到伪造邮件,接收方报告的邮箱地址
3.6 MTA-STS 和 TLS 报告
MTA-STS 是 MTA 严格传输安全协议,作用是确保发送给我们的电子邮件通过 TLS 安全地传输,防止中间人攻击。启用 MTA-STS 后,发送方邮件服务器只有在满足以下条件时,才会向我们发送邮件:
- 使用有效的证书通过身份验证
- 使用 TLS 1.2 或更高版本进行加密
当然如果发送方不支持 MTA-STS,仍然可以发送邮件(可能会有中间人攻击),主要是为了兼容。
启用 MTA-STS 所需条件:
- 创建策略文件,并提供HTTPS方式访问
- 通过DNS 设置txt记录,告诉其它邮件服务商支持MTA-STS
3.6.1 创建策略文件
策略文件 mta-sts.txt 的内容为:
version: STSv1
mode: enforce
mx: mx1.opswill.com
mx: mx2.opswill.com
max_age: 86400
创建子域名并启用 https ,最终的访问路径为:
https://mta-sts.opswill.com/.well-known/mta-sts.txt
3.6.2 配置 MTA-STS 的TXT记录
_mta-sts.opswill.com TXT “v=STSv1; id=20211031T010101;"
一般id为时间戳
3.6.3 启用 TLS 报告
和 DMARC 记录类似,启用 TLS 报告可以接受外部邮件服务器会发送以下内容:检测到的 MTA-STS 政策、流量统计信息、失败的连接以及无法发送的邮件等详细信息。
添加以下 txt 记录:
_smtp._tls.opswill.com TXT "v=TLSRPTv1;rua=mailto:sts-reports@opswill.com"
3.7 DNSSEC、DANE 及 CAA
启用了 MTA-STS 后,DANE 可以确保 TLS 证书是有效的,实际上是通过DNS的方式扮演了 CA 的角色。 DANE 通过 TLSA 记录,来声明某个证书的是可信的,由于 DANE 是基于 DNS 协议,可能会有被挟持的可能,因此需要启用 DNSSEC 来保障传输过程中不被修改。
- 启用 DNSSEC 需域名注册商及 dns 服务商都支持,在 DNS 服务商处选择开启 DNSSEC ,然后将提供的 DS 记录填写到域名注册商即可
- 使用 TLSA证书生成工具 及 PEM 格式的 TLS 证书生成 TLSA 记录
- 使用 CAA Record Helper生成的 CAA 记录
为了保障 TLS 证书安全:
- DNSSEC 保障 DNS 记录传输过程中的安全
- DANE 在客户端侧阻止不当签发的证书
- CAA 指定域名允许哪个证书颁发机构为其颁发证书
此步为加强安全性,有能力推荐启用配置
四、邮件通知到 Telegram
在 maddy.conf 中,找到 storage.imapsql local_mailboxes,添加一个 imap_filter :
storage.imapsql local_mailboxes {
driver sqlite3
dsn imapsql.db
imap_filter {
command /data/script/notice.sh {sender} {original_rcpt_to} {subject}
}
}
邮件通知的脚本内容:
#!/bin/bash
logfile=/data/log/notice.log
echo -e "\n$(date "+%Y-%m-%dT%H:%M:%S") starting sending tg notice with args: $@" >>$logfile
input="$3"
if ! command -v curl &> /dev/null; then
if ! apk add curl; then
exit 1
fi
fi
#bash判断是否为 Base64 编码
if [[ "$input" =~ =\?utf-8\?B\?(.*)\?= ]]; then
encoded=${BASH_REMATCH[1]}
sub=$(echo "$encoded" | base64 -d)
else
sub=$input
fi
MailMsg="New Mail From $1 To $2, Subject: $sub"
curl -s -X POST "https://api.telegram.org/botIDxxxx:botSECRETxxxx/sendMessage" -d "chat_id=185854188&text=$MailMsg" >>$logfile
echo -e "\n$(date "+%Y-%m-%dT%H:%M:%S") tg notice has sent" >>$logfile
五、总结
邮箱服务不只是系统配置烦琐、反垃圾、安全相关、及域名解析等的都很麻烦,如果使用传统的软件,其实不是很适合新手。虽然有一些基于 docker 或者脚本的现成方案,但真部署和调试起来也不容易。对比传统软件 Maddy mail server 安装和配置都足够简单,满足一个现代安全邮箱所需的功能,也有一定的扩展性,虽然比较新还不够成熟,但对个人友好,适合懒人党对可靠性要求不高的情况。
参考链接及有用的工具:
[...]還有像是 DNSSEC, MTA-STS, TLS, TLSA 與 CAA 等紀錄可以強化安全性的,本篇幅就不多寫了,可以參考這篇也是 Maddy 用戶的筆記解說,非常詳細,推薦一看: Maddy打造个人邮箱服务[...]