使用Docker Mailserver 搭建自己的邮件服务

有本事来咬我 2024-09-04 13:07:02 阅读 56

Docker Mailserver 官网

Docker Mailserver 仓库

前提

一个固有公网 IP 的 VPS 与域名

当然有条件的尽可能选择国外的服务器厂商和域名,因为国内的大部分都是封锁出站 25 端口同时域名也需要备案。

在服务器商那里开放<code>25、143、465、587、993端口

tips:封锁 25 出站端口为后续的发送邮件功能产生了不少的麻烦。

这里介绍公网 IP 为1.2.3.4域名为example.com后续修改配置文件,可替换成自己的 IP 和域名

安装

需要安装 Docker 与 Docker compose,这里就不多介绍了。可在其他博客中查看。教程正在 loading

1 创建安装目录

位置自定义,软件本人一般都安装在 /opt/

cd /opt

mkdir mailserver

2 下载必要文件

使用 wget 下载compose.ymlmailserver.env配置文件

也可以从 github 的仓库中下载好上传到服务器中

wget -P /opt/mailserver/ "https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/compose.yaml"

wget -P /opt/mailserver/ "https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/mailserver.env"

3 编辑配置文件

编辑compose.yml文件,修改为自己的域名与证书

这里分为两种情况

裸域安装:裸域安装的相关文件可在官网查看,简单来说就是邮件地址为test@example.com子域安装:使用子域名,例如mail.example.com,邮件地址就为test@mail.example.com

如果选择裸域安装则修改homename并解除注释

如果选择子域名安装修改domainname并解除注释

选择不同的安装方式后续的 DNS 设置也是不同的

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.example.com

domainname: mail.example.com

env_file: mailserver.env

# More information about the mail-server ports:

# https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/

# To avoid conflicts with yaml base-60 float, DO NOT remove the quotation marks.

ports:

- "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead)

- "143:143" # IMAP4 (explicit TLS => STARTTLS)

- "465:465" # ESMTP (implicit TLS)

- "587:587" # ESMTP (explicit TLS => STARTTLS)

- "993:993" # IMAP4 (implicit TLS)

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:

restart: always

stop_grace_period: 1m

# Uncomment if using `ENABLE_FAIL2BAN=1`:

cap_add:

- NET_ADMIN

healthcheck:

test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"

timeout: 3s

retries: 0

4 运行

# 切换目录

cd /opt/mailserver

# 启动容器 -d 后台运行,初次接触安装不建议,无法便捷看到日志信息

# 建议前台,配置结束后使用后台运行

docker compose up

# docker compose up -d

# docker-compose logs -f `# 观察容器 相关日志`

# 关闭容器

docker compose down

Docker Mailserver规定首次运行容器时必须创建第一个邮箱账号,否则容器会自动退出

# 在启动容器时, 使用 docker ps 查看容器的 ID

docker ps

# 出现如下内容

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

318bbf389f9c ghcr.io/docker-mailserver/docker-mailserver:latest "/usr/bin/dumb-init …" 31 seconds ago Up 30 seconds (healthy) 0.0.0.0:25->25/tcp, :::25->25/tcp, 0.0.0.0:143->143/tcp, :::143->143/tcp, 0.0.0.0:465->465/tcp, :::465->465/tcp, 0.0.0.0:587->587/tcp, :::587->587/tcp, 110/tcp, 995/tcp, 0.0.0.0:993->993/tcp, :::993->993/tcp, 4190/tcp mailserver

# 添加第一个邮箱账号

# docker exec -it <CONTAINER NAME> setup email add user@example.com <your password>

# 使用裸域安装(与compose.yml配置文件选择安装方式一致)

docker exec -it 318bbf389f9c setup email add user@example.com <your password>

# 使用子域安装(与compose.yml配置文件选择安装方式一致)

docker exec -it 318bbf389f9c setup email add user@mail.example.com <your password>

# 查看邮箱账号列表

docker exec -it 318bbf389f9c setup email list

# 其他命令可通过 help查看

docker exec -it 318bbf389f9c setup email help

......

5 配置 DNS(以腾讯 DNS 为例)

DKIM 检查器

DKIM生成器

1 生成 DKIM 签名

docker exec -it <CONTAINER NAME> setup config dkim

使用下面命令获取签名公钥, 记得路径中的域名替换成你自己的

[nukix@nukixPC mailserver]# cat /opt/mailserver/docker-data/dms/config/opendkim/keys/mail.example.com/mail.txt

mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "

"p=MIIBIjANBgkqhkiG9w0BAQEFACAQ8AMIIBCgKCAQEAaH5KuPYPSF3Ppkt466BDMAFGOA4mgqn4oPjZ5BbFlYA9l5jU3bgzRj3l6/Q1n5a9lQs5fNZ7A/HtY0aMvs3nGE4oi+LTejt1jblMhV/OfJyRCunQBIGp0s8G9kIUBzyKJpDayk2+KJSJt/lxL9Iiy0DE5hIv62ZPP6AaTdHBAsJosLFeAzuLFHQ6USyQRojefqFQtgYqWQ2JiZQ3"

"iqq3bD/BVlwKRp5gH6TEYEmx8EBJUuDxrJhkWRUk2VDl1fqhVBy8A9O7Ah+85nMrlOHIFsTaYo9o6+cDJ6t1i6G1gu+bZD0d3/3bqGLPBQV9LyEL1Rona5V7TJBGg099NQkTz1IwIDAQAB" ) ; ----- DKIM key mail for mail.example.com

v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFACAQ8AMIIBCgKCAQEAaH5KuPYPSF3Ppkt466BDMAFGOA4mgqn4oPjZ5BbFlYA9l5jU3bgzRj3l6/Q1n5a9lQs5fNZ7A/HtY0aMvs3nGE4oi+LTejt1jblMhV/OfJyRCunQBIGp0s8G9kIUBzyKJpDayk2+KJSJt/lxL9Iiy0DE5hIv62ZPP6AaTdHBAsJosLFeAzuLFHQ6USyQRojefqFQtgYqWQ2JiZQ3iqq3bD/BVlwKRp5gH6TEYEmx8EBJUuDxrJhkWRUk2VDl1fqhVBy8A9O7Ah+85nMrlOHIFsTaYo9o6+cDJ6t1i6G1gu+bZD0d3/3bqGLPBQV9LyEL1Rona5V7TJBGg099NQkTz1IwIDAQAB

2 添加 DMARC 记录(可选)

DMARC(Domain-based Message Authentication, Reporting, and Conformance)是一种邮件验证技术,它可以帮助域名所有者控制其域名下的邮件发送,防止电子邮件被伪造和滥用。DMARC 是 SPF 和 DKIM 的补充,可以对 SPF 和 DKIM 的验证结果进行汇总和分析,并指定如何处理未经验证或验证失败的邮件。

生成器

这里给个通用的最低策略,不同的策略可使用生成器自行生成

裸域安装

请公布以下内容 DNS TXT 记录子域上的_dmarc.example.com

记录类型:TXT

主机:_dmarc

记录值:v=DMARC1; p=none; sp=none;

子域安装

请公布以下内容 DNS TXT 记录子域上的_dmarc.mail.example.com

记录类型:TXT

主机:_dmarc.mail

记录值:v=DMARC1; p=none; sp=none;

3 配置域名 DNS 解析

裸域安装实例:

主机记录值 记录类型 记录值 备注
mail A e.g:1.2.3.4 记录值为自己的 IP 地址
@ MAX mail.example.com 记录值为自己的域名
@ TXT v=spf1 mx ~all
_dmarc TXT v=DMARC1; p=none; sp=none;
mail._domainkey TXT < 替换自己生成的 DKIM > 参考上面进行拼接

子域安装

主机记录值 记录类型 记录值 备注
mail A e.g:1.2.3.4 记录值为自己的 IP 地址
mail MAX mail.example.com 记录值为自己的域名
mail TXT v=spf1 mx ~all
_dmarc.mail TXT v=DMARC1; p=none; sp=none;
mail._domainkey.mail TXT < 替换自己生成的 DKIM > 参考上面进行拼接

其中 MX 记录需要指向 A 地址。

v=spf1 表示这是 SPF 记录的版本号,目前只有一个版本mx 表示授权由域名对应的 MX 记录中列出的 IP 地址发送邮件SoftFail 和 HardFail 是两种策略,用于指定未经授权的发件人邮件如何处理

~all 宽容策略。如果发件人的 IP 地址不在 SPF 记录中指定的允许列表中,那么收件方的邮件服务器不会拒绝该邮件,而是将该邮件标记为“软失败”,并将其放入接收方的垃圾邮件文件夹或者标记为垃圾邮件。-all 严格策略。如果发件人的IP地址不在 SPF 记录中指定的允许列表中,那么收件方的邮件服务器会拒绝该邮件,并将其退回给发件人或者直接删除

更多的 SPF 语法规则可以看这里 http://www.open-spf.org/SPF_Record_Syntax/。

4 设置 RTP(rDNS)(可选)

设置 PTR 记录(或者叫 rDNS),可以通过 IP 地址反向解析出邮箱域名。 不设置也没关系,但是会被某些服务器标记为垃圾邮件。rDNS 主要在控制台进行配置,可能有些厂商设置 RTP 是收费的,这里就不搞了,有兴趣的可以自己尝试尝试,艾特一下让我也学习学习🤞

6 常见的邮箱协议和端口

等我了解完全后更新 loading…

7 SSL 证书配置

网上大部分都是使用Let's Encrypt生成免费的证书。但是,我想说,我都在腾讯买域名了而且他提供了免费的证书,我直接用不好嘛🤣

当然也可以选择使用Let's Encrypt看个人选择嘛,具体申请教程,网上很多。官网也给出的配置教程,官网教程

这里教程是用的腾讯申请的免费证书,申请好后选择 Nginx 类型,这里只需要以keycrt结尾的文件

image.png

<code># 在/opt/mailserver/docker-data/dms下新建文件夹 custom-certs

cd /opt/mailserver/docker-data/dms

mkdir custom-certs

# 将 key 和 crt 文件上传到此文件夹下

# 停止docker容器

cd /opt/mailserver

docker compose down

修改conpose.yml文件

services:

mailserver:

.......... 上面都不动 ..........

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/

# 添加证书的挂载卷

- ./docker-data/dms/custom-certs/:/tmp/dms/custom-certs/:ro

- /etc/localtime:/etc/localtime:ro

environment:

- SSL_TYPE=manual

# 值应与容器内的文件路径匹配:

- SSL_CERT_PATH=/tmp/dms/custom-certs/mail.byteload.cn_bundle.crt

- SSL_KEY_PATH=/tmp/dms/custom-certs/mail.byteload.cn.key

restart: always

stop_grace_period: 1m

# Uncomment if using `ENABLE_FAIL2BAN=1`:

# cap_add:

# - NET_ADMIN

healthcheck:

test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"

timeout: 3s

retries: 0

启动容器

docker compose up

测试证书是否有效

docker exec mailserver openssl s_client \

-connect 0.0.0.0:25 \

-starttls smtp \

-CApath /etc/ssl/certs/

响应应显示证书链,并在下面显示一行:Verify return code: 0 (ok)

此示例在 DMS 容器本身内运行,以验证证书是否在本地运行。

如果从另一个系统进行外部测试,请调整 IP。此外,鼓励对端口 143 (Dovecot IMAP) 进行测试(将 -starttls 的协议从 smtp 更改为 imap)。-connect

-CApath将帮助验证证书链,前提是该位置包含签署 DMS 的 TLS 证书的根 CA。

如果你使用的是海外的服务器,到这里基本上配置就已经结束了,可以使用 Docker Mailserver 进行收发邮件

接收

由于Docker Mailserver没有提供图形化界面进行发送与接收邮件,所以需要借助第三方邮箱。这里推荐使用eM Client 用这个邮件客户端的主要原因在于如果连接有问题,它会给出一些提示。

发送

由于国内的服务器厂商绝大多数都是封锁 25 出站端口,申请解封也是无效的,只能使用中继来发送有效,当然使用国内的 smtp 中继实际接收方显示的发件地址为 smtp 平台的地址。例如:使用 163 邮箱进行中继,收件方显示的邮件发送地址为xxxxx@163.com。谷歌也是这样,当然这里也会给出使用 gmail 进行中继的教程。

这里的中继使用了postfix会的小伙伴可以不用看下面的教程了。

修改compose.yml文件

# 停止容器

docker compose down

# 修改文件内容

services:

mailserver:

.......... 上面不动 ..........

environment:

- SSL_TYPE=manual

# 值应与容器内的文件路径匹配:

- SSL_CERT_PATH=/tmp/dms/custom-certs/mail.byteload.cn_bundle.crt

- SSL_KEY_PATH=/tmp/dms/custom-certs/mail.byteload.cn.key

- DEFAULT_RELAY_HOST=[smtp.163.com]:465

- RELAY_HOST=smtp.163.com

- RELAY_PORT=465

- RELAY_USER=<your account>

- RELAY_PASSWORD=<your authorization code>

restart: always

stop_grace_period: 1m

# Uncomment if using `ENABLE_FAIL2BAN=1`:

# cap_add:

# - NET_ADMIN

healthcheck:

test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"

timeout: 3s

retries: 0

使用 163 邮箱中继(QQ 同理)

使用 163 中继的前提:开通了 POP3 服务,获得了授权码

修改compose.yml文件,在/opt/mailserver/docker-data/dms/config下 新建

postfix-main.cfsasl_passwdsender_canonical

修改postfix-main.cf文件

smtp_use_tls=yes

smtp_sasl_auth_enable=yes

smtp_tls_wrappermode=yes

smtp_tls_security_level=encrypt

smtp_sasl_security_options=noanonymous

smtp_sasl_type=cyrus

smtp_sasl_password_maps=hash:/tmp/docker-mailserver/sasl_passwd

# 设置发件人地址 不设置会出现 "553 mail from must equal authorized user"提示的错误

sender_canonical_maps=regexp:/tmp/docker-mailserver/sender_canonical

修改sasl_passwd文件

# 添加这行内容,保存退出

[smtp.163.com]:465 <your account>:<your authorization code>

# 生成 .db文件

cd /opt/mailserver/docker-data/dms/config

postmap ./sasl_passwd

修改sender_canonical文件

# 添加这行内容,保存退出

/.+/ <your account>

# 生成 .db文件

cd /opt/mailserver/docker-data/dms/config

postmap ./sender_canonical

# 启动容器

cd /opt/mailserver

docker compose up

# 测试发送和接收邮件

# 没出问题即可关闭使用后台运行

到此 使用 163 邮箱中继就结束了

使用 gmail 中继

使用 gmail 中继少许麻烦,因为国内因为某些原因是无法直接连接到 gmail 的,因此需要特定的方法。都是用 gmail 了,相信你肯定会的😎

gmail 现在只能使用授权码了,具体开启方法百度很多

compose.yml中添加网络代理和 gmail 账号

services:

mailserver:

image: ghcr.io/docker-mailserver/docker-mailserver:latest

........ 上面不动 ........

environment:

- HTTP_PROXY=<http://your proxy ip:port >

- HTTPS_PROXY=<http://your proxy ip:port >

- SSL_TYPE=manual

# 值应与容器内的文件路径匹配:

- SSL_CERT_PATH=/tmp/dms/custom-certs/mail.byteload.cn_bundle.crt

- SSL_KEY_PATH=/tmp/dms/custom-certs/mail.byteload.cn.key

- DEFAULT_RELAY_HOST=[smtp.gmail.com]:587

- RELAY_HOST=smtp.gmail.com

- RELAY_PORT=587

- RELAY_USER=<your account >

- RELAY_PASSWORD=<your authorization code>

restart: always

stop_grace_period: 1m

# Uncomment if using `ENABLE_FAIL2BAN=1`:

# cap_add:

# - NET_ADMIN

healthcheck:

test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"

timeout: 3s

retries: 0

修改postfix-main.cf

sasl_passwd文件对着 163 中继的方法修改即可

smtp_sasl_password_maps=hash:/tmp/docker-mailserver/sasl_passwd

# Enable TLS

smtpd_use_tls=yes

smtp_use_tls=yes

# Specify the TLS protocols

smtpd_tls_mandatory_protocols=!SSLv2, !SSLv3

smtp_tls_mandatory_protocols=!SSLv2, !SSLv3

# Specify the TLS ciphers

smtpd_tls_mandatory_ciphers=high

smtp_tls_mandatory_ciphers=high

# Enable TLS for SMTP client (when sending mail to external servers)

smtp_tls_security_level=encrypt

smtp_tls_loglevel=1

# Enable TLS for SMTP server (when receiving mail from external servers)

smtpd_tls_security_level=may

smtpd_tls_loglevel=1

# Use a specific TLS protocol version (e.g., TLSv1.2 or TLSv1.3)

smtpd_tls_protocols=!SSLv2, !SSLv3, !TLSv1, !TLSv1.1

smtp_tls_protocols=!SSLv2, !SSLv3, !TLSv1, !TLSv1.1

# 启动容器

cd /opt/mailserver

docker compose up

# 测试没问题即可后台运行

使用阿里云邮件推送服务

阿里云邮件推送服务,个人用户总免费 2000 封,单日上限 200 封。自己的用的话差不多够了。但是在别人在接收你邮件的时候,发送地址不是你原本的地址(origin)而是你在阿里云上设置的地址。

像腾讯云邮件推送,暂就不写教程 。

地址:阿里云邮件推送

依据官方教程配置即可

compose.yml

services:

mailserver:

....... 上面不动 .......

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/

- ./docker-data/dms/custom-certs/:/tmp/dms/custom-certs/:ro

- /etc/localtime:/etc/localtime:ro

environment:

- SSL_TYPE=manual

# 值应与容器内的文件路径匹配:

- SSL_CERT_PATH=/tmp/dms/custom-certs/mail.byteload.cn_bundle.crt

- SSL_KEY_PATH=/tmp/dms/custom-certs/mail.byteload.cn.key

restart: always

stop_grace_period: 1m

# Uncomment if using `ENABLE_FAIL2BAN=1`:

# cap_add:

# - NET_ADMIN

healthcheck:

test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"

timeout: 3s

retries: 0

修改postfix-main.cf

inet_interfaces = all

inet_protocols = ipv4

# 配置中继

relayhost = [smtpdm.aliyun.com]:465

smtp_sasl_password_maps=hash:/tmp/docker-mailserver/sasl_passwd

smtp_use_tls = yes

smtp_sasl_auth_enable = yes

smtp_tls_wrappermode = yes

smtp_tls_security_level = encrypt

smtp_sasl_security_options = noanonymous

smtp_sasl_type = cyrus

新建sasl_passwd并修改

[smtpdm.aliyun.com]:465 <your aliyun email domain>:<your account smtp key>

# 生成 .db文件

cd /opt/mailserver/docker-data/dms/config

postmap ./sasl_passwd

# 启动容器

cd /opt/mailserver

docker compose up

使用阿里云邮件推送服务在进行收发的时候会比较复杂,这里推荐使用雷鸟客户端进行配置

添加邮箱账户

正常输入登录你的 docker mailserver 的账号密码

image.png

登录成功后,需要设置 smtp 发送地址、发送邮箱以及回复邮箱才能正常的收发邮件

在这里插入图片描述

image.png

在这里插入图片描述

设置完成后回到 账户设置 页面,选择阿里云为 smtp 服务

测试发送邮件

填写完成后,即可发送邮件

查看是否发送成功,这里的发件人显示的是你在阿里云上设置的发信地址,而不是你 docker mailserver 设置的邮件地址,这里是比较坑的

在这里插入图片描述

测试回复

回复的时候,可能会提示,回复地址与原地址不一样,这就是上面坑导致的

继续回复即可

image.png

在这里插入图片描述

显示 origin 地址

以上使用 gmail 和 163 邮箱以及阿里云推送等转发会让原始的发件地址变化

这里推荐一个不会更改原始发件地址的 SMTP 服务Mailgun

Mailgun 的账号注册这里就不写了,网上也很多。

建议使用 gmail 账号进行注册,后面激活账号的时候会让填写手机号码,国内的可能会收不到短信验证码。可发邮件联系客服进行人工激活。实测,人工回复速度挺快的,激活速度也挺看的,全程不到 20 分钟。

注册成功后 Mailgun 会给一个沙盒测试域,这里不使用沙盒,点击左侧的导航栏 <code>Send -> Sengding -> Domains添加你的域名,然后根据提示在 DNS 解析商那里配置。

DNS 验证成功后设置 SMTP 的秘钥即可

配置 Mailgun 的 compose.yml 和配置阿里云的是一样,不会的看阿里云的配置

修改postfix-main.cf

inet_interfaces = all

inet_protocols = ipv4

# 配置中继

relayhost = [smtp.mailgun.org]:587

smtp_sasl_auth_enable = yes

smtp_sasl_password_maps = static:mailgun account:account smtp key

smtp_sasl_security_options = noanonymous

# TLS support

smtp_tls_security_level = may

smtpd_tls_security_level = may

smtp_tls_note_starttls_offer = yes

# 启动容器

cd /opt/mailserver

# 关闭容器

docker compose down

# 启动容器

docker compose up

配置完成后可用Java代码或则其他语言代码进行邮件发送的测试,根据不同的保存原因和服务日志进行调整

使用雷鸟或者 eM Client 进行正常的账号密码登录即可,登录完成后不需要更改其他设置即可使用。

到此邮件的配置就结束了,感兴趣的不妨给个点赞收藏,你的点赞收藏是我继续更新的动力❤



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。