Postfix 日志详解:maillog 排障、队列 ID 追踪与告警

Postfix 日志完整排障指南——maillog/journalctl 日志位置、结合主机和时间按 queue ID 追踪邮件的队列处理、常见报错(relay access denied、connection refused、deferred)含义解析,以及用观测云采集邮件日志并配置退信激增、队列积压告警。

最佳实践
Postfix 日志详解:maillog 排障、队列 ID 追踪与告警技术指南封面

Postfix 的日志通过 syslog 写入系统日志(通常是 /var/log/maillog 或 /var/log/mail.log),记录了每封邮件从进入队列(cleanup)、排队(qmgr)、投递尝试(smtp/smtpd/lmtp)到最终状态(sent/deferred/bounced)的完整生命周期——邮件系统排障的核心技能,就是用一个 queue ID 把散落在日志里的多行记录串成完整故事。

核心要点速览

  • 排障万能命令:grep 'QUEUE_ID' /var/log/maillog——结合主机和时间用 ID 串联队列处理;重新注入可能产生新 ID。
  • status=sent/deferred/bounced 三个状态词描述投递状态,deferred 并非最终结果;deferred 会重试,bounced 是终审。
  • 用观测云采集 Postfix 日志后,"队列积压""退信率激增""中继被拒"都能做成实时监控器告警。

Postfix 日志写在哪里?

  • RHEL/CentOS/Rocky:/var/log/maillog
  • Debian/Ubuntu:/var/log/mail.log
  • systemd 系统(不依赖 syslog 时):可先查 journalctl -u postfix,但 syslog/子进程记录未必都归入该 unit;还需按进程标识与实际日志配置检索

日志由多个子进程分别写入:smtpd(接收外部连接)、cleanup(入队前处理)、qmgr(队列调度)、smtp/lmtp(外发投递)、bounce(退信生成)。

如何用 queue ID 追踪一封邮件?

每封进队的邮件分配一个 queue ID(短格式常为十六进制,长格式也含其他字符)(如 4HxK2m1R3Yz9)。追踪命令:

grep '4HxK2m1R3Yz9' /var/log/maillog

典型输出按时间顺序呈现四个环节:

postfix/smtpd[1234]: 4HxK2m1R3Yz9: client=mail.example.com[203.0.113.5]
postfix/cleanup[1235]: 4HxK2m1R3Yz9: message-id=<abc@example.com>
postfix/qmgr[1236]: 4HxK2m1R3Yz9: from=<sender@example.com>, size=2413, nrcpt=1 (queue active)
postfix/smtp[1237]: 4HxK2m1R3Yz9: to=<user@dest.com>, relay=mx.dest.com[198.51.100.2]:25, delay=1.2, dsn=2.0.0, status=sent (250 OK)

读法要点:status=sent + 对方 250 应答表示该次投递已被下一跳接受,不代表最终邮箱收件或用户阅读;delay 应按邮件路径、重试和历史基线判断,没有统一一秒阈值;dsn 是标准投递状态码(2.x 成功、4.x 临时失败、5.x 永久失败)。

常见报错都意味着什么?

报错片段 含义 处理方向
Relay access denied 本机被当中继但收件域不在许可列表 检查 mydestination/relay_domains 与认证配置
Connection refused/timed out 对方 25 端口不通或防火墙拦截 云厂商常默认封出站 25 端口,需申请解封或走中继
status=deferred 临时失败,队列中等待重试 看紧随的原因行;postqueue -p 看积压
status=bounced 永久失败已退信 5.x DSN,常见收件人不存在/被拒收
warning: hostname ... does not resolve DNS 解析问题 检查本机 DNS、反向解析
lost connection after EHLO 对方中途断连 对方反垃圾策略或网络抖动

查看当前队列:postqueue -p;postqueue -f 是请求队列尝试投递的管理操作;postsuper -d QUEUE_ID 会删除邮件,均不是只读诊断。

Postfix 日志级别与调试

postconf maillog_file(3.4+ 直写文件)、postconf debug_peer_list(对指定对端开调试日志)、-v 追加到 master.cf 中对应服务(如 smtp unix - ... smtp -v)可临时提升详细度——排完障记得改回,调试日志量极大。

验证邮件日志采集与投递状态

  1. 采集:观测云 DataKit 磁盘文件采集配置读取 /var/log/maillog(或 mail.log),标注 service="postfix":
    [[inputs.logging]]
      logfiles = ["/var/log/maillog"]
      source = "postfix"
      service = "postfix"
    
    使用 systemd journal 时,先按 Syslog 接入说明配置转发,或确认 maillog_file 输出后再采文件。
  2. 解析:用一封测试邮件验证 Pipeline 提取的 queue ID、收发地址、dsn 与 delay。把 Postfix 的投递状态另存为 delivery_status,再映射日志标准 status,避免覆盖 sent/deferred/bounced 原值。
  3. 监控器告警(监控 > 监控器 > 日志检测):
    • 投递延迟:按 delivery_status=deferred 检查失败记录;它不能直接代替当前队列长度;
    • 退信激增:bounced 数量同比突增 → 可能是账号被盗发垃圾邮件;
    • 中继被拒:Relay access denied 出现 → 配置变更预警;
    • 无日志:先确认该窗口应有邮件活动,再检查进程与采集链路;低流量时无日志不等于进程故障。
  4. 看板:按 dsn 状态码、目标域、delay 分桶做图表,长期观察投递质量。

常见问题(FAQ)

Q:maillog 里找不到某封邮件的记录? 确认日志时间范围和轮转(mailog 可能被 logrotate 切成 maillog-日期);邮件可能根本没到达本机(先查 smtpd 的连接记录);或者被 reject 在入队前,只有 NOQUEUE: reject 行没有 queue ID。

Q:日志里大量 connect from unknown[...] 是什么? 公网邮件服务器被全网扫描是常态,unknown 通常表示客户端名称无法确认,不能仅据此认定无害;关闭开放中继也不能覆盖全部邮件安全风险,但值得关注认证失败(SASL authentication failed)的暴力破解。

Q:Postfix 3.4 之后还要装 rsyslog 吗? 不必须:maillog_file=/var/log/postfix.log 需配置相应 postlogd 服务等条件才能由内置日志机制写文件,早期错误等仍可能走其他输出;容器化部署常这么干,再把文件交给 DataKit 采集。

Q:怎么统计每天的收发量? 现成工具 pflogsumm 能按日汇总 maillog;在观测云里可按天统计,但要区分收件人投递尝试、队列事件和唯一邮件;不能把每条 sent/deferred 记录直接当一封独立邮件。

系列阅读

[1]: 观测云文档《DataKit 日志采集综述》https://docs.guance.com/integrations/datakit-logging/
[2]: 观测云文档《监控》https://docs.guance.com/monitoring/
[3]: 观测云文档《日志查看器》https://docs.guance.com/logs/explorer/

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台