【Arch Linux】maddy 邮件服务器搭建
maddy 是一个开源的轻量级“可组合”(composable)多合一邮件服务器,支持通过 IMAP/SMTP 等协议和 DKIM、SPF、DMARC、DANE、MTA-STS 等安全模式收发邮件。本文将以官方文档为主线,整理 maddy 服务器配置流程。
准备
为保证 maddy 的正常运行,请先明确一些建议满足的前提条件:
- 具有公网地址(本文以 IPv4 为例)并开放 25、143、465(TLS)、587、993(TLS)等端口(一些 VPS 提供商如谷歌云不支持)的服务器;
- 拥有一个域名(最好是付费二级域名,避免一些 DNS 服务商如 Cloudflare 封禁对其的 API 操作),并接入 DNS 服务商(本文以 Cloudflare 为例);
- TLS 证书(本文以 Let’s Encrypt 和一款证书获取软件 certbot 为例)。
为叙述方便,本文假设邮件服务器的主域名为 example.org,邮件交换(MX)域名为 mx1.example.org,公网 IPv4 地址为 10.2.3.4,邮件账户为 postmaster@example.org。
同时需要在服务器上至少安装如下的软件包:
- maddy
- certbot
- certbot-dns-cloudflare
- nginx(或其他 Web 服务端)
除 maddy 外,其他的软件包都可以使用 pacman
直接安装。
安装
可以在 GitHub 的 Releases 页面获取 maddy 最新版本的源码和预编译程序。也可以参照官方文档的说明,从源码构建、AUR 处获取或 Docker 镜像部署。
注意:从 AUR 处获取需要下载体积很大的 golang 编译器。为节约下载并安装编译器的时间,读者可以直接使用 GitHub 的预编译程序。本文也以此为例。
在服务器终端中执行如下命令,以下载 maddy 的预编译程序:
1 | # 安装 zstd 包,以解压 *.zst 类型的文件 |
启动服务前,先加载所有新增服务:
1 | sudo systemctl daemon-reload |
若要开机自启:
1 | sudo systemctl enable maddy |
因为 maddy 运行在非 root 用户上,还需要创建一个用户用以运行 maddy 服务:
1 | sudo useradd -mrU -s /sbin/nologin -d /var/lib/maddy -c "maddy mail server" maddy |
配置
域名
使用任何编辑器打开 /etc/maddy/maddy.conf
,修改 $(hostname)
和 $(primary_domain)
变量的值为 mx1.example.org
和 example.org
。
TLS 证书
获取
Let’s Enccrypt 签发的 TLS 证书可以通过 certbot 获取。根据 certbot 和 certbot-dns-cloudflare 的官方文档,首先需要在 Cloudflare 的 API Token 配置页面新建一个 Token,选择“Edit zone DNS”的模板,在“Zone Resources”选择目标二级域名(本文则是“example.org”)即可。
注意:Token 只会显示一次,在配置好证书前,请务必牢记。
随后,可以在服务器上存储 Token 以方便后续使用。在终端中执行:
1 | mkdir -p ~/.secrets/certbot |
并设置权限提高安全性:
1 | chmod 600 ~/.secrets/certbot/cloudflare.ini |
再使用 certbot 获取证书:
1 | sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini -d '*.example.org' -d 'example.org' |
注意:可以选择不为含通配符域名,而是根据后文实际需要指定必要的三级域名签发证书。
首次获取证书需要填写邮箱等个人信息。签发完毕后则可以通过 sudo certbot certificates
获取证书的详细信息和存储位置。一般存储位置在 /etc/letsencrypt/live/example.org
,其中证书文件名为 fullchain.pem
,私钥路径为 privkey.pem
。
配置
编辑 /etc/maddy/maddy.conf
,修改 tls file
一行为
1 | tls file /etc/letsencrypt/live/$(primary_domain)/fullchain.pem /etc/letsencrypt/live/$(primary_domain)/privkey.pem |
/etc/letsencrypt/live
文件夹默认权限为 750,maddy 无法访问,故需要使用 ACL 进行权限控制:
1 | sudo setfacl -R -m u:maddy:rX /etc/letsencrypt/{live,archive} |
此时可以启动 maddy 服务来测试:
1 | sudo systemctl start maddy |
若服务未报错,则可以继续进行配置。
DNS
进入 Cloudflare 的 DNS 配置页,作出如下所示的配置:
1 | example.org. A 10.2.3.4 |
其中最后一条记录的值需要用
1 | sudo cat /var/lib/maddy/dkim_keys/example.org_default.dns |
的输出替换。若显示文件不存在,请确认 maddy 服务是否曾成功运行过至少一次。
MTA-STS
MTA-STS 要求访问 https://mta-sts.example.org/.well-known/mta-sts.txt 时能输出类似如下的文本:
1 | version: STSv1 |
对于已经安装 HTTP Echo 模块的 Nginx,直接在 /etc/nginx/nginx.conf
中添加如下条目:
1 | server { |
对于未安装该模块的 Nginx,先添加如下条目:
1 | server { |
再新建 /usr/share/nginx/mta-sts
文件夹,将指定文本写入 mta-sts.txt
文件中:
1 | sudo cat <<EOF |
重启 Nginx 服务:
1 | sudo systemctl restart nginx |
检查上述网络路径是否能够正常访问。
DANE
设置 TLSA(DANE)需要在 https://www.huque.com/bin/gen_tlsa 生成对应的 DNS 记录。
进入页面后,在“Enter/paste PEM format X.509 certificate here:”下的文本框中输入上文中获取的证书的内容:
1 | sudo cat /etc/letsencrypt/live/example.org/fullchain.pem |
注意:该证书很长,务必复制完全。
下方的“Port Number:”填写 25
,Transport Protocol:
填写 tcp
,Domain Name:
填写 mx1.example.org
。再点击“Generate”生成记录。将 DNS 记录写入 Cloudflare 中。
创建邮件账户
在服务器终端中:
1 | maddyctl creds create postmaster@example.org |
此时,邮件账户的用户名为“postmaster@example.org”,密码则在创建账户时要求设置。该账户已经可以在邮件客户端(如 Thunderbird 和 Outlook)中配置并使用。
(可选)开启 DNSSEC 认证
DNSSEC(Domain Name System Security Extensions),即域名系统安全扩展,对DNS提供给DNS客户端(解析器)的DNS数据来源进行认证,并验证不存在性和校验数据完整性验证。
Arch Wiki 中给出了一些验证方法。安装 ldns
包后:
1 | $ drill -DT example.org # 替换为二级域名 |
如果命令执行结果如上所示(域名前的 flag 值为“T”),则说明 DNSSEC 认证已开启;反之,请参考 Install a DNSSEC-validating resolver 章节,或参考 DNS 服务商的文档。
以下简单介绍 Cloudflare 为域名开启 DNSSEC 的方法:进入 Cloudflare 控制台后,进入目标域名的详情页面,点击左侧的“DNS”选项卡,在页面尾部的“DNSSEC”部分点击“Enable DNSSEC”。随后 Cloudflare 将给出域名的 DS Record。再进入域名注册商的域名管理页面设置 DS Record。具体设置方法参照 Cloudflare 的官方文档。
【Arch Linux】maddy 邮件服务器搭建
1.Codeforces 1324B: Yet Another Palindrome Problem
2.Codeforces 363B: Fence & Rust for Competitive Programming
3.Codeforces 1327A: Sum of Odd Integers
4.LeetCode Problem 3: Longest Substring Without Repeating Characters
5.【文件格式探究】EP.2 WAV 音频文件格式
6.Codeforces 1399D: Binary String to Subsequences
7.Codeforces 1368B: Codeforces Subsequences
8.Codeforces 1430C: Numbers on Whiteboard
1.【ACG音乐分享】Ceui《今、歩き出す君へ》
2.使用 GPG 加密、解密和验证信息
3.【翻译】如何编写 Git 提交消息
4.Linux 时间操作及其同步
5.【实测】Python 和 C++ 下字符串查找的速度对比
6.Codeforces 1312B: Bogosort