Docker自建Email服务器 - 私人邮件系统

搭建Email服务,该方法适用于个人,公司或组织

备注:这是我找到唯一简便安装且能正常使用的邮件系统,请留言告诉我你是否有更好的自建解决方案。

踩了很多的坑,经历了一个月左右的时间,才测试收发邮件成功(部分邮箱目的地无法达到,由于互联网上的反垃圾邮件策略),持续更新完善中.

2024年3月18日 新增章节:“维护定时任务”

2024年3月22日 新增章节:“SMTP服务测试” 并修正spf的DNS设置内容;关注到另外一个备选方案:Stalwart Mail Server(All-in-One 邮件服务器)

下一步:朋友提出新需求:如何批量发送邮件?

怎么用

  • 日常收发邮件

    • 通过搭建邮件服务来收发你自己域名下的邮件
  • 第三方平台(或自己搭建的服务)上需要设置的SMTP服务(SMTP邮箱设置)邮件通知/告知

相关内容

实现方法

iRedMail Docker搭建

iRedMail docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
version: '3.9'
services:
mariadb:
image: 'iredmail/mariadb:stable'
volumes:
- './postfix_queue:/var/spool/postfix'
- './sa_rules:/var/lib/spamassassin'
- './clamav:/var/lib/clamav'
- './mysql:/var/lib/mysql'
- './ssl:/opt/iredmail/ssl'
- './custom:/opt/iredmail/custom'
- './imapsieve_copy:/var/vmail/imapsieve_copy'
- './mlmmj-archive:/var/vmail/mlmmj-archive'
- './mlmmj:/var/vmail/mlmmj'
- './mailboxes:/var/vmail/vmail1'
- './backup-mysql:/var/vmail/backup/mysql'
- "/etc/localtime:/etc/localtime:ro" #这条可纠正邮件系统的时区
ports:
- '587:587'
- '465:465'
- '25:25'
- '993:993'
- '143:143'
- '995:995'
- '110:110'
- '4433:443'
- '8093:80'
env_file:
- ./iredmail-docker.conf
container_name: iRedMail

Docker启动后,假如一切正常则调试信息类似于:

docker启动iRedMail成功后输出信息

一切启动正常后,可以开始设置DNS记录,然后端口映射出防火墙。

最后可用系统自带的WEB网页客户端来收发邮件,或使用Outlook等客户端配置SMTP,POP3来收发邮件

设置DNS

Your DNS MX record should point to this value

设置DNS项范例:

image-20240229144603695

image-20240229144758944

| DNS类型 | DNS记录名 | 内容/值 | 说明/备注 |

DNS类型 DNS记录名 内容/值 备注/说明
MX carlzeng.top. mail.carlzeng.top. 标识邮件服务器名称,DNS MX entry
A mail.carlzeng.top. *.8.18.* 邮件服务器的IP地址
TXT carlzeng.top. v=spf1 mx -all SPF entry/记录
TXT dkim._domainkey.carlzeng.top. v=DKIM1; k=rsm; p=* DKIM entry/记录,含DKIM公钥public key,详见下方如何在docker中用命令获取这个内容值
TXT dmarc.carlzeng.top v=DMARC1; p= reject; rua=* DMARC entry/记录

问:三个TXT记录不知道怎么从iRedMail邮件系统中获取?

答:After installation: Setup DNS records for your iRedMail server (A, PTR, MX, SPF, DKIM, DMARC)

假如想要检测DNS记录的正确性,可以使用:https://mxtoolbox.com/

SPF entry/记录

v=spf1 mx a:mail.carlzeng.top -all

根据SMTP测试报告,这条记录可能存在错误

image-20240321195957875

v=spf1 a mx include:_spf.google.com ~all

CF中编辑DNS记录后使用dig检测:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
% dig carlzeng.top txt

; <<>> DiG 9.10.6 <<>> carlzeng.top txt
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49494
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 7

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1024
;; QUESTION SECTION:
;carlzeng.top. IN TXT

;; ANSWER SECTION:
carlzeng.top. 2099 IN TXT "google-site-verification=709aI8iBja5qWYVP85LxviHsfbHWjpuJZmBOqENAXBM"
carlzeng.top. 2099 IN TXT "v=spf1 mx a:mail.carlzeng.top -all"
carlzeng.top. 2099 IN TXT "google-site-verification=CLgNXe3i4ZobXoFz9U4gy6OzMAa8gNmXImQbNmTiNPY"

;; AUTHORITY SECTION:
carlzeng.top. 0 IN NS amir.ns.cloudflare.com.
carlzeng.top. 0 IN NS paityn.ns.cloudflare.com.

;; ADDITIONAL SECTION:
amir.ns.cloudflare.com. 20184 IN A 108.162.193.62
amir.ns.cloudflare.com. 20184 IN A 172.64.33.62
amir.ns.cloudflare.com. 20184 IN A 173.245.59.62
paityn.ns.cloudflare.com. 59423 IN A 108.162.194.18
paityn.ns.cloudflare.com. 59423 IN A 172.64.34.18
paityn.ns.cloudflare.com. 59423 IN A 162.159.38.18

;; Query time: 5 msec
;; SERVER: 223.5.5.5#53(223.5.5.5)
;; WHEN: Thu Mar 21 20:18:20 CST 2024
;; MSG SIZE rcvd: 403

大约半小时时间,修改过后的spf记录仍然没有得到更新,持续关注中….

纠正了这条spf相关的DNS记录以后,测试SMTP;显示成功:

image-20240322081436077

DKIM entry/记录

关于如何获取dkim._domainkey.mydomain.com.的内容/值,举例:

1
2
3
4
5
6
7
8
9
10
11
12

> docker exec -it iRedMail bash

root@cc9dd27b3e25:/etc/amavis/conf.d# amavisd-new showkeys
; key#1 1024 bits, i=dkim, d=carlzeng.top, /opt/iredmail/custom/amavisd/dkim/carlzeng.top.pem
dkim._domainkey.carlzeng.top. 3600 TXT (
"v=DKIM1; p="
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDUF5BslOb2fARJjXK41xsAPSg"
"hToQAkJzRuxp5pwaCyqPzIbFNxTZ66z9yw+rbeXYKdpu3bKemHhKVQ7rvnmVlFFL"
"Nvef7Pk9ddT/nur2T1sfUY6yDu5QRcZArClAQRjfNCFRA11VgsD5q6OKS5GTNtE5"
"dz3kJGpVdCllilo4OwIDAQAB")

DMARC entry/记录

1
v=DMARC1; p=reject; sp=none; adkim=s; aspf=s; rua=mailto:postmaster@carlzeng.top; ruf=mailto:postmaster@carlzeng.top

端口映射

这个步骤的作用是让路由器上接收到的邮件相关的数据,都转发给正确的邮件服务系统。

外部端口 内部NAS/Mail主机端口 说明
‘587:587’
‘465:465’
‘25:25’
‘993:993’
‘143:143’
‘995:995’
‘110:110’
4433 4433 添加到443端口的访问可能

将这些端口一一对应,很庆幸这些端口还没有被ISP屏蔽;

image-20240301105204159

SMTP设置发邮件

比如在佰阅发卡kamifaka中设置邮箱信息,用于消息通知之邮箱通知。

错误:无法成功到达邮件目的地

解决办法:详见‘错误及解决办法’的章节:SMTP服务测试

调整了SPF的那条DNS记录(第二天发现生效),再次测试;可以正常发送测试邮箱。

错误及解决方法

Docker启动错误:”Permission denied”

iRedMail | /usr/sbin/mysqld: Can’t create file ‘/var/lib/mysql/mysqld.err’ (errno: 13 “Permission denied”)
iRedMail | 2024-02-28 16:12:07 0 [ERROR] mysqld: Can’t create/write to file ‘/var/lib/mysql/aria_log_control’ (Errcode: 13 “Permission denied”)

解决办法:

chmod 777 -R /volume2/KingchuxingSSD512G/docker/compose/iRedMail
chmod 777 -R /volume2/KingchuxingSSD512G/docker/compose/iRedMail/mysql/

DNS设置错误之No DMARC Record found

错误列表检测自:https://mxtoolbox.com/emailhealth/carlzeng.top/

Category Host Result
Status Problem dmarc carlzeng.top No DMARC Record found information More Info
Status Problem blacklist mail.carlzeng.top Blacklisted by UCEPROTECTL3 information More Info
Status Problem mx carlzeng.top No DMARC Record found information More Info

错误解决:

原来DNS记录的名称搞错了,正确的dmarc DNS记录名必须是(含下划线):_dmarc

iredadmin操作不携带端口错误

操作的后台https://iredmail.carlzeng.top:3/iredadmin,当提交新的确认操作时,页面跳转到未携带端口状态

错误解决:

image-20240301101140381

没有解决自动携带端口的问题,等待docker重启后继续测试

icloud通信受阻rejected due to listing in Spamhaus PBL

host mx01.mail.icloud.com[17.56.9.31] said: 550
5.7.1 Mail from IP 111.197.216.113 was rejected due to listing in Spamhaus
PBL. For details please see
http://www.spamhaus.org/query/bl?ip=111.197.216.113 (in reply to RCPT TO
command)

解决办法:

去给定的IP AND DOMAIN REPUTATION CHECKER网站上提交解封申请,提交成功后,如图:

image-20240301104242813

程序发邮件被自我拦截为SPAM

从网站平台配置的SMTP,程序发邮件被自我拦截为SPAM;

1
2
3
4
5
6
7
8
Spam scanner report:
Spam detection software, running on the system "cc9dd27b3e25",
has identified this incoming email as possible spam. The original
message has been attached to this so you can view it or label
similar future email. If you have any questions, see
the administrator of that system for details.

Content preview: Test send email

解决办法: 未知,如何关闭自己对自己发邮件的过度SPAM检测(邮件不是SPAM,系统误判)。。。

- https://docs.iredmail.org/disable.spam. … mails.html
- https://docs.iredmail.org/completely.di … assin.html

docker exec -it iRedMail bash

没有找到这个文件:/etc/amavis/conf.d/50-user

1
2
# @bypass_virus_checks_maps = (1);  # controls running of anti-virus code
# @bypass_spam_checks_maps = (1); # controls running of anti-spam code

Restarting Amavisd service is required after changing settings.

1
2
3
> service  amavis restart                                                     
Stopping amavisd: amavisd-new.
Starting amavisd: amavisd-new.

environment:

TZ=Asia/Shanghai

发现:使用最初的账户没有这个误判的情况。

是否可删除mail.**的DNS记录?

由于设定了泛域名解析道正确的IP ,目前增加的这条mail.carlzeng.top反而增加了DDNS需要去轮询更新IP的任务数,没有这条DNS解析,直接ping mail.* 也一样得到最新且正确的IP地址。

待实践核实/测试… (理论上没问题,因为iodine已经成功删除/优化掉A记录)

维护定时任务

每天邮箱中都收到6封系统自动备份的邮件:

1
2
3
4
5
6
7
Cron <root@c7e4835b8e6d> /bin/bash /var/vmail/backup/backup_mysql.sh 

/bin/sh: 1: freshclam: not found

/etc/cron.daily/logrotate:
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of reload-log.

进入docker

1
2
3
4
docker exec -it iRedMail bash   

# 编辑Linux中的定时任务的命令
crontab -e

注释掉

1
2
3
4
5
6
7
#40 3 * * * /bin/bash /var/vmail/backup/backup_mysql.sh 

#Ansible: freshclam: update database regularly.
#1 */6 * * * freshclam --quiet --foreground --config-file=/etc/clamav/freshclam.conf --daemon-notify=/etc/clamav/clamd.conf >/dev/null

#Ansible: Scan spam/ham reported by end users.
#*/10 * * * * /bin/bash /opt/iredmail/bin/dovecot/scan_reported_mails >/dev/null

感受:去掉这些每天的自动备份功能以后,清爽许多 :-)

尴尬的是,这种进bash编辑的方式,重启整个NAS后,编辑的内容会重置,还得再去编辑….

这次NAS运行81天多才重启一次,暂且用这种收邮件的方式就知道docker中的内容被恢复了。

纠正邮件系统的时区

修改docker-compose文件,在volumes下面新增这条,可纠正邮件系统的时区:

  • “/etc/localtime:/etc/localtime:ro” #这条可纠正邮件系统的时区

SMTP服务测试

SMTP Test Tool

​ 优点:实时显示详细的debug日志。赞!

Email Check Spam Score and Improve Quality

​ 优点:可以检测出详细的DNS配置错误(如果有错误的话),并给出修正的建议。赞!

iredMail证书配置

Using http://www.checktls.com/, it’s clear that the Zendesk TLS cert is incorrect in that it doesn’t specify that mail.pod-4 host.

image-20240328214042643

从这点来看,可能是自签证书的问题?那么如何替换和生成一个证书呢?

测试配置步骤:

  1. 下载NPM中生成的泛域名证书,得到certificate.zip,解压缩一共是4个文件。
  2. 上传fullchain.pem 和 privkey.pem 到 映射的目录中(/KingchuxingSSD512G/docker/compose/iRedMail/ssl),分别重命名为iRedMail.crt 和 iRedMail.key。再重新上传一遍(备份原文件名)
  3. 测试https://www.ssllabs.com/ssltest/index.htmlhttps://www.checktls.com/

本章节参考:

Use a bought SSL certificate

Request a free cert from Let’s Encrypt (for servers deployed with downloadable iRedMail installer)

image-20240423102406511

确保证书是: mail.carlzeng.top
使用dns challenge的方式,dns_cloudflare_api_token
Processing… This might take a few minutes.

https://dash.cloudflare.com/profile/api-tokens
> Global API Key

fail to get the cert by dns challenge
成功了,原来不是使用Global API KEY;要使用”API 令牌”中的‘创建令牌’ 》 编辑区域 DNS

image-20240423105448516

cp mail.jbritian.com_bundle.crt cert.pem

cp mail.jbritian.com_bundle.crt combined.pem

cp mail.jbritian.com.key key.pem

image-20240423110722391

cert1.pem 重命名成: cert.pem

fullchain1.pem 重命名成:combined.pem

privkey1.pem 重命名成:key.pem

1
2
ln -s /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem /etc/ssl/certs/iRedMail.crt
ln -s /etc/letsencrypt/live/mail.mydomain.com/privkey.pem /etc/ssl/private/iRedMail.key

都检查过这些组件了,确实都是映射到容器中的 /opt/iredmail/ssl 目录中的三个文件

1
2
3
4
5
6
7
8
9
10
11
Postfix
File /etc/postfix/main.cf (on Linux/OpenBSD)

Dovecot
File `/etc/dovecot/dovecot.conf` (on Linux/OpenBSD)

Nginx
File /etc/nginx/templates/ssl.tmpl (on Linux/OpenBSD)

MySQL, MariaDB
On Debian and Ubuntu, it's defined in /etc/mysql/my.cnf.

TXT记录变更:
v=spf1 a mx include:_spf.google.com ~all
v=spf1 mx -all


以下为踩坑记录(请跳过)

docker-mailserver

docker-compose.yml (docker-mailserver)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
services:
mailserver:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mailserver
# Provide the FQDN of your mail server here (Your DNS MX record should point to this value)
hostname: mail.carlzeng.top
ports:
- "25:25"
- "465:465"
- "587:587"
- "993:993"
volumes:
- ./mail-data/:/var/mail/
- ./mail-state/:/var/mail-state/
- ./mail-logs/:/var/log/mail/
- ./config/:/tmp/docker-mailserver/
environment:
- ENABLE_RSPAMD=0
- ENABLE_CLAMAV=0
- ENABLE_FAIL2BAN=1
- TZ=Asia/Shanghai
cap_add:
- NET_ADMIN # For Fail2Ban to work
restart: always

docker-compose up 测试中…

下一步要生成配置文件?

docker exec -ti mailserver setup

1
mailserver    | [ WARNING ]  You need at least one mail account to start Dovecot (120s left for account creation before shutdown)

docker exec -ti mailserver setup email add service@carlzeng.top

解决办法:未知

文档信息:

https://github.com/docker-mailserver/docker-mailserver?tab=readme-ov-file

https://docker-mailserver.github.io/docker-mailserver/latest/

postfix and postfixadmin

docker-compose for postfix and postfixadmin

postfixadmin
Postfix Admin is a web based interface to configure and manage a Postfix based email server for many users.

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

services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_RANDOM_ROOT_PASSWORD: 1
MYSQL_DATABASE: postfixadmin
MYSQL_USER: postfixadmin
MYSQL_PASSWORD: example

postfixadmin:
depends_on:
- db
image: postfixadmin
ports:
- 8000:80
restart: always
environment:
POSTFIXADMIN_DB_TYPE: mysqli
POSTFIXADMIN_DB_HOST: db
POSTFIXADMIN_DB_USER: postfixadmin
POSTFIXADMIN_DB_NAME: postfixadmin
POSTFIXADMIN_DB_PASSWORD: example

Where to file issues:
https://github.com/postfixadmin/docker/issues

还差一个靠谱可用的postfix

https://gitlab.com/tozd/docker/postfix

https://gitlab.com/tozd/docker/mail

https://hub.docker.com/r/tozd/postfix

Ports

  • 25/tcp: SMTP port.
  • 465/tcp: SMTPS port.
  • 587/tcp: Mail submission port.

alpine-316`: Postfix 3.7.6

https://hub.docker.com/search?q=postfix

另外一个是:https://github.com/catatnight/docker-postfix

Note:这是我找到唯一简便安装且能正常使用的邮件系统,请留言告诉我你是否有更好的自建解决方案。

感谢列表

开源大世界-自托管-电子邮件

Running iRedMail E-Mail Server in Docker

Setup DNS records for your iRedMail server (A, PTR, MX, SPF, DKIM, DMARC)

From zero to full mail server in 20 minutes with Mailu Docker images!

HTTPS/SSL证书配置