Rocky Linux 9 搭建 Postfix + Dovecot 邮件服务器(附 CentOS 7 差异)
需要自己掌控邮件收发——比如给内部系统发告警、给注册用户发通知——可以用 Postfix 做发送(MTA),Dovecot 做接收(IMAP/POP3),两者配合就是一套够用的自建邮件服务。本文主环境为 Rocky Linux 9,从安装、双配置检查到本机投递闭环全部在容器里实测通过:postfix check 无输出、25/143 正常监听、测试邮件在 maillog 里留下 status=sent (delivered to maildir)。
跨服务器的收发依赖 MX 记录和 25 端口连通性,这部分容器验证不了,文末标注了验证边界;老读者关心的 CentOS 7 差异集中在「历史版本差异」一节。
前置条件
- Rocky Linux 9(或同系 RHEL 9 发行版),root 权限;
- 一个可用的域名(本文以 example.com 为例),能把 A/MX 记录指到这台机器;
- 25/110/143 等端口未被云厂商封禁(多数云默认封 25,发信需申请解封)。
一、安装必要的软件
安装 Postfix、Dovecot,以及用于安全通信的 cyrus-sasl-plain:
1 | dnf install postfix dovecot cyrus-sasl-plain |
装完先补一条容易漏的:执行 newaliases 生成 /etc/aliases.db。不生成它,本地投递会一直卡在 deferred,maillog 报 alias database unavailable(实测踩到,详见常见报错)。
1 | newaliases |
再确认版本,写进你的部署记录里。实测输出(Rocky Linux 9 容器):
1 | postconf mail_version && dovecot --version |

二、配置 Postfix
编辑主配置文件:
1 | vi /etc/postfix/main.cf |
添加或修改以下行,搭起基本的邮件服务:
1 | myhostname = mail.example.com |
注:原文这份清单里还有一行
mta_sts_policy = enforce。实测 Postfix 3.5.25 对它只报unused parameter警告、不阻断 check,但它不是有效配置;稳妥做法是从 main.cf 删掉,MTA-STS 如需落实走官方文档的独立方案。
几个关键项:
- myhostname:邮件服务器的主机名。
- mydestination:设置邮件可以送达的域名。
- home_mailbox:用户的邮箱目录,
Maildir/格式即每封邮件一个文件。 - smtpd_sasl_auth_enable:启用 SASL 认证,认证工作交给 Dovecot 完成。
- smtpd_recipient_restrictions:只允许本机网络和通过 SASL 认证的用户发信,其余未知目的地一律拒绝,避免被当成开放中继滥用。
改完先做语法检查,无输出即为合法(实测通过,退出码 0):
1 | postfix check |
再重启并设置开机自启:
1 | systemctl restart postfix |
验证服务状态:systemctl status postfix 应看到 active (running)。容器环境没有 systemd,实测用 postfix start 直接拉起,效果等价。
三、配置 Dovecot
Dovecot 负责邮件的接收(IMAP/POP3),同时给 Postfix 提供 SASL 认证服务。编辑主配置文件:
1 | vi /etc/dovecot/dovecot.conf |
确保有以下配置:
1 | disable_plaintext_auth = no |
mail_location 与 Postfix 的 home_mailbox = Maildir/ 指向同一套邮箱;service auth 里的 unix_listener 就是 Postfix 配置里 smtpd_sasl_path = private/auth 对应的那个套接字,两边靠它接通认证。
保存后用 doveconf -n 校验——它会打印 Dovecot 实际生效的非默认配置,报错说明语法有问题。实测打印出 disable_plaintext_auth = no、mail_location = maildir:~/Maildir 等行即为生效。
启动 Dovecot:
1 | systemctl restart dovecot |
容器实测时两个服务都能脱离 systemd 直接拉起(postfix start 和 dovecot 命令),ss -ltn 确认 25 与 143 都在监听。有一个容器特有的坑:conf.d/10-ssl.conf 默认的 ssl_cert 指向自签证书 /etc/pki/dovecot/certs/dovecot.pem,最小容器里没有这个文件,dovecot 直接起不来——补一张自签证书(或临时 ssl = no)即可,生产环境必须换成真证书。
四、测试邮件功能
本机投递链路可以完整闭环,实测如下。先建一个本地收件用户,再发一封测试邮件:
1 | useradd mailtest |
发出后 tail /var/log/maillog,看到 status=sent 才算成功;实测最后一行是 status=sent (delivered to maildir),同时 /home/mailtest/Maildir/new/ 出现新邮件文件,cat 可见主题与正文,与发送内容逐字一致:

接收侧登录邮件客户端,或用 mutt 直接在命令行里查看:
1 | mutt |
注:容器内实测覆盖到本机投递闭环为止;跨服务器的收发依赖 MX 记录与 25 端口连通性,需在真实环境验证。来源:本机投递为实跑输出,外网收发为 Postfix/Dovecot 官方文档标准做法。
历史版本差异(CentOS 7)
- 版本:CentOS 7 上是 postfix 2.10.1、dovecot 2.2.36;包名相同、配置语法一致,把
dnf换回yum即可。本文的全部配置项在两代上都有效。 - 系统源:CentOS 7 已于 2024-06-30 停止维护,mirrorlist 已下线,需切到 vault 归档(见常见报错),实测修复后安装正常。
- 未知参数的容忍度:Rocky 9 的 Postfix 3.5.x 对不认识的参数只给警告;2.10.1 的行为未实测,保守起见
mta_sts_policy这行在两代上都不要保留。
装坏了怎么办
配置改坏导致服务起不来时,先 postfix check / doveconf -n 定位语法错误;想整体回退,dnf remove postfix dovecot 后重装,再按本文重新配置即可——两套软件的配置都集中在 /etc/postfix/ 和 /etc/dovecot/,备份这两个目录就能在任何时候恢复现场。
常见报错
- 本地投递一直 deferred,maillog 报
alias database unavailable:/etc/aliases.db没生成。实测里邮件卡在队列(status=deferred (alias database unavailable)),执行newaliases后队列立刻消化成status=sent。 - 容器里 maillog 是空的:容器默认没有 syslog 守护进程。Postfix 3.4+ 可在 main.cf 加
maillog_file = /var/log/maillog直写日志(实测有效),或者跑一个 syslog 服务。 - 容器里 dovecot 起不来,报 ssl_cert 打不开:
conf.d/10-ssl.conf默认引用自签证书,最小容器没有;生成自签证书或临时ssl = no,生产必须配真证书。 Cannot find a valid baseurl for repo: base/7:CentOS 7 EOL 后 mirrorlist 已下线。把/etc/yum.repos.d/*.repo里的mirror.centos.org替换为vault.centos.org、注释掉 mirrorlist 行并启用 baseurl(实测修复后安装正常)。- 能发不能收:依次查 mydestination 是否包含收件域名、MX 记录是否指到本机、防火墙是否放行 25 端口。
注意事项
- 用 firewalld 或 iptables 做访问控制,邮件服务器暴露在公网上,访问策略要收紧。
- 生产环境应配置 SSL/TLS 加密,保护邮件数据在传输中的安全。
disable_plaintext_auth = no允许明文认证,只在测试环境临时用,正式上线务必配合 TLS 并改回 yes。smtpd_recipient_restrictions三条规则缺一不可,少了reject_unauth_destination,服务器就可能被外部当跳板群发垃圾邮件。
自建邮件服务的完整价值要靠”能发、能收、不被当中继”三条一起兑现:按本文装好、postfix check 与 doveconf -n 双双通过、本机投递实测 status=sent,再在真实环境把收发两条链路各测一封,这套服务才算真正接住了开头的需求。
本文由作者 2020-2024 年间的 CSDN 博客文章重构而来,原发布于 CSDN。