自建邮局排查指南
自建邮局能发不能收,是很常见的坑。发信和收信走的是两条完全不同的链路:发信靠出站 SMTP,收信则依赖 MX 记录、入站 25 端口、本地域名配置,以及客户端通过 IMAP / POP3 取信的能力——任何一环出问题都会导致收信失败。
不管你是"别人发给我的邮件根本收不到",还是"服务器上明明有邮件,客户端却看不到",都可以按本文的顺序逐层排查,比一上来就翻配置文件更高效。
先判断故障发生在哪一层
在动手之前,先把问题分成下面三类:
- 外部发件人根本投递不进来
重点检查
MX、A/AAAA、公网25端口、反向解析和服务器是否真的在监听。 - 服务器已经收到了邮件,但客户端读不到
重点检查
IMAP/POP3监听、TLS 证书、账号认证、邮箱配额和客户端配置。 - 手动配置能用,但自动配置失败
重点检查自动发现接口、
SRV记录,以及客户端的自动发现机制。
如果你不确定属于哪一类,最简单的办法是同时做两件事:
- 用外部邮箱(如 Gmail、Outlook)给你的域名发一封测试邮件。
- 立即查看服务器日志,确认这封邮件有没有到达。
只要日志里完全没有新的入站记录,问题大概率还停留在 DNS、网络或 25 端口这一层。
1. 先检查 DNS 解析
收信链路里,DNS 是第一关。MX 错了,后面的配置再正确也没用。
I. 检查 MX 记录
dig example.com MX需要确认两点:
MX记录确实存在。MX指向的是一个域名,而不是 IP 地址。
例如下面这种写法才是正常的:
example.com. 300 IN MX 10 mail.example.com.II. 检查 MX 指向的 A/AAAA 记录
dig mail.example.com A
dig mail.example.com AAAAMX 指向的主机名必须能继续解析到可访问的公网地址。
这里有一个很常见的坑:AAAA 记录存在,但服务器其实没有正确配置 IPv6。这样一来,部分发件方会优先走 IPv6 投递,结果表现为“有些邮件能收到,有些收不到”。如果你暂时不打算支持 IPv6,宁可先去掉错误的 AAAA 记录,也不要让它半通不通。
III. 检查 PTR 反向解析
dig -x <服务器公网IP>虽然 PTR 错误不一定会导致完全无法收信,但它会显著影响投递质量,某些服务商也会更严格地对待这类主机。理想情况是:
- 公网 IP 的
PTR指回你的邮件主机名,例如mail.example.com - 这个主机名再正向解析回同一个 IP
IV. 注意 DNS 生效延迟和本地缓存
如果你刚改过记录,别忘了考虑两件事:
- 解析未完全传播,外部仍在命中旧记录
- 本地机器或路由器缓存了旧结果
可以额外做一次查询验证:
dig +short example.com MX
dig +short mail.example.com A
dig +short mail.example.com AAAA2. 确认入站端口是否真的可达
“发信正常”经常会让人误以为网络没问题,但这只能说明出站路径大致可用,并不能证明别人可以从公网连到你的服务器。
I. 优先测试 SMTP 25 端口
如果外部邮件根本投递不进来,最应该先查的是 25 端口:
nc -zv -w 3 mail.example.com 25如果你还要顺手检查客户端收信相关端口,可以一起测:
nc -zv -w 3 mail.example.com 143
nc -zv -w 3 mail.example.com 993
nc -zv -w 3 mail.example.com 110
nc -zv -w 3 mail.example.com 995
nc -zv -w 3 mail.example.com 465
nc -zv -w 3 mail.example.com 587II. 常见邮件端口对照
| 服务 | 端口 | 用途 | 加密方式 |
|---|---|---|---|
| SMTP | 25 | 服务器间收发信 | 无/STARTTLS |
| SMTP | 587 | 客户端提交发信 | STARTTLS |
| SMTPS | 465 | 客户端提交发信 | SSL/TLS |
| IMAP | 143 | 客户端收信 | STARTTLS |
| IMAPS | 993 | 客户端收信 | SSL/TLS |
| POP3 | 110 | 客户端收信 | STARTTLS |
| POP3S | 995 | 客户端收信 | SSL/TLS |
III. 不要只看服务器防火墙
端口不通时,问题可能出在下面任意一层:
- 服务器本机防火墙没有放行
- 云厂商安全组或网络 ACL 没开
- 路由器或 NAT 没有做端口转发
- 宿主机到容器的端口映射不正确
- 上游运营商或机房对邮件端口有限制
如果你部署在家宽或某些云平台上,25 端口尤其值得重点确认。有些环境不是“服务没启动”,而是上游直接不让你接这类连接。
IV. 其他检测方式
nmap -p 25,110,143,465,587,993,995 mail.example.com
curl -v --connect-timeout 3 telnet://mail.example.com:25如果你希望完全不依赖外部工具,也可以用 Bash 自带的 TCP 探测:
(echo >/dev/tcp/mail.example.com/25) && echo "开放" || echo "关闭"3. 检查 TLS 和证书
如果问题表现为“服务器能收到邮件,但客户端连 IMAP/POP3 总是报证书错误、握手失败或一直转圈”,那下一步就该看 TLS。
I. 测试隐式 TLS 端口
openssl s_client -connect mail.example.com:993 -servername mail.example.com
openssl s_client -connect mail.example.com:465 -servername mail.example.com
openssl s_client -connect mail.example.com:995 -servername mail.example.comII. 测试 STARTTLS 端口
openssl s_client -connect mail.example.com:143 -servername mail.example.com -starttls imap
openssl s_client -connect mail.example.com:587 -servername mail.example.com -starttls smtp
openssl s_client -connect mail.example.com:110 -servername mail.example.com -starttls pop3注意:
openssl s_client -starttls的协议协商并不总是可靠的——有些服务器在 STARTTLS 之前要求先完成认证或特定交互,openssl做不到这些,就会导致测试失败,但服务器本身其实没问题。如果隐式 TLS 端口(993/465/995)全部通过,而 STARTTLS 端口全部失败,大概率是测试工具的局限,而不是服务器配置有误。大多数客户端默认使用隐式 TLS 连接,所以只要隐式 TLS 正常,收信一般不受影响。
III. 快速提取证书信息
openssl s_client -connect mail.example.com:993 -servername mail.example.com 2>/dev/null | openssl x509 -noout -subject -issuer -datesIV. 常见证书问题
最常见的几类问题通常是:
- 证书是自签的,客户端默认不信任
- 证书上的域名与客户端连接用的域名不一致
- 证书已经过期
- 服务端口根本没有正确启用 TLS,输出里会看到
no peer certificate available
要注意一点:SMTP 25 端口缺少 TLS 并不一定会让收信完全失败,但 IMAP / POP3 端口的 TLS 配置错误,往往会直接表现为“明明有邮件,但客户端就是登录不了”。
4. 检查邮件服务本身
如果 DNS 和端口都没问题,接下来就该确认邮件服务本身有没有正确对外提供“收信”和“取信”能力。
I. 确认服务监听在公网地址
先看相关端口到底监听在什么地址上:
ss -tlnp | rg ':(25|110|143|465|587|993|995)\\b'正常情况下,至少应该看到服务监听在 0.0.0.0、[::] 或你的公网可达地址上。
如果只监听在 127.0.0.1 或 ::1,那外部客户端当然连不上。
II. 确认服务器愿意接收你的域名
这是另一个非常常见的配置问题:服务启动了,端口也通,但服务器根本没把 example.com 当作本地域名处理。
不同邮件服务器的叫法不完全一样,但你需要检查的本质都是同一件事:
- 你的域名是否被列入本地投递域名
- 该域名下的邮箱账号或别名是否真实存在
- 邮件到达后是否有正确的投递目标
如果这一层配置有误,常见表现是:
- 外部会收到
relay access denied - 服务器把发给你自己的邮件当成要继续转发的外部邮件
- 日志里能看到邮件进来,但最终被拒收或落到了错误的位置
III. 检查账号、配额和本地存储
如果外部投递已经成功,但客户端看不到邮件,还要继续排查:
- 该账号是否真的存在
- 邮箱是否已满
- 邮件是否被投递到了意料之外的文件夹
- 是否有过滤规则把邮件转移、归档或删除了
IV. 留意封禁和限速策略
很多人排查时只盯着主配置,却忘了还有额外的访问控制层,例如:
- fail2ban 或类似封禁工具
- 服务自身的 IP 黑名单或灰名单
- 登录失败后的限速或临时封锁
这类问题特别像“偶发故障”:同一套配置,在一台设备上能连,在另一台设备上又不行。
V. 直接看日志
日志通常比猜配置更快。无论你是系统服务、容器还是面板部署,都应该优先找到最近几十行日志:
journalctl -u <你的邮件服务> --no-pager -n 100
docker logs <你的邮件容器> --tail 100重点关注这些关键词:
connectrejectrelaytlscertificateauthentication failedtimeoutrate limitmailbox full
如果你在外部发出测试邮件的同时盯着日志,往往几分钟内就能判断问题是在“进不来”还是“进来了但处理失败”。
5. 检查客户端自动发现
如果手动填服务器地址和端口可以正常收发,但 Thunderbird、Outlook 或手机系统的自动配置失败,那问题通常不在收信本身,而在“自动发现”这层。
I. 常见自动发现方式
不同客户端会使用不同机制,常见的有:
Autoconfig例如https://autoconfig.example.com/mail/config-v1.1.xmlAutodiscover例如https://autodiscover.example.com/autodiscover/autodiscover.xmlDNS SRV记录 例如_imaps._tcp、_submission._tcp- 猜测常见主机名
例如
mail.example.com、imap.example.com、smtp.example.com
II. 可以先直接验证相关地址
curl -v "https://autoconfig.example.com/mail/config-v1.1.xml"
curl -v "https://autodiscover.example.com/autodiscover/autodiscover.xml"如果这些地址根本打不开、证书不对,或者返回内容不是客户端期望的格式,那么自动配置自然会失败。
III. 常见 SRV 记录示例
| 记录类型 | 主机记录 | 记录值 |
|---|---|---|
| SRV | _imaps._tcp |
0 1 993 mail.example.com. |
| SRV | _imap._tcp |
0 1 143 mail.example.com. |
| SRV | _submissions._tcp |
0 1 465 mail.example.com. |
| SRV | _submission._tcp |
0 1 587 mail.example.com. |
| SRV | _pop3s._tcp |
0 1 995 mail.example.com. |
IV. 手动配置往往是最快的验证方式
如果你只想先确认服务本身是否可用,直接手动配置通常更高效:
| 项目 | 服务器 | 端口 | 安全 |
|---|---|---|---|
| 收信 IMAP | mail.example.com | 993 | SSL/TLS |
| 发信 SMTP | mail.example.com | 465 | SSL/TLS |
只要手动配置能通,就说明“邮件服务”本身大概率没问题,剩下只是自动发现资料没补齐。
6. 排除本地网络和缓存干扰
有些“收信异常”其实不是服务器坏了,而是你当前网络环境在捣乱。
I. 先换一个网络再试
如果出现下面这些现象,很值得怀疑本地网络或运营商干扰:
nc能连上,但 TLS 握手异常中断- 同一账号在手机热点下正常,在公司或家里网络下异常
- 只有个别设备、个别网络环境出问题
最简单的验证方式是:
- 用手机热点再试一次
- 开 VPN 再试一次
- 换另一台设备再试一次
II. 必要时抓包看连接有没有到服务器
如果你有服务器权限,可以直接在服务端抓包确认客户端流量是否到达:
sudo tcpdump -i any -n 'port 25 or port 993'观察思路很简单:
- 客户端连接根本没到服务器,优先查 DNS、路由、端口映射
- 连接到了服务器,但服务没有回应,优先查服务状态和 TLS
- 连接到了服务器,服务器立刻拒绝,优先查认证、封禁和访问策略
III. 清理本地缓存
改过 DNS 或证书后,还可以顺手排查一下本地缓存:
sudo resolvectl flush-caches
resolvectl query mail.example.com
grep example /etc/hosts如果 hosts 里残留了旧记录,或者系统还在使用旧解析结果,排查方向很容易被带偏。
7. 用命令行做一次最小化验证
图形客户端的信息往往不够直接。怀疑客户端本身有问题时,可以用命令行做一次最小验证。
I. 测试 IMAP 登录
curl -v --url "imaps://mail.example.com/INBOX" --user "[email protected]:密码"只要这一步能成功列出或访问邮箱内容,说明至少下面几层已经基本打通:
- 域名解析
993端口连通- TLS 握手正常
- 用户名和密码正确
- IMAP 服务可用
II. 手动与 IMAP 服务交互
openssl s_client -connect mail.example.com:993 -servername mail.example.com -quiet连接后可以手工输入:
a1 LOGIN [email protected] 密码
a2 LIST "" "*"
a3 SELECT INBOX
a4 LOGOUT这种方式虽然原始,但在排查“到底是客户端问题,还是服务器问题”时非常直接。