最近 LQCD 的代码写得不太顺利,结果就是搭电子乐高的瘾又犯了,花了一下午和一晚上搭建了自己的 mail server。搭建过程不难,但还是会踩一些小坑,就在博客里做一个小小的记录。我使用的是由 Hetzner 提供的预装有 Debian GNU/Linux 11 (bullseye) 的服务器,用 Cloudflare 管理 DNS。小心 Hetzner。
主要参考文档:Docker Mailserver。以下内容也是按照文档中的顺序来组织的。
主机上的配置(PART A)#
rDNS(PTR 记录)#
在 Cloudflare 上创建 PTR 记录似乎没用,需要在 Hetzner 的管理面板直接编辑反向 DNS 记录:
IPv4 和 IPv6 的 rDNS 都需要设置为 mail.example.com
(example.com
替换为自己的),这是 实际提供邮件服务 的域名。子域名设置成别的也可以,一般默认是 mail
。
开放合适的端口#
确保出站的 25 和 465 端口是开放的。入站的端口除了 25 一定要打开以外,其余端口根据个人喜好来开放。我希望所有连接都用 implicit TLS,所以只开放了 465 和 993 端口。
根据 Hetzner 的文档,为了防止他们的服务器被滥用,Hetzner 上服务器的出站 25 和 465 端口默认是被关闭的,并且它们在防火墙设置处无法被开启,需要在 limit request 页面手动申请解封。如果用的是其他 ISP,也一定要认真确认端口的开放状态。
最后折腾了我大半晚上的就是这一步,
小心 Hetzner。
DNS 服务商处的配置 (PART A)#
这一步先添加 A(AAAA) 记录以及 MX 记录。
- 添加 A(AAAA) 记录
域名部分是 实际提供邮件服务的域名,在这里就是mail.example.com
,该记录指向服务器的 IPv4(6) 地址。如果是在 Cloudflare 上配置,要关掉 proxy。 - MX 记录
域名部分是 邮箱账户 @ 后面的域名,在这里设置为example.com
,该记录指向 实际提供邮件服务的域名,即mail.example.com
。Priority
部分写 0 就好。
添加完毕后运行如下测试,结果应该是一致的:
$ dig @1.1.1.1 +short MX example.com
mail.example.com
$ dig @1.1.1.1 +short A mail.example.com
11.22.33.44
$ dig @1.1.1.1 +short -x 11.22.33.44
mail.example.com
主机上的配置(PART B)#
安装 SSL 证书#
这里用 certbot 来安装 SSL 证书。安装时会用到 80 端口,所以如果有类似 Nginx 的占用 80 端口的服务需要暂时关闭。
# 为域名 mail.example.com 申请证书
$ sudo certbot certonly --standalone -d mail.example.com
# 查看所有证书的状态
$ sudo certbot certificates
配置 Docker Mailserver#
我新建了一个 mailserver
文件夹,在里面运行 Docker Mailserver 文档里的命令:
DMS_GITHUB_URL="https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master"
wget "${DMS_GITHUB_URL}/compose.yaml"
wget "${DMS_GITHUB_URL}/mailserver.env"
接下来编辑 compose.yaml
:
- 将
hostname
改为自己的 - 将
ports
下不需要的端口注释掉 - 为了使用 SSL 证书,在
volumes
末尾添加:- /etc/letsencrypt:/etc/letsencrypt
然后编辑 mailserver.env
:
- 重要
SSL_TYPE=letsencrypt
:也是为了用 SSL 证书
- 可选
TZ
:服务器使用的时区。我设置了TZ=Asia/Tokyo
ENABLE_CLAMAV
:杀毒软件,打开打开ENABLE_FAIL2BAN
:防止密码被暴力破解,打开打开小提示(又是一个坑):
如果设置了ENABLE_FAIL2BAN = 1
,一定要在compose.yaml
中将# cap_add: # - NET_ADMIN
这两行的注释取消掉。
Mailserver 初次启动#
在 mailserver
文件夹中运行:
$ docker compose up -d # 后台运行 docker compose 服务
这时在两分钟内添加第一个账户,那么就添加一个管理员账户:
$ docker exec -ti mailserver setup email add [email protected]
然后为管理员账户创建 postmaster 别名
$ docker exec -ti mailserver setup alias add [email protected] [email protected]
现在就可以在邮件客户端(Thunderbird 等)登录邮箱啦!向 Mail Tester 发一封测试邮件看看评分…2.1 分…嗯,看来还有一些配置要完成…
生成 DKIM key#
$ docker exec -it mailserver setup config dkim
生成的文件被放在了 ./docker-data/dms/config/opendkim/keys/example.com
中,我们需要的是 mail.txt
中的内容。
DNS 服务商处的配置 (PART B)#
最后,在域名 DNS 记录下添加三个神秘的 TXT:SPF、DKIM 和 DMARC。
SPF#
最简单的一个,只需要添加:
- Type: TXT
- Name: example.com
- Content: v=spf1 mx -all
DKIM#
通过之前的步骤,应该得到了 mail.txt
中的三行内容。把所有的双引号和空格删除以后,添加到下文中的 Content:
- Type: TXT
- Name: mail._domainkey.example.com
- Content: v=DKIM1; h=sha256; k=rsa; p=一大串乱码
DMARC#
- Type: TXT
- Name: _dmarc
- Content: v=DMARC1; p=reject; adkim=s; aspf=s; rua=mailto:某备用邮箱; ruf=mailto:某备用邮箱
最后,在 Mail Tester进行测试…10 分!在 Learn and Test DMARC也测试一下…全部 PASS!新的电子乐高搭好了!Hurray!
附录#
Docker Compose 常用命令#
$ docker compose up -d # 后台运行 docker compose 服务
$ docker compose down # 停止 docker compose 服务
$ docker compose logs -f # 查看服务日志
如果要完全重启 Docker Mailserver,最好的方法是
$ docker compose down
$ sudo systemctl restart docker.service
$ docker compose up -d
Docker Mailserver 常用命令#
# 创建新用户
$ docker exec -ti <CONTAINER NAME> setup email add [email protected]
# 查看用户列表
$ docker exec -ti <CONTAINER NAME> setup email list
# 生成 DKIM key
$ docker exec -it <CONTAINER NAME> setup config dkim