
一、为什么需要这套方案?
当你在云服务器尝试搭建邮箱服务时,常常会遇到运营商封锁 25 端口的难题,25 端口就像邮局的发货通道,一旦被封,你的邮件服务器就像被没有腿的邮递员,无法对外发送信件
如果无法解除此端口的屏蔽,需要通过其他服务来转发出站邮件,以便其他服务代您发送。我的解决方案是使用 Resend,也就是让人帮他送
并且我需要一台可以创建无限邮箱地址的服务器,因为有个网站会每隔一段时间给账户发兑换码:)方便我白嫖,还有我用邮箱注册了数百个网站,验证码都发在一堆不方便管理,有了自己的服务器后可以按照网站随便注册
比如说,我需要注册 Bilibili,那么邮箱就填 bilibili@qladgk.com ,我不用在服务器中手动添加这个邮箱,可以直接设置一个规则,让不存在的邮箱接受的邮件全部转发给 info@qladgk.com,这样所有的验证码都在 info 这个邮箱。如果哪天我的邮箱泄露,可以很方便的知道是哪个网站对应的邮箱
二、准备你的工具箱
工具/服务 | 作用说明 | 获取方式 |
---|---|---|
Docker | 容器化部署环境 | 官网下载 |
Resend 账户 | 邮件中继服务(每月免费额度 3000 封) | 注册 |
域名 | 邮箱域名(如 qladgk.com) | 域名注册商购买 |
SSL 证书 | 加密通信保障 | 使用受信任的 CA 颁布的证书 |
三、五步搭建实战
步骤 1:创建目录结构
mkdir -p mail.qladgk.com/docker-data/{dms/config,certs}
cd mail.qladgk.com
我个人喜欢在服务器的 ~
位置创建用具体域名的文件夹来管理,所以就用了 mail.qladgk.com,然后需要确认你的 SSL 证书中有这个域名
步骤 2:准备 docker-compose.yml
# docker-compose.yml
version: "3.8"
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.qladgk.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/
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/
- ./docker-data/certs/:/tmp/certs/ # 修改成你的证书目录
- /etc/localtime:/etc/localtime:ro
environment:
- SSL_TYPE=manual # 如果要手动设置路径证书类型必须是手动
- SSL_CERT_PATH=/tmp/certs/nginx.crt # 改成你自己的证书地址
- SSL_KEY_PATH=/tmp/certs/nginx.key # 改成你自己的证书地址
- DEFAULT_RELAY_HOST=[服务商获取]:端口 # 中继服务主机
- RELAY_USER=服务商获取 # 中继服务用户名
- RELAY_PASSWORD=服务商获取 # 中继服务密码
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
与官网的 compose 对比只修改了这些部分:
hostname: mail.qladgk.com # 修改为你的域名
volumes:
- ./docker-data/certs/:/tmp/certs/ # 准备你的域名证书
environment:
- SSL_TYPE=manual # 如果要自定路径证书类型必须选手动
- SSL_CERT_PATH=/tmp/certs/certs.crt # 根据自己的证书名设定
- SSL_KEY_PATH=/tmp/certs/certs.key # 根据自己的证书名设定
- DEFAULT_RELAY_HOST=[服务商获取]:端口 # 中继服务主机
- RELAY_USER=服务商获取 # 中继服务用户名
- RELAY_PASSWORD=服务商获取 # 中继服务密码
然后还需要将官网的 mailserver.env 下载下来,这个文件尽量不要改动,东西很多容易错,我们就用 Docker 的环境变量就好,而且环境变量优先于 mailserver.env
步骤 3:配置 Postfix 中继主机
注册好 Resend 后添加域名并且使用 DNS 验证

然后需要等待验证通过,可能需要两三分钟

然后就可以设置主机、用户名、密码了,修改 docker-compose.yml
- DEFAULT_RELAY_HOST=[smtp.resend.com]:587
- RELAY_USER=resend
- RELAY_PASSWORD=创建一个 api 就是密码
以上配置是根据 Resend 设置,在官网的这个地方

默认用户名应该都是 resend,密码就是你创建的 apikey
步骤 4 :初始化邮件服务器
# 首次启动初始化
docker compose up -d
# 在 120 秒内创建管理员邮箱
docker exec mailserver setup email add postmaster@qladgk.com <你的邮箱密码>
# 然后创建一个自己用的邮箱
docker exec mailserver setup email add hi@qladgk.com <你的邮箱密码>
# 生成 DKIM 签名
docker exec -it mailserver setup config dkim
将 docker-data/dms/config/opendkim/keys/qladgk.com/mail.txt
里 ()
中的复制出来,并删掉其中的 ""
和 多余的空格
拼接成一行备用
比如生成的 txt 如下

拼接之后的 txt 如下:
v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAybULjMm1Pv2qn8l0SIan+I8NpBTanNQaVFNVLvR5We9QITGAfxJtVUJv9e9e0BV3XVR/hDWRwxfw4KG6szRzUB1VABp4knYgwr1i3UNgKag3pSgTS4v1k5BccwIod/UK/E6+6iRiIzVoTikd3eSuygDAnAf+/FbZcnVF2Y/W4BvC9+aOyyDUYVCsSmPMgK99fm6fj5Q1LGMAvDapZ4XP+A7aFIHOL+AffPquPcsPAymJgC9guOJH4+D+ejqL5T6loTIljcGzcbavd82sRt01BxX3vRWqsqQ4K5I3yNVX5aLm1vrk5EIssGlyKxjjW9c2+6N7TUz6BD78AaKQmlBlfwIDAQAB
步骤 5:配置 DNS 记录
类型 | 名称 | 值 | 说明 |
---|---|---|---|
A | 你的服务器 ip | 邮件路由 | |
MX | @ | mail.qladgk.com | 优先级设置成 10 |
TXT | @ | v=spf1 mx -all | SPF 发件人验证 |
TXT | _dmarc | v=DMARC1; p=none; | DMARC 记录 |
TXT | mail._domainkey | 刚才准备的那串 txt | DKIM 记录 |
算上开始配置的 Resend 的 DNS ,你的 DNS 解析应该如下
类型 | 名称 | 值 | 说明 |
---|---|---|---|
A | 你的服务器 ip | 邮件路由 | |
MX | @ | mail.qladgk.com | 优先级设置成 10 |
TXT | @ | v=spf1 mx -all | SPF 发件人验证 |
TXT | _dmarc | v=DMARC1; p=none; | DMARC 记录 |
TXT | mail._domainkey | 刚才准备的那串 txt | DKIM 记录 |
---- | ---------------- | ------------------ | --------------- |
MX | send | Resend 提供的值 | 优先级设置成 10 |
TXT | send | Resend 提供的值 | SPF 发件人验证 |
MX | resend._domainkey | Resend 提供的值 | DKIM 记录 |
这里同时配置了两个邮箱的 SPF/DKIM ,因为最后邮件是 Resend 用 @send.qladgk.com 这个邮箱地址代发,那么 send.qladgk.com 子域的 SPF/DKIM 记录确实需要按 Resend 要求配置。同时,根域名 @ 的 DMARC 记录对于邮件 From: 是 user@qladgk.com 的情况仍然重要,它需要与 send.qladgk.com 的 SPF/DKIM 对齐(通常是宽松对齐)。
四、验证你的邮箱系统
发送测试邮件
使用雷鸟客户端,添加邮箱账户和密码

这里的收件和发件都是 mail.qladgk.com
是没有问题的
添加账户后给你的 163 或者 qq 尝试发送邮件,可以看到成功收到

发件人是 hi@qladgk.com 后面显示的是由 xxxxx@send.qladgk.com 代发
测试 163 直接回复

可以看到直接回复的是 origin 地址而不是代发地址
给 https://www.mail-tester.com/ 发送测试邮件,查看邮件评分

同时你也能看见 Resend 中帮你转发的邮件

接收邮件测试

发现我们的 hi@qladgk.com 邮箱成功接收到 163 发来的邮件,但是 Resend 中没有接收记录,后面会解释
五、原理解释
涉及的服务器与 DNS 配置
自建服务器配置(mail.qladgk.com)
类型 | 完整主机名 | 值示例 | 作用说明 |
---|---|---|---|
A | mail.qladgk.com | 11.22.33.44 | 邮件服务器 IP 地址 |
MX | @qladgk.com | mail.qladgk.com | 声明主域名的邮件服务器地址(优先级 10) |
TXT | @qladgk.com | v=spf1 mx -all | 仅允许 mail.qladgk.com 的 IP 发送邮件(防御伪造) |
TXT | mail._domainkey.qladgk.com | v=DKIM1; p=公钥... | 邮件数字签名公钥(防止邮件被篡改) |
Resend 中继配置(send.qladgk.com)
类型 | 完整主机名 | 值示例 | 作用说明 |
---|---|---|---|
MX | send.qladgk.com | feedback-smtp.us-east-1.amazonses.com | Resend 要求的特殊 MX 记录(用于建立发送域身份) |
TXT | send.qladgk.com | v=spf1 include:amazonses.com ~all | 授权 Resend 的服务器代发邮件 |
TXT | resend._domainkey.qladgk.com | k=rsa; p=公钥... | Resend 提供的 DKIM 公钥(验证邮件来源合法性) |
全局反垃圾邮件策略
类型 | 完整的主机名称 | 值示例 | 作用 |
---|---|---|---|
TXT | _dmarc.qladgk.com | v=DMARC1; p=none; | 邮件验证策略(告知收件方如何处理验证失败的邮件) |
也就是说我们一共在解析中设置了两个 MX 方式,所以会出现两个邮箱地址 比如 hi@qladgk.com 和 hi@send.qladgk.com
涉及到的端口和认证信息
为了让主机认证我们,需要提供端口和账户密码
在 IMAP 邮件服务器中常见的端口分别如下
端口 | 协议 | 使用场景 | 加密方式 |
---|---|---|---|
25 | SMTP | 服务器之间的邮件传输 | 无 |
465 | SMTP over SSL | 客户端到服务器的加密邮件发送 | SSL/TLS |
587 | SMTP with STARTTLS | 客户端到服务器的加密邮件发送 | STARTTLS |
143 | IMAP | 客户端从服务器接收邮件(不加密) | 无 |
993 | IMAP over SSL | 客户端从服务器加密接收邮件 | SSL/TLS |
这里容易混淆,需要慢慢理解
┏━━━━━━━━━━ Submission ━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━ Transfer/Relay ━━━━━━━━━━━┓
┌─────────────────────┐ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
MUA ----- STARTTLS -------> ┤(587) MTA ╮ (25)├ <-- cleartext ---> ┊ Third-party MTA ┊
----- implicit TLS ---> ┤(465) │ | └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
----- cleartext ------> ┤(25) │ |
|┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄|
MUA <---- STARTTLS -------- ┤(143) MDA ╯ |
<---- implicit TLS ---- ┤(993) |
└─────────────────────┘
┗━━━━━━━━━━ Retrieval ━━━━━━━━━━━━━━┛
MUA 是客户端、MTA 是服务器
发邮件过程会经理 MUA - MTA - MTA - MUA 这过程,我们所说的加密邮件指的是 MTA 与 MUA 之间的过程,而 MUA 之间的传输我们不能干预

之所以之前只能接受邮件而不能发送,是因为服务器封锁 25 端口的出站流量,而没有封锁入站流量。如下图:

可以看到用服务器通过 25 去访问别人的 stmp 会失败,但是个人电脑上去访问服务器的 25 则成功
接下来是认证信息
其中邮箱客户端(雷鸟)里:
- imap 主机是 mail.qladgk.com、端口是 993(SSL/TLS 加密方式)、用户名是邮箱、密码是邮箱密码
- smtp 主机是 mail.qladgk.com、端口是 587(STARTTLS 加密方式)、用户名是邮箱、密码是邮箱密码
因为接受邮件只有 993 有加密,所以选他。关于 465 和 587 选谁网上说法不一,但是 587 是现在邮箱常见默认端口,所以选他
而我们的 Resend 的 SMTP 的认证信息则直接存放在 docker-mailserver 里
# 配置中继
relayhost = [smtp.resend.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = static:resend的用户名:resend的密码
smtp_sasl_security_options = noanonymous
这里的 587 指的是我们的邮件服务器现在作为客户端与 Resend 服务端通过 STARTTLS 加密方式将邮件传到他们的 STMP 上
邮件发送流程(中继模式):
- 客户端提交:雷鸟通过加密连接将邮件提交到 mail.qladgk.com(587 端口),使用邮箱账户密码认证
- 中继路由决策:Postfix 检测到目标为外部域(如 163.com),根据 relayhost = [smtp.resend.com]:587 启动中继流程
- 中继服务器认证:使用 SASL 认证机制,通过 Resend 提供的 API Key 完成身份验证:
- 信封发件人重写:Resend 会将信封发件人(Envelope From)改为 xxx@send.qladgk.com,这是邮件显示"代发"的原因
- 最终投递:Resend 通过 25 端口将邮件投递到目标服务器,完全绕开本地服务器的出站限制
所以最后收到的邮件的代发人是 xxx@send.qladgk.com
邮件接收流程
- MX 记录查询:外部服务器(163)给 hi@qladgk.com 发邮件时通过 MX 记录找到他的邮件服务器(mail.qladgk.com)
- 直接投递:发送方通过 25 端口直连你的服务器(云厂商通常允许入站 25 端口)
- 本地存储:Postfix 将邮件存入 /var/mail/ 目录下的用户邮箱
- 客户端同步:雷鸟通过 IMAPS(993 端口)加密拉取邮件
为什么接收邮件不经过 Resend?
接收流程是标准的邮件服务器间直接通信(Server to Server),仅依赖:
- 正确的 MX 记录指向
- 25 端口的入站连接(通常云厂商允许入站 25 端口)
- 有效的 SSL 证书
而发送时需要出站 25 端口连接(被禁止),因此需要通过中继 "借道" 发送。
Resend 的角色
Resend 在本方案中充当邮件中继服务器,主要负责将你的邮件投递到目标邮箱服务器。
通过配置 Postfix 的 relayhost 参数,将本地邮件服务器的发送任务委托给 Resend 的 SMTP 服务器。
Resend 提供了每月 3000 封免费额度,对于个人用户或小型团队来说,基本可以满足日常需求。
六、常见问题排雷
1. 邮件进入垃圾箱
- 检查 SPF/DKIM/DMARC 记录
- 申请反向解析 PTR
其中阿里云的 PTR 很好申请,发个工单就行,三分钟分钟之内添加好

我是这么发的:
主题:
申请添加PTR记录
内容:
尊敬的阿里云售后工程师:
您好!我正在搭建邮件服务器,需要为我的服务器添加 PTR 记录,以便提高邮件的送达率。现向您提交申请,以下是相关信息:
ECS 实例所属地域:[具体地域,如北京、深圳等]
ECS 实例的公网 IP 地址:[公网IP地址]
对应的域名:[域名]
请协助我完成 PTR 记录的添加,谢谢!
2. 客户端连接失败
# 检查端口监听状态
docker exec mailserver netstat -tulpn | grep -E '25|587'