0%

威联通NAS使用docker-mailserver搭建邮件服务

最近入手了第一台NAS,考虑配置拓展入手了威联通,于是开始了捣腾QTS系统。威联通的通知中心会发送事件和警报通知给注册的设备,其中一种发送方式是邮件,需要通过SMTP服务连接一个邮件服务器,使用这个服务器的账户发送通知给指定的邮箱。其实简单点直接配置自己的邮箱服务就行,但我突然想尝试一下在NAS上搭一个邮件系统。威联通系统不像群晖有自带的邮件服务,需要自己去搭建,在搜索几个服务后选择了docker-mailserver来搭建,这个镜像比较轻量级,可以简单的只搭建一个SMTP服务,对系统的要求比较低一些。

由于我没有自己的域名,而当前的需求只是发送邮件,所以这里的配置不涉及任何SSL配置,简单来说这个文章就是把最基本的容器跑起来的一个过程。

参考了多个文章之后(列在最后的参考文档,非常感谢几位作者的分享,第一次搭邮件系统好多都不懂),发现官方tutorial中Using DMS as a local mail relay for containers是比较符合我的需求的,只搭建SMTP服务,不搭POP3 / IMAP。

威联通Container Station认识

正好是到手第一次配置docker,也算是对这个定制化docker认识的一个过程,记录一些小发现:

  • 支持Docker Compose,但竟然是在Application中创建,第一次找了半天没找到
  • 使用Container时,输入镜像后选择版本依赖hub.docker.com的访问,这个域名DNS污染了,需要手动解决下(顺便解决上这个网站的问题)
  • ssh进入后,可以完美使用docker命令,嫌页面麻烦的可以直接ssh操作,不过bash比较难用(还没成功使用zsh)
  • bash的vim版本低的可怜,relativenumber和color都不支持,实在是太难用了

服务搭建过程

编写compose文件

文件基本时照搬官方文档的,其实也没几行配置:
首先需要配置一个hostname,这里按喜好填写,但建议不要用常见的域名,不知道会不会被其他邮箱拦截;
ports只配置SMTP的端口,其实感觉甚至后两个不配都可能没事;
volume配置照抄官方配置,其实不是特别好因为是映射到了container的本地文件中,在QNAP中重新编译会删掉原本的本地文件,比较好的做法是用docker的volume,不过我也只是搭个账号就简单处理了。至于为什么要映射本地文件是为了保证容器重启后数据不会丢失;
环境变量中需要注意把SSL_TYPE删掉,这样默认SSL就是空,如果根据原本的配置会需要一个SSL证书,否则容器跑不起来。当然如果想要接收邮件证书是必须的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: '1.0'

services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mailserver
hostname: mail.example.com # 千万记得换个域名,发送邮件给网易被拒绝了就是因为这个域名。。。
ports:
- "25:25"
- "587:587"
- "465:465"
volumes:
- ./docker-data/dms/mail-data/:/var/mail/
- ./docker-data/dms/mail-state/:/var/mail-state/
- ./docker-data/dms/mail-logs/:/var/log/mail/
- ./docker-data/dms/config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
environment:
- ENABLE_FAIL2BAN=1
- PERMIT_DOCKER=network
- SPOOF_PROTECTION=0
cap_add:
- NET_ADMIN
restart: always

然后把这个配置丢到Application中创建就行,它会自动创建并启动一个对应的容器。

配置一个用户

容器启动后,就会提示没有用户,需要创建一个用户(这里一个坑点是120s没有用户就会重启,不是很懂)
这时就需要ssh进入系统,跑下命令创建一个用户,这个操作很多文档都说要下载脚本跑,但实际上直接用docker里的脚本操作就行,以下命令是创建一个邮箱是admin@example.com密码是passwd123的一个账户。

1
docker exec -ti mailserver setup email add admin@example.com passwd123

这个脚本运行后,就会发现docker中显示正常启动了。

通知中心连接服务

其实到这一步,邮件服务算是跑起来了,但是还有其他的坑我们晚点处理,现在可以尝试连接邮件服务了。在通知中心中添加SMTP服务,选择custom account,服务ip配置127.0.0.1,安全连接配置为None,输入用户名密码,就可以了。
创建后点击发送测试邮件,自己给自己发一封邮件,会发现有些日志,不过好像有点错误(也可能成功,我用example.com的域名能发送成功,用新的域名就是失败找不到域名)不过至少我们服务器能连接上了。
当然也可以尝试发送一封邮件给自己真实的邮箱,如果能发送成功,那恭喜你就配置完成了。不过我这边会有个postfix的报错Host or domain name not found. Name service error for name=example.com

处理域名问题

上面这个postfix的服务解析问题,其实是因为dns配置错误导致的,通过互联网搜索找到了解法,可以修改resolv.conf配置postfix的dns解析。

首先进入容器,我这里ui界面的terminal不知道为什么没法用(还需要研究下),直接ssh到服务后运行docker命令:

1
docker exec -it mailserver /bin/bash

可以找到配置文件路径在/etc/resolv.conf,使用cat看下默认的配置:

1
2
nameserver 127.0.0.11
options ndots:0

域名解析的服务器不知道为什么还在本地,需要修改成真实解析的dns地址。在docker文档上找了一圈没找到配置项,只能手动改这个配置了。结果尝试vim / vi竟然都不支持,可能作者为了精简吧,把编辑功能都删了,尝试apt install直接连不上。。还好这配置只有两行,最终用最傻的方法>直接覆盖写入文件(不过好像在源文件后面append一行配置也可以)

1
2
3
4
# 先复制一份,虽然没什么用
cp resolv.conf resolv.conf.backup
echo 'nameserver 1.1.1.1' > resolv.conf
echo 'options ndots:0' >> resolv.conf

然后用通知中心给自己的邮箱发送一份邮件,就能很愉快的接收到了,也可以从docker的日志看到一些信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Nov 27 02:07:05 xxx postfix/trivial-rewrite[16634]: warning: do not list domain my-mail.com in BOTH mydestination and virtual_mailbox_domains
Nov 27 02:07:05 xxx postfix/smtpd[16548]: send-id-A: client=unknown[172.29.8.1]
Nov 27 02:07:05 xxx postfix/cleanup[16635]: send-id-A: message-id=<>
Nov 27 02:07:05 xxx opendkim[489]: send-id-A: no signing table match for 'user@my-mail.com'
Nov 27 02:07:05 xxx opendkim[489]: send-id-A: no signature data
Nov 27 02:07:05 xxx postfix/qmgr[619]: send-id-A: from=<user@my-mail.com>, size=32379, nrcpt=1 (queue active)
Nov 27 02:07:05 xxx postfix/smtpd[16548]: disconnect from unknown[172.29.8.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Nov 27 02:07:05 xxx postfix/smtpd-amavis/smtpd[16638]: connect from localhost[127.0.0.1]
Nov 27 02:07:05 xxx postfix/trivial-rewrite[16634]: warning: do not list domain my-mail.com in BOTH mydestination and virtual_mailbox_domains
Nov 27 02:07:05 xxx postfix/smtpd-amavis/smtpd[16638]: receive-id-B: client=localhost[127.0.0.1]
Nov 27 02:07:05 xxx postfix/cleanup[16635]: receive-id-B: message-id=<this-is-id@my-mail.com>
Nov 27 02:07:05 xxx postfix/qmgr[619]: receive-id-B: from=<user@my-mail.co>, size=32604, nrcpt=1 (queue active)
Nov 27 02:07:05 xxx amavis[687]: (00687-01) Passed CLEAN {RelayedOpenRelay}, [172.29.8.1]:59858 <user@my-mail.co> -> <my-real-email@email.com>, Queue-ID: send-id-A, mail_id: xxxxx, Hits: -, size: 32345, queued_as: receive-id-B, 43 ms
Nov 27 02:07:05 xxx postfix/smtp-amavis/smtp[16636]: send-id-A: to=<my-real-email@email.com>, relay=127.0.0.1[127.0.0.1]:10024, delay=0.07, delays=0.01/0.01/0/0.04, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as receive-id-B)
Nov 27 02:07:05 xxx postfix/qmgr[619]: send-id-A: removed
Nov 27 02:07:06 xxx postfix/smtp[16639]: receive-id-B: to=<my-real-email@email.com>, relay=real-email-domian[xxx.xxx.xx.xx]:25, delay=0.89, delays=0/0.01/0.16/0.72, dsn=2.0.0, status=sent (250 Mail OK queued as some-id another-id)
Nov 27 02:07:06 xxx postfix/qmgr[619]: receive-id-B: removed

这样配置后,理论上我们还需要把这个配置做持久化映射,否则docker重启后又会发送失败。

后记

整体只是一个简单的配置,但是因为不熟悉邮件系统 + 没有域名导致折腾了很久,很多配置在域名上的我以为是本地配的,找了半天。另外其实这个邮件系统有点鸡肋,算是一个小小的学习demo吧。
其实运行过程中还会发现有些问题,比如经常出现connect from unknown然后忽略连接,也不知道是局域网有问题还是什么情况;另外也有思考既然基本只用到postfix是不是找个postfix镜像就行,但好像还需要一个简单的db存储,针对这个docker也需要更深入研究下。

参考文档