postfix默认不能直接发外网邮件,必须配置relayhost中继至gmail等第三方smtp,并启用tls+sasl认证、正确设置sasl_passwd权限与dns解析。

Postfix 默认不发外网邮件,想让 mail 命令或脚本发出的邮件能到达 user@gmail.com 这类公网邮箱,必须显式配置中继(relayhost),靠本地投递或直连目标 MX 几乎必然失败——Gmail、Outlook 等服务商主动屏蔽来自云服务器 IP 段的直连 SMTP 请求。
为什么不能直接发到 gmail.com?
不是 Postfix 配错了,而是公网邮箱服务商(Gmail / Outlook / Yahoo)默认拒绝来自动态 IP、云主机段、无反向 DNS 或缺失 SPF 记录的 IP 的直连连接。你看到的 status=bounced (Host or domain name not found) 或 Connection timed out,大概率是被对方防火墙静默丢包,而非 DNS 或网络层问题。
真实原因常被误判,排查顺序应为:
- 先确认
nslookup smtp.gmail.com能返回 IP —— 否则 DNS 确实崩了 - 再用
telnet smtp.gmail.com 587测试端口可达性 —— 失败说明防火墙或网络策略拦了 outbound 587 - 最后看
postqueue -p:如果邮件卡在队列里,且日志(journalctl -u postfix -n 30)出现NOQUEUE: reject但没提具体原因,90% 是 relayhost 未生效或 SASL 凭据权限不对
Postfix 中继必须配这三样
只改 main.cf 里的 relayhost 行远远不够。缺一不可:
-
relayhost = [smtp.gmail.com]:587—— 方括号强制绕过 MX 查询,直连;端口必须匹配加密方式(587 对应 STARTTLS,465 对应 SSL) -
smtp_sasl_auth_enable = yes且smtp_sasl_security_options = noanonymous—— 否则 Gmail 拒绝认证 -
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt(Debian/Ubuntu)或/etc/pki/tls/certs/ca-bundle.crt(RHEL/CentOS)—— TLS 握手需要可信 CA,否则报SSL handshake failed
漏掉任意一项,Postfix 都会静默失败,日志里只有泛泛的 connect to smtp.gmail.com[...]: Connection timed out。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
sasl_passwd 权限和哈希是最大坑点
Postfix 读取 /etc/postfix/sasl_passwd 时,对文件权限极其敏感:必须是 root 所有、600 权限,且不能是符号链接。哪怕只是 chmod 644,它就直接跳过认证,不报错也不提示。
正确操作流程:
- 写入凭证:
echo "[smtp.gmail.com]:587 your.name@gmail.com:your_app_password" > /etc/postfix/sasl_passwd - 生成哈希:
postmap /etc/postfix/sasl_passwd(会生成sasl_passwd.db) - 收紧权限:
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db - 重载配置:
systemctl reload postfix
常见错误:用普通用户编辑文件、忘记 postmap、或把密码写成 Gmail 登录密码(必须是两步验证后生成的“应用专用密码”)。
测试中继是否真生效
别只信 echo "test" | mail -s "hi" user@gmail.com 是否“没报错”——它可能把邮件塞进队列就返回了。真正验证要分两步:
- 立刻查队列:
mailq或postqueue -p。如果队列为空,说明邮件已尝试投递;如果有条目,说明卡在 relay 环节 - 盯日志:
tail -f /var/log/mail.log | grep -i "gmail\|relay\|sasl"。成功发送会看到类似status=sent (250 2.0.0 OK ...);失败则暴露在哪一步断开(DNS、连接、认证、TLS)
最易忽略的是时间偏差:若系统时间比真实时间快/慢超过 5 分钟,Gmail 会直接拒绝 TLS 握手,日志只显示 SSL_connect error,不提时间问题。










