Ubuntu 22.04搭建Postfix+Dovecot邮件系统:内网SMTP与IMAP全配置指南 📅 发布时间:2026/9/13 6:06:41 👁 浏览次数: 最近有个需求折腾了我一晚上——要在内网快速搭一套邮件系统用于测试环境的通知发送、定时报告投递顺带承接一个旧应用残留的SMTP调用。本来想直接用现成的第三方邮件服务结果测试环境出于安全考虑不允许出公网只能在本地方案里选。对比了一圈最省事、最稳的仍然是Postfix Dovecot这个老牌组合。Postfix负责SMTP发信和收信Dovecot负责IMAP/POP3取信两个加起来就是一套完整的邮件系统。Ubuntu 22.04标题里写成22.40实际对应的是Jammy22.04 LTS的软件源里这两个包都有现成版本装完做基础配置就能跑完全不需要商业组件。这篇就把我这次的完整操作记录下来从环境准备到收发信验证再到最常见的坑一次说清楚。1. 先想清楚本地邮件系统到底解决了什么问题很多人一听自建邮件系统就觉得麻烦其实得看场景。如果你只是想让某台服务器能往外发告警邮件那Postfix一个就够Dovecot根本不用上。但如果你的应用需要IMAP去拉取特定邮箱的内容或者团队内部需要几个真实可用的邮箱账号互相收发信来联调业务流程那PostfixDovecot是必须的组合。我这次的需求就属于后者一套内部系统要向若干个虚拟用户邮箱发通知同时有一个服务会通过IMAP去轮询某个收件箱里的邮件做后续自动化处理。两个需求叠在一起任何单一组件都搞不定只能配合使用。再聊聊方案选型。邮件系统的开源方案其实不少除了PostfixDovecot还有OpenSMTPD、Haraka、Mailcow这种全家桶。我选PostfixDovecot的理由很朴素两者都是Linux邮件系统的事实标准文档多踩坑经验好搜。包管理直接安装不引入容器、数据库等额外依赖。配置结构清晰一个发信、一个取信职责分开出了问题好定位。对低配虚拟机很友好512MB内存跑这两个服务毫无压力。Mailcow这类全家桶固然省事但它需要Docker和Compose还自带数据库、Web界面和一堆容器服务在纯内网测试环境里属于杀鸡用牛刀而且问题排查链路太长。PostfixDovecot这种拆分式架构反而更适合需要搞清楚每一封邮件流转的场合。2. 环境准备和主机名规划这部分偷懒后面必踩坑2.1 系统版本和软件源确认先在服务器上确认系统版本Ubuntu 22.04的代号是jammy对应内核6.x。执行下面命令看下lsb_release -a如果是Ubuntu 22.04.1到22.04.4之间的任意一个小版本软件源里的postfix版本都是3.6.xdovecot版本是2.3.16这套组合已经经过大量生产环境验证直接用没问题。安装前先做两件事更新软件源缓存、确保时区正确。邮件头里的Date字段依赖系统时间如果服务器时区或时间不对邮件客户端显示的时间会混乱排查问题的时候也容易产生误导。sudo apt update sudo timedatectl set-timezone Asia/Shanghai2.2 主机名与域名规划最容易被忽略的坑这是整篇里我最想强调的部分。邮件系统对主机名hostname和域名domain极其敏感服务启动时会用hostname来标识自己发出去的邮件头里会带上这个标识收件方的邮件服务器也会根据这个标识来反查服务器身份。我这里有一个反例。第一次部署时图省事直接用了默认的hostname结果Postfix起来后只认本机的短主机名发出去的邮件From字段变成了userubuntu在Dovecot里配置的虚拟域名完全不生效联调了半天才发现是主机名的问题。正确的做法是先规划好一个完整的邮件域名比如mail.local内网环境用.local或.internal这类保留域名最安全但注意不要和公网真实域名冲突然后把服务器的主机名设为该域名的主机部分。sudo hostnamectl set-hostname mail.local同时编辑/etc/hosts把主机名解析写进去127.0.0.1 localhost 127.0.0.1 mail.local mail这条hosts记录很关键。Postfix在启动时会查hostname对应的IP如果解析不到它会回退到一种保守模式日志里不断报unable to look up hostname之类的问题所有收发信全部异常。不要指望去依赖内网DNS编辑hosts是最快最稳的解决办法。2.3 安装软件包确认好主机名后安装就很直接sudo apt install postfix dovecot-imapd dovecot-pop3d -y安装Postfix过程中安装器会弹出一个配置界面问你邮件服务器类型。这里选择Internet Site系统类型填你规划的域名mail.local。如果这一步不小心选错了也没关系后续可以通过dpkg-reconfigure postfix重新配置。这里顺手装dovecot-imapd和dovecot-pop3d两个子包它们会把dovecot核心和对应协议的插件一起装进来。如果只装dovecot-core后面还需要手动装协议扩展很麻烦。3. Postfix部分一封邮件的SMTP之旅从这开始3.1 main.cf里值得改的几个关键参数Postfix的主配置文件是/etc/postfix/main.cfUbuntu安装好以后会有一个默认配置。这个默认配置可以直接跑起来但不适合我们的场景需要做几处调整。先看几个核心参数的意义myhostnamePostfix用来标识自己主机身份的完全限定域名默认读取系统hostname但显式写出来更清晰。mydomain邮件域。myorigin发出去的邮件From地址里后面的部分。希望所有本机发的邮件都显示为usermail.local就把myorigin设为$mydomain。mydestinationPostfix接受的本机投递域名列表。当一个邮件发往usermail.local时Postfix发现自己就是mail.local的权威服务器才会接收这封邮件。如果不配置这个Postfix会拒绝掉所有发给自己域的邮件。home_mailbox决定用户邮件保存在家目录的哪个文件。inet_interfaces监听网络接口。测试环境希望内网其他机器也能通过SMTP来中继发信就要设为all不能只监听loopback。我最后使用的配置关键段落如下sudo nano /etc/postfix/main.cfmyhostname mail.local mydomain mail.local myorigin $mydomain mydestination $myhostname, localhost.$mydomain, localhost, $mydomain inet_interfaces all inet_protocols ipv4 home_mailbox Maildir/ mailbox_command 这里重点说下home_mailbox Maildir/。传统Linux邮箱格式是mbox所有邮件堆在一个文件里Dovecot读取、应用遍历都不方便锁竞争也严重。Maildir格式每封邮件一个独立文件更稳也符合现代邮件系统的主流用法。设置成Maildir后每个系统用户的邮件会落在/home/用户名/Maildir/目录里。inet_protocols ipv4要单拎出来说。如果服务器没有IPv6环境而Postfix默认同时监听IPv4和IPv6启动时虽然会成功但日志里会有地址绑定警告。强制只用IPv4可以避免这些无谓的告警也让后续排错更省心。3.2 真正的用户邮件账号从哪来这里涉及一个关键设计决策。默认情况下PostfixDovecot配合系统用户使用即每个Linux用户就对应一个邮箱账号密码就是系统密码。这种模式的好处是配置简单但有一个天然的坏处系统安全的暴露面增大了。举个例子需要新增一个邮箱账号时就有责任给它分配一个系统shell、一个家目录这可能带来安全风险。测试环境我没这么讲究直接用系统用户模式。后续如果想上虚拟用户模式还需要引入数据库表来映射账号和密码Postfix里要用virtual_alias_domains和virtual_mailbox_domains那一套配置复杂度会明显上来。创建邮件用户的命令很简单sudo useradd -m -s /usr/sbin/nologin alice sudo passwd alice-s /usr/sbin/nologin的作用是让这个用户无法登录shell只能收邮件更安全些。家目录要保留因为Dovecot要把邮件写到用户的家目录里。按照plan我会创建两个测试账号一个用于发信测试一个用于IMAP轮询测试sudo useradd -m -s /usr/sbin/nologin alice sudo passwd alice sudo useradd -m -s /usr/sbin/nologin bob sudo passwd bob3.3 启动和验证Postfix配置完毕先语法检查再重启sudo postfix check sudo systemctl restart postfix sudo systemctl status postfixpostfix check这个命令会检查配置文件里所有引用的路径和权限。如果有错误它会直接指出具体是哪一行配置有问题这是定位配置错误最高效的手段比看日志快得多。如果状态显示active可以通过本地发送测试邮件来看基本功能是否正常echo test email body | mail -s test subject alicelocalhost这条命令会调用本机的sendmail接口把邮件投递给本地用户alice。然后去检查alice的Maildirsudo ls -la /home/alice/Maildir/ sudo ls -la /home/alice/Maildir/new/如果new目录下有文件说明Postfix的投递链路已经通了。这封邮件现在躺在alice的Maildir队列里等Dovecot起来后就可以通过IMAP读出来。4. Dovecot部分让邮件能读出来才是完整闭环Postfix解决了邮件的收发和投递但它不提供读取接口。就像快递公司把包裹送到你家门口但你没有钥匙打开邮箱拿信。Dovecot就是那把钥匙为邮件客户端提供IMAP和POP3的访问入口。4.1 Dovecot的配置文件结构Dovecot的配置和Postfix有很大不同它采用多个文件分散配置的方式主配置在/etc/dovecot/dovecot.conf其他模块则通过conf.d目录下的文件管理。这种设计的好处是模块清晰坏处是新手容易找不到设置项到底在哪个文件。我这次主要改的文件/etc/dovecot/dovecot.conf开启协议支持。/etc/dovecot/conf.d/10-mail.conf配置邮件存储位置。/etc/dovecot/conf.d/10-auth.conf配置认证方式。/etc/dovecot/conf.d/10-master.conf配置服务监听端口和Postfix的权限对接。4.2 核心配置邮件位置和认证模式先改10-mail.conf把Dovecot识别的邮件目录格式和Postfix写入的格式对齐。因为我们在Postfix里用了Maildir这边也必须告诉Dovecot用Maildir去读sudo nano /etc/dovecot/conf.d/10-mail.conf把mail_location设为mail_location maildir:~/Maildir然后改10-auth.conf启用系统用户PAM认证并允许明文认证内网环境可以先这样跑测试没问题再上TLSsudo nano /etc/dovecot/conf.d/10-auth.confdisable_plaintext_auth no auth_mechanisms plain login注意disable_plaintext_auth no是内网测试环境起步用的配置。一旦对外开放明文密码就等于裸奔必须配合TLS加密并且把这项改回yes。这部分我在第6节专门展开。主配置文件里确认协议是激活的sudo nano /etc/dovecot/dovecot.confprotocols imap pop34.3 让Postfix投递的邮件能进Dovecot的权限圈接下来是整套系统里最常见的一个坑权限。Postfix以postfix用户身份投递邮件写的邮件文件属主是postfix。Dovecot以后台dovecot用户身份尝试读取邮件结果没有权限直接报错客户端登录后看不到任何邮件。解决方式是在10-master.conf里把Postfix投递服务对应的unix socket配置一下让邮件投递后Dovecot有权限读取。具体来说找到service postfix相关的段落确保它的组和权限设置允许dovecot访问。实际操作中我是这样改的sudo nano /etc/dovecot/conf.d/10-master.confservice postfix { unix_listener /var/spool/postfix/private/auth { mode 0660 user postfix group postfix } }这段配置实际上是给Postfix的SMTP认证SASL用的。如果你不需要客户端通过SMTP发送认证比如只允许内网IP中继发信这个可以暂时不配。但既然要走完整流程我建议直接配上因为它也顺带解决了dovecot-lda投递的权限衔接问题。Dovecot自带一个LDALocal Delivery Agent工具可以代替Postfix自己往Maildir里丢邮件它更懂Maildir格式还能自动创建目录是更推荐的做法。想让Postfix用Dovecot的LDA来做本地投递需要在main.cf里加一行sudo nano /etc/postfix/main.cfmailbox_command /usr/lib/dovecot/dovecot-lda -f $SENDER -- $RECIPIENT这行配置的意思是Postfix收到本域邮件后不自己往用户邮件目录里塞而是交给dovecot-lda处理。这样做的好处很多包括自动创建Maildir目录、正确维护索引、支持sieve脚本过滤等。配合前面的权限配置dovecot-lda能以对应用户的身份投递用户自己的邮件自己读权限问题从根上消失。改完重启Dovecot和Postfixsudo systemctl restart dovecot postfix4.4 用telnet实测Dovecot的IMAP功能不看配置自信直接上客户端是个坏习惯。我习惯先用telnet或nc手动测一遍IMAP端口确认服务真的在工作。sudo apt install telnet -y telnet 127.0.0.1 143连上后输入a1 LOGIN alice 密码 a2 LIST * a3 SELECT INBOX a4 LOGOUT如果登录成功并且能SELECT INBOX说明Dovecot的认证和邮件访问链路都是通的。我之前遇到过一种情况Postfix那边能投递但Dovecot登录后看不到邮件最后排查下来就是10-master.conf里权限配置没到位。telnet这条手动链路测试能让你快速区分问题出在认证环节还是邮件读取环节。5. 联调验证和排错这五个坑几乎每次都会遇到5.1 第一封真正的全链路邮件从SMTP发送到IMAP读取配置全部就位后我开始做全链路验证。在一台内网客户端上用telnet直接跑一遍SMTP发信绕开任何客户端自动补全的干扰最干净telnet 192.168.1.100 25EHLO test.local MAIL FROM: alicemail.local RCPT TO: bobmail.local DATA Subject: test from alice Hello bob, this is a test. . QUIT如果Postfix返回250 OK说明服务器已经接受这封邮件。接着登录bob的邮箱就能看到。这一步走通整个闭环就成立了Alice发出邮件Postfix接收投递Dovecot提供读信接口Bob用任何邮件客户端登录就能看到。5.2 坑一防火墙没放行端口Ubuntu默认开启ufw防火墙时25、143、110这些端口不会自动放行。如果邮件客户端连接超时多半是这里的问题sudo ufw allow 25/tcp sudo ufw allow 143/tcp sudo ufw allow 110/tcp sudo ufw allow 587/tcp sudo ufw allow 993/tcp sudo ufw allow 995/tcp25是SMTP143是IMAP110是POP3587是SMTP提交端口带认证993和995是SSL加密版的IMAP和POP3。测试环境可以先把前三个放开加密端口等上TLS时再开。5.3 坑二IPv6监听导致的日志混乱前面提到的inet_protocols ipv4如果在Postfix配置里没处理系统日志会刷类似no IPv6 addresses available的警告虽然不影响发信但是会严重干扰排错时看日志的效率。在干净的环境里一次性配置好后面少很多麻烦。5.4 坑三Dovecot认证失败的排查步骤客户端登录提示认证失败可能的原因太多。我遇到最多的是password没同步或者系统用户没有密码。用sudo passwd alice重新设置一下密码然后看日志sudo tail -f /var/log/mail.logDovecot的认证失败信息会非常明确地出现在这里比如authentication failure它会告诉你用户名是否存在、密码是否为空。不要瞎猜直接看日志是最快的路。5.5 坑四Postfix mydestination没配好导致拒收本域邮件发往bobmail.local的邮件Postfix如果返回Relay access denied基本可以断定是mydestination里没有包含mail.local。Postfix的逻辑是收到一封信先看收件域名是否属于自己管理mydestination如果属于就接收投递不属于就看是否允许中继转发再不行就拒绝。所以自己的域名一定得写进mydestination否则系统会认为你在尝试转发陌生域名的邮件安全策略直接拦下。5.6 坑五邮件客户端发信还需要SMTP认证如果配置完成后邮件客户端连接时提示SMTP需要认证但Postfix还没开SASL客户端会弹出反复输密码的窗口。这时需要确认两点一是前面10-master.conf里的auth socket配置存在且进程监听正常二是在main.cf里确认真实开启了对客户端SMTP认证的接受sudo nano /etc/postfix/main.cfsmtpd_sasl_type dovecot smtpd_sasl_path private/auth smtpd_sasl_auth_enable yes smtpd_relay_restrictions permit_mynetworks, permit_sasl_authenticated, reject_unauth_destinationpermit_mynetworks允许内网段机器免认证发信permit_sasl_authenticated允许通过认证的客户端发信reject_unauth_destination拒绝所有未知目标域名的邮件。这三条加在一起既能保障内网方便又能杜绝开放中继变成垃圾邮件跳板。6. TLS加密和后续加固内网不等于安全豁免区测试环境很多人会忽略TLS但我的建议是既然要搭就把TLS一起配上理由有两个一是邮件客户端默认对未加密连接会有安全弹窗很烦二是Dovecot配置一次TLS之后以后生产环境迁移省得再折腾。6.1 自签名证书生成和配置内网环境没必要去买公网证书用openssl自签一个就行。生成一个同时包含私钥和证书的文件sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/dovecot/private/dovecot.pem \ -out /etc/dovecot/private/dovecot.pem \ -subj /CCN/STLocal/LLocal/OLocal/CNmail.localPostfix也需要一份可以直接复用同一个文件也可以单独生成一份sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/postfix/smtpd.pem \ -out /etc/postfix/smtpd.pem \ -subj /CCN/STLocal/LLocal/OLocal/CNmail.local注意自签名证书在客户端第一次连接时会有不可信告警内网测试环境属于正常现象点信任即可。6.2 Postfix开启SMTPS和SubmissionPostfix的TLS配置在main.cf追加smtpd_tls_cert_file /etc/postfix/smtpd.pem smtpd_tls_key_file /etc/postfix/smtpd.pem smtpd_tls_security_level may smtpd_tls_auth_only yessecurity_level may表示兼容明文和TLS连接客户端想加密就加密不想加密也能发测试阶段方便。auth_only yes表示SMTP认证必须发生在TLS加密通道上避免密码被明文截获。同时还要在master.cf里启用submission端口587这是客户端发信的标准端口sudo nano /etc/postfix/master.cf找到submission相关行取消注释submission inet n - y - - smtpd -o syslog_namepostfix/submission -o smtpd_tls_security_levelencrypt -o smtpd_sasl_auth_enableyes6.3 Dovecot启用IMAPS和POP3SDovecot的TLS配置在10-ssl.conf里sudo nano /etc/dovecot/conf.d/10-ssl.confssl required ssl_cert /etc/dovecot/private/dovecot.pem ssl_key /etc/dovecot/private/dovecot.pemssl required表示所有连接必须走TLS这样明文密码的担忧就可以放下。配置完后IMAP客户端要连993端口而不是143POP3要连995而不是110。全部改完重启服务sudo systemctl restart postfix dovecot用之前telnet的方式再测一遍这次连993端口并带上TLSopenssl s_client -connect 127.0.0.1:993 -quiet如果证书链正常握手成功说明TLS已经生效。6.4 关于开放中继的最后提醒邮件服务器最危险的一件事就是变成开放中继任何外部服务器都能通过你的机器转发垃圾邮件结果就是IP被各类黑名单封禁。之前配过reject_unauth_destination这条规则已经把大部分风险拦住了。如果你只用mynetworks里的IP段做中继还可以在main.cf的mynetworks里明确只写自己内网段mynetworks 127.0.0.0/8 192.168.0.0/16 10.0.0.0/8最后可以用这个命令快速自测是否开放中继telnet 127.0.0.1 25输入MAIL FROM: spamexample.com RCPT TO: victimexample.org如果返回554 Relay access denied说明中继限制生效这很关键。7. 进程自启和日志监控系统跑起来只是开始邮件系统不是配完就完事的它需要7x24小时在后台默默工作。这里有几个我在实际使用中离不开的后勤动作。第一是确保开机自启sudo systemctl enable postfix dovecot第二是日志监控。邮件系统的所有活动都记录在/var/log/mail.log这是排查问题的第一现场。我习惯用跟踪模式实时看日志sudo tail -f /var/log/mail.log日志会记录每个连接、每封邮件的来源、去向、状态、错误信息。收到一封邮件日志里的每一行都能还原它的完整旅程哪台机器连上来用哪个账号发的信发到哪个域投递结果如何。第三是配置a定时清理。测试环境邮件会越积越多长期不清理会占用大量磁盘。可以简单写个cron定时把超过30天的邮件清除sudo crontab -e0 2 * * * find /home/*/Maildir/cur -type f -mtime 30 -delete 0 3 * * * find /home/*/Maildir/new -type f -mtime 30 -delete这一步虽小但能让你的邮件服务器不至于运行半年后把磁盘塞满。整套系统跑通之后我在实际使用中发现几个顺手的改进空间如果后续要支持邮件别名比如opsmail.local同时投递给多个运维成员可以在Postfix里配aliases文件修改/etc/aliases然后执行newaliases生效。如果要做更细粒度的邮件过滤比如自动把特定主题的邮件归档Dovecot可以接sieve插件在用户家目录放一个.dovecot.sieve就能实现规则过滤。这些属于解锁完整邮件服务后的外延功能每一步都有对应的官方文档支持。还有就是如果你希望这套系统后续能对外收发公网邮件那必须有一个真实域名和公网IP还要配置MX记录、PTR反向解析以及SPF、DKIM、DMARC这三件套否则你发的邮件基本都会进别人的垃圾箱。这次我是在纯内网环境测试没涉及这些但如果你是有公网需求的场景答应我一定提前了解这三件套别等邮件被退信了再临时补课。