Ubuntu 22.04 安装 Postfix 3.6.4 指南

Ubuntu 22.04 上从零安装 Postfix 3.6.4-1ubuntu1.4:apt 仓库与离线 deb 双方案实测,含本地投递、双机 SMTP 互发闭环与 8 条排障实录

Postfix邮件服务器SMTPPostfix邮件2026/10/26

Ubuntu 22.04 安装 Postfix 3.6.4 指南

目标:在 Ubuntu 22.04 服务器上从零安装 Postfix 3.6.4(Ubuntu 仓库版 3.6.4-1ubuntu1.4),完成首次配置、服务启动、本地投递与双机 SMTP 互发闭环验证。已在两台 Ubuntu 22.04 服务器(mail1.example.com、mail2.example.com)与一台离线演示机(mail3.example.com)实测通过,实测日期 2026-10-26。

一、环境信息

本文所有命令与回显来自以下实测环境(两台在线服务器 + 一台离线演示机,同一内网 10.89.57.0/24):

项目值
操作系统Ubuntu 22.04 LTS(amd64)
Postfix 版本3.6.4-1ubuntu1.4(Ubuntu jammy 仓库)
服务器 Amail1.example.com,10.89.57.11,本域 example.com
服务器 Bmail2.example.com,10.89.57.12,本域 example.net
离线演示机mail3.example.com(用于离线 deb 方案验证)
配置文件/etc/postfix/main.cf、/etc/postfix/master.cf
队列目录/var/spool/postfix
日志文件/var/log/mail.log(rsyslog 提供)
监听端口25/tcp(SMTP)

💡 技术拓展:MTA(Mail Transfer Agent,邮件传输代理)负责服务器之间的 SMTP 信件转运,常见开源实现对比——

MTA特点适用场景
Postfix模块化多进程、配置平铺直观、安全历史优异通用首选,Internet 站点与内网中继
Exim表达力极强的 ACL/路由 DSL需要高度定制路由策略的场景
Sendmail最古老的 MTA,m4 宏配置仅存量系统维护
OpenSMTPDOpenBSD 系,配置语法极简轻量个人/小型站点

本文实际采用 Postfix:Ubuntu 22.04 仓库原生收录、默认配置开箱可用,且与 Ubuntu 安全维护渠道(jammy-security)衔接。

二、前置条件

2.1 系统与权限

安装需要 root 权限,且软件源可达。确认系统版本与 root 身份:

cat /etc/os-release | grep PRETTY

实测回显:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
whoami

实测回显:

root

2.2 主机名与域名解析规划

Postfix 的多个核心参数(myhostname、mydestination、myorigin)都围绕主机名与邮件域名展开,安装前先把主机名与解析固定下来。设置主机名:

hostnamectl set-hostname mail1.example.com
hostname

实测回显:

mail1.example.com

内网双机互发需要在两台服务器的 /etc/hosts 中互相固定解析(生产公网环境应改为 DNS A/MX 记录,原理相同):

10.89.57.11	mail1.example.com mail1
10.89.57.12	mail2.example.com mail2

在 mail1 上验证两台机器均能解析:

getent hosts mail1.example.com
getent hosts mail2.example.com

实测回显:

10.89.57.11   mail1.example.com
10.89.57.12   mail2.example.com

2.3 端口与防火墙

Postfix 对外服务只监听 25/tcp(SMTP)。若服务器启用了防火墙,需要放行 25 端口入站;本指南的实测内网未启用防火墙。可通过 ss -ltn | grep :25 在安装完成后确认监听(见 4.5 节实测回显)。

三、版本选型说明

3.1 仓库候选版本实查

Ubuntu 22.04 仓库中 Postfix 的候选版本实查如下:

apt-cache policy postfix

实测回显:

postfix:
  Installed: 3.6.4-1ubuntu1.4
  Candidate: 3.6.4-1ubuntu1.4
  Version table:
 *** 3.6.4-1ubuntu1.4 500
        500 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages
        100 /var/lib/dpkg/status

即:候选版本为 3.6.4-1ubuntu1.4,同时来自 jammy-updates(常规更新)与 jammy-security(安全更新)两个渠道,100 /var/lib/dpkg/status 表示本机已安装的记录。安装后可用软件自身的版本参数复核:

postconf mail_version

实测回显:

mail_version = 3.6.4

3.2 上游版本与维护状态

  • Postfix 上游(postfix.org)约每 12 个月发布一个 minor 稳定分支。据官方源码发布页实查(查询日期 2026-10-26):当前上游稳定版为 3.11.x,实验版为 3.12 快照(postfix-3.12-20261020)。
  • 上游在 Postfix 3.10(2025 年 2 月)发布时宣布 3.6 分支不再由上游继续更新;Ubuntu 22.04 LTS 生命周期内,3.6.4-1ubuntu1.4 由 Ubuntu 安全团队经 jammy-security 渠道继续提供安全修复。生产环境在 Ubuntu 22.04 上使用仓库版即可持续获得安全更新。
  • 站内 《Mailcow 2026-09a 介绍与选型指南》 显示,主流自托管邮件全家桶 Mailcow 内置的 SMTP 组件正是 Postfix 3.10.12,可见 Postfix 同时活跃于发行版仓库与邮件套件两条生态线。

3.3 安装方案总览

方案适用场景是否需联网安装方式
A. 在线仓库安装(推荐)可访问 Ubuntu 源的服务器是apt 安装 debconf 预置 + 自动配置
B. 离线 deb 包安装断网/隔离网段服务器否(需先在联网机下载)递归下载全量 deb 后 dpkg 安装

两方案装出的二进制完全一致(同一版本号),差别只在依赖解决方式与初始配置的生成时机,详见第四、五、五章。

四、方案 A:在线仓库安装(推荐)

4.1 安装前预置配置(非交互)

Ubuntu 的 postfix 包在安装时会弹出 debconf 配置向导。自动化安装(脚本/批量装机)可先用 debconf-set-selections 预置答案,安装过程即不再停顿:

echo "postfix postfix/main_mailer_type select Internet Site" | debconf-set-selections
echo "postfix postfix/mailname string mail1.example.com" | debconf-set-selections

两条命令均无输出(预置成功)。第一行选择配置类型 Internet Site(直接面向 Internet 收发的独立邮件站点),第二行指定系统邮件名(写入 /etc/mailname)。

4.2 交互式安装对话框说明

若不做预置,安装时会进入字符界面向导,实测对话框共两步:

  • 第一步 Postfix Configuration 要求选择配置类型,实测选项共 5 项:1. No configuration、2. Internet Site、3. Internet with smarthost、4. Satellite system、5. Local only。独立邮件服务器选 Internet Site。
  • 第二步要求输入 System mail name,即本机对外邮件域名,实测填入 mail1.example.com(写入 /etc/mailname)。

💡 技术拓展:五种配置类型的取舍——Internet Site(自己收发全部邮件)、Internet with smarthost(收信自收、发信经上游中继)、Satellite system(全部邮件交给上游中继,本机只发不收)、Local only(仅本机内部投递)、No configuration(不生成 main.cf,完全手工配置)。本文因要在内网双机间直接收发,选择 Internet Site。

4.3 执行安装

先刷新软件源索引:

apt-get update

实测回显(输出节选,实测首尾):

Get:15 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [82.9 kB]
Get:16 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [35.6 kB]
Get:17 http://security.ubuntu.com/ubuntu jammy-security/restricted amd64 Packages [7955 kB]
Get:18 http://security.ubuntu.com/ubuntu jammy-security/multiverse amd64 Packages [96.8 kB]
Fetched 49.0 MB in 24s (2027 kB/s)
Reading package lists...

安装 postfix 与 mailutils(后者提供 mail 命令,用于收发验证;最小化系统建议一并安装 iproute2(ss 命令)与 rsyslog(mail.log 日志)):

apt-get install -y postfix mailutils iproute2 rsyslog

实测回显(输出节选,实测首尾):

The following NEW packages will be installed:
  ca-certificates cpio cron gsasl-common guile-3.0-libs iproute2 libatm1
  libbpf0 libbsd0 libcap2-bin libelf1 libestr0 libexpat1 libfastjson4
  libfribidi0 libgc1 libgsasl7 libicu70 libidn12 libldap-2.5-0 libldap-common
  libltdl7 libmailutils8 libmd0 libmnl0 libmpdec3 libmysqlclient21 libntlm0
  libpam-cap libpopt0 libpq5 libpython3-stdlib libpython3.10
  libpython3.10-minimal libpython3.10-stdlib libreadline8 libsasl2-2
  libsasl2-modules libsasl2-modules-db libsqlite3-0 libxtables12 logrotate
  mailutils mailutils-common media-types mysql-common netbase openssl postfix
  python3 python3-minimal python3.10 python3.10-minimal readline-common
  rsyslog ssl-cert ucf
0 upgraded, 57 newly installed, 0 to remove and 3 not upgraded.
Need to get 34.8 MB of archives.
After this operation, 147 MB of additional disk space will be used.

安装器设置 postfix 包的阶段,实测关键回显如下(逐行照抄):

Setting up postfix (3.6.4-1ubuntu1.4) ...
Adding group `postfix' (GID 102) ...
Done.
Adding system user `postfix' (UID 101) ...
Adding new user `postfix' (UID 101) with group `postfix' ...
Not creating home directory `/var/spool/postfix'.
Creating /etc/postfix/dynamicmaps.cf
Adding group `postdrop' (GID 103) ...
Done.
setting myhostname: mail1.example.com
setting alias maps
setting alias database
changing /etc/mailname to mail1.example.com
setting myorigin
setting destinations: $myhostname, mail1.example.com, localhost.example.com, , localhost
setting relayhost: 
setting mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
setting mailbox_size_limit: 0
setting recipient_delimiter: +
setting inet_interfaces: all
setting inet_protocols: all
/etc/aliases does not exist, creating it.
WARNING: /etc/aliases exists, but does not have a root alias.

Postfix (main.cf) is now set up with a default configuration.  If you need to 
make changes, edit /etc/postfix/main.cf (and others) as needed.  To view 
Postfix configuration values, see postconf(1).

After modifying main.cf, be sure to run 'systemctl reload postfix'.

Running newaliases

⚠️ 注意:最后两行 invoke-rc.d: could not determine current runlevel / policy-rc.d denied execution of start 只出现在无 systemd 运行级的极简环境(安装器无法代为启动服务),需要手工启动(见 4.5 节)。常规 Ubuntu 22.04 服务器带 systemd,安装完成时 postfix.service 会自动启动,无需手工干预。

关键信息解读:

  • 安装器自动创建了 postfix(GID 102)与 postdrop(GID 103)两个组、postfix 系统用户(UID 101);
  • setting destinations: $myhostname, mail1.example.com, localhost.example.com, , localhost——由 System mail name 推导出 mydestination;注意其中 localhost.example.com, , localhost 里有一项为空(两个连续逗号),这是安装器基于主机名拆分生成的空项,属于实测事实,无功能影响,介意可用 postconf -e 重写该项(见《Postfix 3.6.4 配置参数详解》);
  • /etc/aliases does not exist, creating it.——首次安装生成别名库并执行了 newaliases;
  • 提示语明确:改完 main.cf 后执行 systemctl reload postfix。

4.4 安装生成的初始 main.cf 解读

用 postconf -n 查看「与内置默认值不同」的生效参数(这是检查 Postfix 配置差异的标准姿势):

postconf -n

实测回显(全新安装机):

alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
compatibility_level = 3.6
inet_interfaces = all
inet_protocols = all
mailbox_size_limit = 0
mydestination = $myhostname, mail1.example.com, localhost.example.com, , localhost
myhostname = mail1.example.com
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
readme_directory = no
recipient_delimiter = +
relayhost =
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level = may

逐项解读关键参数:

参数默认值(实测)含义
compatibility_level3.6兼容级别锁在 3.6,未来升级到更高版本时旧行为不突变
myhostnamemail1.example.com本机主机名,出现在 SMTP 横幅与日志中
mydestination$myhostname, mail1.example.com, …本机直接接收的域列表(本地域)
myorigin/etc/mailname本机发信默认补齐的域(读自 /etc/mailname)
mynetworks127.0.0.0/8 等信任客户端网段(默认仅回环,不放行外部中继)
inet_interfacesall监听所有网卡
smtpd_relay_restrictionspermit_mynetworks …中继控制链:信任网段放行、SASL 认证放行、其余延迟拒绝
smtpd_tls_security_levelmay对外启用机会性 TLS(客户端支持就加密)
smtpd_tls_cert_filessl-cert-snakeoil.pem默认自带的「snakeoil」自签证书
mailbox_size_limit0邮箱大小限制 0 = 不限制

队列与目录结构确认(/var/spool/postfix 是 Postfix 的队列与 chroot 根):

ls /var/spool/postfix/

实测回显:

active  bounce  corrupt  defer  deferred  dev  etc  flush  hold  incoming  lib  maildrop  pid  private  public  saved  trace  usr

4.5 启动服务与监听验证

在极简环境(安装时服务未被拉起)手工启动:

service postfix start

实测回显:

   ...done.

确认运行状态(postfix status 静默返回、退出码 0 表示在运行):

postfix status; echo "rc=$?"
pgrep -a master

实测回显:

rc=0
3946 /usr/lib/postfix/sbin/master -w

验证 25 端口监听(IPv4 与 IPv6 双栈):

ss -ltn | grep :25

实测回显:

LISTEN 0      100          0.0.0.0:25         0.0.0.0:*          
LISTEN 0      100             [::]:25            [::]:*          

常规 systemd 服务器上的服务状态形态(实测于 mail1):

systemctl is-active postfix
systemctl status postfix --no-pager

实测回显:

active
● postfix.service - Postfix Mail Transport Agent
     Loaded: loaded (/lib/systemd/system/postfix.service; enabled; vendor preset: enabled)
     Active: active (exited) since Mon 2026-10-26 09:44:07 UTC; 1h 15min ago
       Docs: man:postfix(1)
   Main PID: 4012 (code=exited, status=0/SUCCESS)
        CPU: 1ms

Active: active (exited) 是 Postfix systemd 单元的正常形态:master 守护进程由单元拉起后自行脱离监管,单元显示 exited 但服务真实在跑(进程验证见上方 pgrep)。

4.6 本地投递验证

用 mail 命令给 root 发第一封信(sendmail 投递链走本机 Postfix):

echo "first local mail body from $(hostname)" | mail -s "first-local-test" root
sleep 2
ls -la /var/mail/root

实测回显:

-rw------- 1 root mail 531 Oct 26 11:02 /var/mail/root

信件已落到 root 的 mbox。查看信件头部(本地投递的标准头链):

head -8 /var/mail/root

实测回显:

From root@mail1.example.com  Mon Oct 26 11:02:25 2026
Return-Path: <root@mail1.example.com>
X-Original-To: root
Delivered-To: root@mail1.example.com
Received: by mail1.example.com (Postfix, from userid 0)
	id A048BA49A68; Mon, 26 Oct 2026 11:02:25 +0000 (UTC)
Subject: first-local-test
To: root@mail1.example.com

用 mail 命令交互读信(按 h 列表、回车读信、q 退出)确认可读:

printf "1\nq\n" | mail

实测回显(输出节选,实测首尾):

"/var/mail/root": 2 messages 2 new
>N   1 root@mail1.example Mon 10/26 11:02  14/531   first-local-test

日志链逐行核对(rsyslog 提供的 /var/log/mail.log,一封信从入队到投出的完整生命周期):

tail -5 /var/log/mail.log

实测回显:

Oct 26 11:05:18 mail1 postfix/pickup[5085]: A59F1A49B42: uid=0 from=<root@mail1.example.com>
Oct 26 11:05:18 mail1 postfix/cleanup[5105]: A59F1A49B42: message-id=<20261026110518.A59F1A49B42@mail1.example.com>
Oct 26 11:05:18 mail1 postfix/qmgr[5086]: A59F1A49B42: from=<root@mail1.example.com>, size=363, nrcpt=1 (queue active)
Oct 26 11:05:18 mail1 postfix/local[5108]: A59F1A49B42: to=<root@mail1.example.com>, orig_to=<root>, relay=local, delay=0, delays=0/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
Oct 26 11:05:18 mail1 postfix/qmgr[5086]: A59F1A49B42: removed

五个阶段解读:pickup(maildrop 收取,uid=0 即 root 发起)→ cleanup(生成 message-id、写规范头)→ qmgr(active 队列调度)→ local(本地投递代理,orig_to=<root> 说明别名/短名被补全为 root@mail1.example.com)→ qmgr removed(投递成功出队)。队列应已清空:

postqueue -p

实测回显:

Mail queue is empty

4.7 systemd 托管说明(真机)

Ubuntu 22.04 真机上 postfix.service 默认 enabled,开机自启。常用托管命令(每行只操作 postfix 一个单元):

systemctl start postfix
systemctl stop postfix
systemctl reload postfix
systemctl is-active postfix

reload 让 master 进程重读 main.cf 而不断开在途 SMTP 连接,是改配置后的标准动作;stop 后 postfix status 退出码变为 1(实测见《Postfix 3.6.4 常用 CLI 命令详解》停启闭环一节)。

五、方案 B:离线 deb 包安装(断网服务器)

5.1 方案说明

完全隔离的服务器无法访问 apt 源,可在一台同版本(Ubuntu 22.04、同架构 amd64)联网机上把 postfix 及其全部依赖一次性下载成 deb 文件,拷贝到离线机后用 dpkg 安装。两个关键点:只下载 postfix_3.6.4-1ubuntu1.4_amd64.deb 单包是不够的(postfix 依赖 libsasl2-2、netbase、ssl-cert、cpio 等,离线机缺一个就配置失败,实测见 5.3);要用 apt-cache depends --recurse 递归解析出全量依赖清单。

5.2 联网侧下载全量 deb

在工作目录中递归下载全部依赖包:

mkdir deb && cd deb
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
  --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends \
  postfix | grep "^\w" | sort -u)

实测回显(输出节选,实测首尾):

Get:1 http://archive.ubuntu.com/ubuntu jammy/main amd64 base-files amd64 12ubuntu4.7 [64.5 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy/main amd64 debianutils amd64 5.5-1ubuntu2 [55.9 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates/main amd64 tar amd64 1.34+dfsg-1ubuntu0.1.22.04.2 [288 kB]
...
Fetched 31.5 MB in 3s (9303 kB/s)
Download complete and in download only mode

下载结果核对(48 个 deb,postfix 主包体积约 1.2 MB):

ls *.deb | wc -l
ls -la postfix_*.deb

实测回显:

48
-rw-r--r-- 1 root root 1247868 May  7 22:29 postfix_3.6.4-1ubuntu1.4_amd64.deb

5.3 离线侧安装与排障实录

把 deb 目录整体拷到离线机后安装:

dpkg -i *.deb

实测回显(输出节选,实测首尾):

Selecting previously unselected package ssl-cert.
Preparing to unpack .../ssl-cert_1.1.2_all.deb ...
Unpacking ssl-cert (1.1.2) ...
Setting up netbase (6.3) ...
Setting up cpio (2.13+dfsg-7) ...
Setting up postfix (3.6.4-1ubuntu1.4) ...
retry_warning: not found
dpkg: error processing package postfix (--install):
 installed postfix package pre-installation script subprocess returned error exit status 127
Errors were encountered while processing:
 postfix

⚠️ 排障实录:retry_warning: not found(退出码 127)是 postfix 的 preinst 脚本在非交互环境(无 debconf 前端)下找不到交互函数所致,属离线批量安装的已知形态。此时其余依赖已全部装好,只有 postfix 停在 unconfigured 状态,用补配置动作收尾即可:

dpkg --configure -a

实测回显(输出节选,实测首尾):

Setting up postfix (3.6.4-1ubuntu1.4) ...

Postfix (main.cf) is now set up with a default configuration.  If you need to 
make changes, edit /etc/postfix/main.cf (and others) as needed.  To view 
Postfix configuration values, see postconf(1).

(过程中会伴随若干 debconf Perl 提示噪音,不影响配置完成。)确认包状态恢复为 ii:

dpkg -l postfix | tail -1

实测回显:

ii  postfix  3.6.4-1ubuntu1.4  amd64  High-performance mail transport agent

5.4 离线机验证

service postfix start
postfix status; echo "rc=$?"
postconf -h myhostname

实测回显:

   ...done.
rc=0
mail3.example.com

离线机 myhostname 由其自身主机名生成,服务状态与在线安装完全一致。

5.5 两方案对比与选择建议

维度方案 A 在线仓库方案 B 离线 deb
版本3.6.4-1ubuntu1.4(jammy)同一版本包
联网要求安装时需达 apt 源离线机全程不联网
依赖处理apt 自动解析需 apt-cache depends --recurse 预先递归下载
初始配置生成debconf 向导(预置或交互)preinst 在无交互前端时会报 127,需 dpkg --configure -a 收尾
升级通道apt upgrade 直通每次升级都要重新打包拷贝

选择建议:可联网一律走方案 A(升级与安全更新直通);真正隔离的网段用方案 B,并把 deb 目录纳入内网软件仓(如自建 apt 仓库)以便后续升级。另有第三条路——上游源码编译安装(postfix.org 提供 postfix-3.11.x 等源码包),仅在需要 3.6.4 没有的新特性或非标编译选项时考虑,日常运维不建议偏离发行版包体系。

六、双机 SMTP 互发闭环验证

6.1 双机规划与 hosts

两台服务器分工:mail1.example.com 服务 example.com 域,mail2.example.com 服务 example.net 域;解析已在两台机 /etc/hosts 互指(见 2.2 节)。双机各自完成第四章安装。

6.2 mynetworks 与 transport_maps

第一步,双方把对端网段加入 mynetworks(信任网段,允许其中机器经本机中继):

postconf -e "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.89.57.0/24"
postconf -h mynetworks

实测回显:

127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.89.57.0/24

第二步,mail1 上把发往 example.net 的信指定交给 mail2(transport 表 + postmap 生成 hash 库):

cat >> /etc/postfix/transport <<'EOF'
example.net    relay:[mail2.example.com]
EOF
postmap /etc/postfix/transport
postconf -e "transport_maps = hash:/etc/postfix/transport"
postmap -s hash:/etc/postfix/transport

实测回显(postmap -s 列出表内容,输出节选):

example.net	relay:[mail2.example.com]

relay:[...] 方括号表示直接按主机名连 A 记录、不再查询 MX。mail2 上对称配置(example.com relay:[mail1.example.com])。两台机各自 systemctl reload postfix 生效。

6.3 mail1 → mail2 发信实测

从 mail1 用 swaks 直接向 mail2 的 SMTP 端口发信(收件人属于 example.net):

swaks --to root@example.net --server mail2.example.com

实测回显(输出节选,实测首尾):

=== Trying mail2.example.com:25...
=== Connected to mail2.example.com.
<-  220 mail2.example.com ESMTP Postfix (Ubuntu)
 -> EHLO mail1.example.com
<-  250-mail2.example.com
...
 -> MAIL FROM:<root@mail1.example.com>
<-  250 2.1.0 Ok
 -> RCPT TO:<root@example.net>
<-  250 2.1.5 Ok
...
<-  250 2.0.0 Ok: queued as D69EF3E13C5
 -> QUIT
<-  221 2.1.0 Bye

mail2 侧日志完整呈现「接收→入队→本地投递→出队」:

Oct 26 11:06:30 mail2 postfix/cleanup[4782]: D69EF3E13C5: message-id=<20261026110630.006562@mail1.example.com>
Oct 26 11:06:30 mail2 postfix/qmgr[4752]: D69EF3E13C5: from=<root@mail1.example.com>, size=487, nrcpt=1 (queue active)
Oct 26 11:06:30 mail2 postfix/local[4783]: D69EF3E13C5: to=<root@example.net>, relay=local, delay=0.01, delays=0/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
Oct 26 11:06:30 mail2 postfix/qmgr[4752]: D69EF3E13C5: removed

信件落到 mail2 的 /var/mail/root。若走 mail1 的 transport_maps 路径(用 mail 命令发,先经 mail1 队列再转给 mail2),mail1 侧日志形态为(实测历史链):

Oct 26 09:48:19 mail1 postfix/relay/smtp[4304]: 4AF6D3E066A: to=<root@example.net>, relay=mail2.example.com[10.89.57.12]:25, delay=0.02, delays=0/0.01/0/0, dsn=2.0.0, status=sent (250 2.0.0 Ok: queued as 4E34E3E06A2)

6.4 mail2 → mail1 反向实测

对称方向验证:

swaks --to root@example.com --server mail1.example.com

实测回显(关键行):

<-  250 2.0.0 Ok: queued as 025E03E13C5

mail1 侧投递日志:

Oct 26 11:06:33 mail1 postfix/local[6574]: 025E03E13C5: to=<root@example.com>, relay=local, delay=0.01, delays=0.01/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
Oct 26 11:06:33 mail1 postfix/qmgr[6288]: 025E03E13C5: removed

双机闭环达成:example.com 与 example.net 两域互发全部落箱。

6.5 未授权中继的拒收行为

mynetworks 只含回环时的对照实验:第三方客户端要求 mail1 替其把信转发到无关外域 foreign.example:

swaks --to user@foreign.example --server mail1.example.com

实测回显(关键行):

<** 454 4.7.1 <user@foreign.example>: Relay access denied

mail1 日志侧影(NOQUEUE 说明信在 RCPT 阶段就被拒、未入队):

Oct 26 09:54:38 mail1 postfix/smtpd[4800]: NOQUEUE: reject: RCPT from unknown[10.89.57.12]: 454 4.7.1 <user@foreign.example>: Relay access denied; from=<root@mail2.example.com> to=<user@foreign.example> proto=ESMTP helo=<mail2.example.com>

这是 smtpd_relay_restrictions = … defer_unauth_destination 的默认防线:454 是临时码(按 RFC 5321 客户端可稍后重试),Postfix 用它对「疑似配置失误的中继请求」留出缓冲。把对端网段加入 mynetworks 后,同样的命令即可放行:

<-  250 2.0.0 Ok: queued as 885253E0077

随后 Postfix 尝试投递到 foreign.example(实测内网无法解析公网 MX),产生标准退信(dsn=5.4.4):

Oct 26 09:52:54 mail1 postfix/smtp[4686]: 2BAF93E076B: to=<user@foreign.example>, relay=none, delay=0.09, delays=0/0.01/0.08/0, dsn=5.4.4, status=bounced (Host or domain name not found. Name service error for name=foreign.example type=AAAA: Host found but no data record of requested type)

结论:放行中继前务必确认目标域真实可达,否则中继者会持续收到退信;对外服务器的 mynetworks 保持默认回环、只给 permit_sasl_authenticated 留认证中继通道(认证配置见《Postfix 3.6.4 配置参数详解》)。

七、配置说明(安装后通用项)

7.1 /etc/mailname 与 myorigin

安装器把 System mail name 写入了 /etc/mailname,myorigin 以文件形式引用它:

cat /etc/mailname
postconf -h myorigin

实测回显:

mail1.example.com
/etc/mailname

本机用户发信时,root 这样的短地址会补齐为 root@mail1.example.com(见 4.6 节 mbox 头 Return-Path)。修改邮件域时改 /etc/mailname 后需 newaliases && systemctl reload postfix。

7.2 别名库

首次安装生成的 /etc/aliases(首行实测):

postmaster:    root

追加别名后重建 hash 库生效:

echo "webmaster: root" >> /etc/aliases
newaliases
postalias -q webmaster /etc/aliases

实测回显(最后一行):

root

7.3 日志

邮件日志由 rsyslog 落盘为 /var/log/mail.log(配套 mail.warn、mail.err 等),logrotate 按 /etc/logrotate.d/rsyslog 定义轮转。日志是 Postfix 排障的第一现场,每封信的五阶段链(pickup→cleanup→qmgr→投递代理→removed)见 4.6 节解读。

7.4 版本锁定

生产机若不希望 apt upgrade 意外升级 MTA,可锁定版本:

apt-mark hold postfix

实测回显:

postfix set on hold.

解除锁定:

apt-mark unhold postfix

实测回显:

Canceled hold on postfix.

八、常见问题(排障实录)

Q1:安装完成后 25 端口没有监听? 极简环境安装器被 policy-rc.d 阻止拉起服务(安装回显中的 policy-rc.d denied execution of start),手工 service postfix start 或 systemctl start postfix 后用 ss -ltn | grep :25 复核(回显见 4.5 节)。真机正常情况下安装即自启,无需干预。

Q2:没有 /var/log/mail.log? mail.log 由 rsyslog 产出;最小化安装的系统可能没有 rsyslog 或其未启动。apt-get install -y rsyslog 并启动后即可看到五阶段日志链(本文所有日志回显均来自该文件)。

Q3:安装时 debconf 向导卡在字符界面? 批量装机用 4.1 节的两条 debconf-set-selections 预置;单机安装直接在向导里选 Internet Site 并填 System mail name(见 4.2 节)。

Q4:发往本域的信被拒 550 5.1.1 User unknown in local recipient table? 收件人不在这个系统用户表且未在别名中。确认用户已创建,或用 /etc/aliases 把该地址映射到真实用户后 newaliases。本地投递的资格由 mydestination 决定——收件域不在 mydestination 列表时根本不会尝试本地投递。

Q5:外域客户端中继被拒 454 4.7.1 Relay access denied? 默认安全行为(见 6.5 节)。信任的客户端网段加入 mynetworks,或为漫游客户端配置 SASL 认证。

Q6:离线 dpkg 安装报 retry_warning: not found(exit 127)? postfix preinst 脚本在无 debconf 交互前端的批量安装环境下的已知形态,依赖已装齐,dpkg --configure -a 收尾即可(完整实录见 5.3 节)。

Q7:改了 main.cf 不生效? Postfix 常驻 master 进程不会自动重读配置,改完必须 systemctl reload postfix(安装器末尾的提示原话见 4.3 节)。验证某参数当前值用 postconf -h 参数名。

Q8:mydestination 里有个空项(, ,)要不要紧? 安装器基于主机名拆分生成,实测形态见 4.3/4.4 节,不影响收发;介意可 postconf -e "mydestination = …" 重写为显式列表。

九、卸载与清理

连配置一起清除:

apt-get purge -y postfix

实测回显(输出节选,实测首尾):

Removing postfix (3.6.4-1ubuntu1.4) ...
Purging configuration files for postfix (3.6.4-1ubuntu1.4) ...

purge 会移除 /etc/postfix 与 /var/spool/postfix:

ls /etc/postfix
ls /var/spool/postfix

实测回显:

ls: cannot access '/etc/postfix': No such file or directory
ls: cannot access '/var/spool/postfix': No such file or directory

注意两处残留(purge 不动它们):/var/lib/postfix/(postscreen 缓存等运行期数据)与 /var/mail/(用户 mbox,含实测期间的收信)。确认不再需要时手工删除;如只做重装则保留 /var/mail 即可保留历史信件。仅卸载程序保留配置用 apt-get remove -y postfix。

十、参考链接

  1. Postfix 官网与官方文档:https://www.postfix.org/(含 BASIC_CONFIGURATION_README、postconf(5) 参数手册)
  2. Ubuntu 软件包页:https://packages.ubuntu.com/jammy/postfix(jammy 渠道版本 3.6.4-1ubuntu1.4,查询日期 2026-10-26)
  3. Postfix 源码发布页:https://www.postfix.org/download.html(上游稳定版 3.11.x 与 3.12 实验快照,查询日期 2026-10-26)
  4. 站内同族实战:《Mailcow 2026-09a 介绍与选型指南》(内置 Postfix 的邮件全家桶)、《Postfix 3.6.4 介绍与选型指南》(选型与认知)、《Postfix 3.6.4 配置参数详解》、《Postfix 3.6.4 常用 CLI 命令详解》