Ubuntu 22.04 安装 OpenSMTPD 指南

Ubuntu 22.04 安装 OpenSMTPD 双方案实测:apt 仓库安装 6.8.0p2(含默认配置 localhost 双绑定故障排障实录)与官方 7.9.0p0 源码编译安装(特权分离用户、/var/empty、队列目录属主等坑位全记录),systemd 托管、swaks 投递闭环、升级与卸载全流程

OpenSMTPD邮件服务器OpenSMTPD2026/10/21

Ubuntu 22.04 安装 OpenSMTPD 指南

目标:在 Ubuntu 22.04 服务器上从零安装 OpenSMTPD 并跑通「SMTP 收信 → 本地投递 → 队列管理」闭环。本文实测了两条安装主线:A 线用系统 apt 仓库安装 opensmtpd 6.8.0p2,B 线用官方源码包编译安装最新稳定版 7.9.0p0,两线均完成 systemd 服务化与投递验证,安装过程中的真实报错与排障过程全部沉淀在对应章节与常见问题中。

一、环境信息

本文所有命令与回显均在以下环境实测通过:

项目值
操作系统Ubuntu 22.04.5 LTS(x86_64)
内核5.15 系列
测试主机名mail.example.com
演示账号root / 普通用户 admin(密码 q1w2e3r4)
A 线软件版本opensmtpd 6.8.0p2-4build1(jammy/universe)
B 线软件版本OpenSMTPD 7.9.0p0(官方源码包编译安装)
监听端口25(SMTP)、587(Submission,B 线演示)
队列目录/var/spool/smtpd
配置文件A 线 /etc/smtpd.conf;B 线 /usr/local/etc/smtpd.conf
测试工具swaks(SMTP 会话测试)

二、前置条件

2.1 系统要求

  • 一台 Ubuntu 22.04 服务器,具备 root 或 sudo 权限;
  • 服务器出网可访问 archive.ubuntu.com(apt 安装)或 www.opensmtpd.org(源码下载);
  • 若服务器对公网提供服务,防火墙需放行 25/tcp(收信)与 587/tcp(客户端提交)。

2.2 检查端口占用

OpenSMTPD 默认监听 25 端口。若系统此前装过 Postfix、Exim 或其他 MTA,必须先卸载或停用,否则端口冲突:

# 查看当前 25 端口占用
sudo ss -ltnp | grep :25

实测输出(空闲状态无任何输出;若被占用会列出进程名与 PID,先 systemctl stop --now postfix 并 apt purge postfix 处理):

ss -ltnp | grep :25

回显为空即端口可用,可继续安装。

2.3 主机名准备

SMTP 协议大量使用主机名(HELO/EHLO、证书 CN、日志溯源),建议安装前把主机名设置为可解析的 FQDN 形式(本文以 mail.example.com 为例):

sudo hostnamectl set-hostname mail.example.com

同步更新 /etc/hosts,把 127.0.1.1 一行指向新主机名:

cat /etc/hosts

实测回显:

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::  ip6-localnet
ff02::  ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.0.0.2        mail.example.com

验证主机名解析:

hostname -f

实测回显:

mail.example.com

三、版本选型说明

OpenSMTPD 存在「上游最新版」与「发行版仓库版」两条基准线,安装前先明确要哪一个(查询日期 2026-10-21):

基准版本来源适用场景
Ubuntu 22.04 仓库版opensmtpd 6.8.0p2-4build1jammy/universe,apt install opensmtpd快速部署、跟随 apt 升级维护
上游最新稳定版OpenSMTPD 7.9.0p0(2026-09-13 发布)opensmtpd.org/archives 源码包需要 7.x 新特性(如内建 filter DSL 细化、dispatcher 架构)与最新安全修复

查看仓库可装版本的实测命令:

apt-cache policy opensmtpd

实测回显:

opensmtpd:
  Installed: (none)
  Candidate: 6.8.0p2-4build1
  Version table:
     6.8.0p2-4build1 500
        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages

⚠️ 注意:仓库版 6.8.0p2 比上游最新 7.9.0p0 落后约两个大版本(6.8 → 7.6 → 7.7 → 7.8 → 7.9),且 6.8.0p2 在 Ubuntu 22.04 上存在一个影响开箱即用的「默认配置启动失败」问题(见第四章排障实录)。若不接受该问题或需要新版特性,直接走第五章源码编译方案。

四、方案 A:在线仓库安装(apt,opensmtpd 6.8.0p2)

本章是 A 线主线:apt 一条命令完成安装,随后处理一个必须知晓的首次启动故障,最后跑通投递验证。

4.1 方案说明

apt 方案的优势是安装、升级、卸载全部纳入包管理,systemd 服务单元由发行版直接提供;劣势是版本固定为 6.8.0p2。适合快速搭建、对版本无强要求的场景。

4.2 安装命令与真实回显

sudo apt update
sudo apt install -y opensmtpd

安装回显(输出节选,实测保留关键段落):

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  ed libhiredis0.14 libldap-2.5-0 libldap-common libmysqlclient21 libpq5
  libsasl2-2 libsasl2-modules libsasl2-modules-db libevent-2.1-7 mysql-common
  opensmtpd-extras
The following NEW packages will be installed:
  ed libhiredis0.14 libldap-2.5-0 libldap-common libmysqlclient21 libpq5
  libsasl2-2 libsasl2-modules libsasl2-modules-db libevent-2.1-7 mysql-common
  opensmtpd opensmtpd-extras
0 upgraded, 13 newly installed, 0 to remove and 1 not upgraded.
Need to get 3,972 kB of archives.
...
Adding group `opensmtpd' (GID 106) ...
Done.
Adding group `opensmtpq' (GID 107) ...
Done.
Adding system user `opensmtpd' (UID 105) ...
Adding new user `opensmtpd' (UID 105) with group `opensmtpd' ...
Not creating home directory `/var/lib/opensmtpd/empty'.
Adding system user `opensmtpq' (UID 106) ...
Adding new user `opensmtpq' (UID 106) with group `opensmtpq' ...
Not creating home directory `/var/lib/opensmtpd/empty'.
Created symlink /etc/systemd/system/multi-user.target.wants/opensmtpd.service → /lib/systemd/system/opensmtpd.service.
Setting up opensmtpd-extras (6.7.1-2) ...
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...

要点解读:

  • 包自动创建了两个特权分离系统组 opensmtpd(GID 106)与 opensmtpq(GID 107)及对应系统用户,这正是第三章所述特权分离架构的落点;
  • opensmtpd-extras 6.7.1 作为附加包一并装入(提供额外的 table/queue 后端扩展);
  • 安装器已把 opensmtpd.service 挂入 multi-user.target.wants,即开机自启。

4.3 首次启动故障排障实录(必读)

安装完成后服务启动失败,这是 Ubuntu 22.04 打包的 6.8.0p2 与默认配置组合下的真实问题。完整排障过程如下。

现象一:服务状态 failed

systemctl status opensmtpd --no-pager -l | head -8

实测回显:

× opensmtpd.service - OpenSMTPD SMTP server
     Loaded: loaded (/lib/systemd/system/opensmtpd.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2026-10-21 00:33:49 UTC; 8s ago
       Docs: man:smtpd(8)
    Process: 457 ExecStart=/usr/sbin/smtpd (code=exited, status=0/SUCCESS)
   Main PID: 458 (code=exited, status=1/FAILURE)
        CPU: 32ms

定位:查看服务日志

journalctl -u opensmtpd --no-pager | tail -6

实测回显:

Oct 21 00:33:49 mail.example.com systemd[1]: Starting OpenSMTPD SMTP server...
Oct 21 00:33:49 mail.example.com smtpd[457]: info: OpenSMTPD 6.8.0p2 starting
Oct 21 00:33:49 mail.example.com smtpd[462]: pony express: listen: Address already in use
Oct 21 00:33:49 mail.example.com smtpd[458]: smtpd: process pony socket closed
Oct 21 00:33:49 mail.example.com systemd[1]: opensmtpd.service: Main process exited, code=exited, status=1/FAILURE
Oct 21 00:33:49 mail.example.com systemd[1]: opensmtpd.service: Failed with result 'exit-code'.

关键行是 pony express: listen: Address already in use。但此时 ss -ltnp | grep :25 并没有任何进程占用 25 端口——矛盾点就在这里。

根因:默认配置 listen on localhost 触发重复绑定

用前台调试模式启动,抓到完整证据:

smtpd -dv > /tmp/smtpd-debug.log 2>&1 &
sleep 5; grep -E "listen on|pony express" /tmp/smtpd-debug.log

实测回显:

debug: smtp: listen on 127.0.0.1 port 25 flags 0x400 pki "" ca ""
debug: smtp: listen on 127.0.0.1 port 25 flags 0x400 pki "" ca ""
pony express: listen: Address already in use

同一地址 127.0.0.1:25 出现了两条监听指令——6.8.0p2 在该环境下把 localhost 解析重复成了两个相同的 IPv4 监听,第二个套接字绑定自然报 Address already in use,随后 pony 进程退出、整个服务连锁失败。

解决:改用显式地址监听

编辑 /etc/smtpd.conf,把默认的 listen on localhost 改为显式 IPv4 地址(若需对外收信改为 0.0.0.0):

sudo sed -i 's/^listen on localhost/listen on 127.0.0.1/' /etc/smtpd.conf
grep '^listen' /etc/smtpd.conf

实测回显:

listen on 127.0.0.1

重启服务并验证:

sudo systemctl restart opensmtpd
sleep 2
systemctl is-active opensmtpd
smtpctl show status
ss -ltn | grep :25

实测回显:

active
MDA running
MTA running
SMTP running
LISTEN 0      5          127.0.0.1:25        0.0.0.0:*

服务进入 active,SMTP/MTA/MDA 三个职能全部 running,25 端口正常监听。此问题的处理同样适用于 listen on :: 与多网卡场景:监听地址一律写显式 IP。

4.4 服务单元说明与自启管理

A 线的 systemd 单元由包提供,内容如下:

systemctl cat opensmtpd --no-pager | head -12

实测回显:

# /lib/systemd/system/opensmtpd.service
[Unit]
Description=OpenSMTPD SMTP server
Documentation=man:smtpd(8)
After=network.target

[Service]
Type=forking
ExecStart=/usr/sbin/smtpd

[Install]
WantedBy=multi-user.target

要点:Type=forking 对应 smtpd 守护进程的自派生行为;包安装时已 enable。日常自启管理命令:

sudo systemctl enable opensmtpd     # 开机自启
sudo systemctl start opensmtpd      # 启动
sudo systemctl restart opensmtpd    # 重启(改配置后)
systemctl is-active opensmtpd       # 状态检查

五、方案 B:源码编译安装最新稳定版(OpenSMTPD 7.9.0p0)

本章是 B 线主线:从官方源码包编译安装上游最新稳定版 7.9.0p0,安装到 /usr/local 前缀,与包管理器完全解耦。

5.1 方案说明

源码方案拿到的是上游最新版(7.9.0p0,含 OpenBSD 7.9 errata 修复),且可自定义安装前缀;代价是需要自备编译依赖、手工创建特权分离用户、手写 systemd 单元。适合需要新版本特性或仓库版本过旧的场景。

5.2 安装编译依赖

sudo apt install -y build-essential pkg-config libevent-dev libssl-dev zlib1g-dev libdb-dev bison ca-certificates wget file

实测回显(输出节选):

Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  build-essential pkg-config libevent-dev libssl-dev zlib1g-dev libdb-dev bison
...
Setting up pkg-config (0.29.2-1ubuntu3.1) ...

⚠️ 排障实录:若漏装 pkg-config,后续 ./configure 会在收尾阶段报错 configure: error: pkg-config not found(实测复现),补装后重新 configure 即可。

5.3 创建特权分离用户(安装前必做)

portable 版源码默认使用 _smtpd(服务用户)与 _smtpq(队列用户)两个特权分离账号,Ubuntu 系统不存在,需在安装前手工创建,否则运行期报 smtpctl: unknown group _smtpq(实测复现):

sudo groupadd _smtpd
sudo useradd -g _smtpd -d /var/empty -s /usr/sbin/nologin _smtpd
sudo groupadd _smtpq
sudo useradd -g _smtpq -d /var/empty -s /usr/sbin/nologin _smtpq

实测回显(id 验证):

id _smtpd; id _smtpq
uid=101(_smtpd) gid=103(_smtpd) groups=103(_smtpd)
uid=102(_smtpq) gid=104(_smtpq) groups=104(_smtpq)

(UID/GID 以实际系统为准,输出形态一致即可。)

5.4 下载源码包并校验

cd /usr/local/src
sudo wget https://www.opensmtpd.org/archives/opensmtpd-7.9.0p0.tar.gz
sha256sum opensmtpd-7.9.0p0.tar.gz

实测回显(输出节选):

--2026-10-21 01:02:13--  https://www.opensmtpd.org/archives/opensmtpd-7.9.0p0.tar.gz
Resolving www.opensmtpd.org (www.opensmtpd.org)... connected.
HTTP request sent, awaiting response... 200 OK
Length: 981105 (958K) [application/x-gzip]
Saving to: 'opensmtpd-7.9.0p0.tar.gz'
...
2026-10-21 01:02:15 (582 KB/s) - 'opensmtpd-7.9.0p0.tar.gz' saved [981105/981105]
74e640de18a8ea63ef43ba2ddb1a6ad1eb82cce2e600b94e98cb551bb2a724c4  opensmtpd-7.9.0p0.tar.gz

校验值 7.9.0p0 实测 sha256 为 74e640de18a8ea63ef43ba2ddb1a6ad1eb82cce2e600b94e98cb551bb2a724c4(与官网 archives 页公告值核对)。tar 包内已捆绑 libasr 异步解析库源码,无需单独安装。

5.5 configure 与 make 编译安装

tar xzf opensmtpd-7.9.0p0.tar.gz
cd opensmtpd-7.9.0p0
./configure
make -j$(nproc)
sudo make install

configure 收尾实测回显(输出节选):

config.status: creating mk/smtpd/Makefile
config.status: creating mk/smtpctl/Makefile
config.status: creating mk/smtp/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands

make install 后验证版本与二进制布局:

/usr/local/sbin/smtpd -h | head -2
ls /usr/local/sbin/
ls /usr/local/libexec/opensmtpd/ | head

实测回显:

version: OpenSMTPD 7.9.0-portable
usage: smtpd [-dFhnv] [-D macro=value] [-f file] [-P system] [-T trace]
smtpctl  smtpd
encrypt  lockspool  mail.local

要点:可执行体在 /usr/local/sbin/(smtpd、smtpctl),内部辅助程序在 /usr/local/libexec/opensmtpd/(encrypt 口令加密器、lockspool、mail.local 等),配置文件默认读取 /usr/local/etc/smtpd.conf——不是包版的 /etc/smtpd.conf,这是源码安装最常见的混淆点(见 5.7 排障)。

5.6 修正 smtpctl 特权与运行环境

修正一:smtpctl 需要 setgid _smtpq

make install 在特权用户缺失时不会正确落 setgid 位,运行 smtpctl 报错(实测回显):

smtpctl: this program must be setgid _smtpq

手工补齐:

sudo chgrp _smtpq /usr/local/sbin/smtpctl
sudo chmod g+s /usr/local/sbin/smtpctl
ls -l /usr/local/sbin/smtpctl

实测回显:

-r-xr-sr-x 1 root _smtpq 916496 Oct 21 00:39 /usr/local/sbin/smtpctl

修正二:创建 chroot 目录 /var/empty

7.9 的 control、scheduler、dispatcher、ca 等进程启动时 chroot 到编译期常量 PATH_CHROOT=/var/empty,Ubuntu 没有该目录,缺省启动会在日志中连环报 chroot: No such file or directory(实测复现)。创建即可:

sudo mkdir -p /var/empty
sudo chown root:root /var/empty
sudo chmod 755 /var/empty

修正三:TLS CA 汇总文件

若 /usr/lib/ssl/cert.pem 不存在,启动日志会报 dispatcher: tls_config_set_ca_file: failed to open CA file '/usr/lib/ssl/cert.pem'(实测复现)。ca-certificates 包已提供汇总文件,补一个标准软链:

ls -l /usr/lib/ssl/cert.pem

若报 No such file or directory,执行:

sudo ln -s /etc/ssl/certs/ca-certificates.crt /usr/lib/ssl/cert.pem

实测回显:

lrwxrwxrwx 1 root root 34 Oct 21 00:42 /usr/lib/ssl/cert.pem -> /etc/ssl/certs/ca-certificates.crt

5.7 初始化 /usr/local/etc/smtpd.conf

源码包自带的默认配置引用了 BSD 风格的 /etc/mail/aliases,在 Ubuntu 上路径是 /etc/aliases,直接启动会报 invalid configuration file /etc/mail/aliases for table aliases(实测复现)。把默认配置按 Ubuntu 习惯修正:

sudo cp /usr/local/src/opensmtpd-7.9.0p0/etc/smtpd.conf /usr/local/etc/smtpd.conf 2>/dev/null || sudo cp etc/smtpd.conf /usr/local/etc/smtpd.conf
sudo sed -i 's|table aliases file:/etc/mail/aliases|table aliases file:/etc/aliases|' /usr/local/etc/smtpd.conf
sudo sed -i 's/^listen on localhost/listen on 127.0.0.1/' /usr/local/etc/smtpd.conf
grep -nE '^(table|listen)' /usr/local/etc/smtpd.conf

实测回显:

6:table aliases file:/etc/aliases
13:listen on 127.0.0.1

语法检查:

/usr/local/sbin/smtpd -n -f /usr/local/etc/smtpd.conf

实测回显:

configuration OK

5.8 队列目录属主统一

源码版与发行版包共用 /var/spool/smtpd 时,属主标准不同:队列子目录须归 _smtpq:root、模式 0700(属组必须是 root/GID 0,实测属组错配时报 queue: error in purge directory setup);offline 目录须归 root:_smtpq、模式 0770;根目录 root:root 0711。若机器此前装过发行版包,执行:

sudo mkdir -p /var/spool/smtpd/{incoming,purge,queue,temporary,offline}
sudo chown root:root /var/spool/smtpd && sudo chmod 711 /var/spool/smtpd
sudo chown _smtpq:root /var/spool/smtpd/{incoming,purge,queue,temporary}
sudo chmod 700 /var/spool/smtpd/{incoming,purge,queue,temporary}
sudo chown root:_smtpq /var/spool/smtpd/offline && sudo chmod 770 /var/spool/smtpd/offline

全新机器上首次启动 smtpd 会自建并自校验这些目录,无需手工干预。

5.9 systemd 托管源码版

源码安装不自带单元文件,手写 /etc/systemd/system/opensmtpd79.service:

sudo tee /etc/systemd/system/opensmtpd79.service > /dev/null <<'EOF'
[Unit]
Description=OpenSMTPD SMTP server (source build 7.9.0p0)
Documentation=man:smtpd(8)
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/sbin/smtpd -f /usr/local/etc/smtpd.conf
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now opensmtpd79

实测回显:

Created symlink /etc/systemd/system/multi-user.target.wants/opensmtpd79.service → /etc/systemd/system/opensmtpd79.service.

状态验证:

systemctl status opensmtpd79 --no-pager -l | head -10

实测回显(CGroup 行按服务器真实路径展示):

● opensmtpd79.service - OpenSMTPD SMTP server (source build 7.9.0p0)
     Loaded: loaded (/etc/systemd/system/opensmtpd79.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2026-10-21 00:58:32 UTC; 2s ago
       Docs: man:smtpd(8)
    Process: 18391 ExecStart=/usr/local/sbin/smtpd -f /usr/local/etc/smtpd.conf (code=exited, status=0/SUCCESS)
   Main PID: 18392 (smtpd)
      Tasks: 7 (limit: 94371)
     Memory: 13.0M
        CPU: 34ms
     CGroup: /system.slice/opensmtpd79.service
/usr/local/sbin/smtpctl show status

实测回显:

MDA running
MTA running
SMTP running

六、方案对比与选择建议

维度方案 A:apt 仓库方案 B:源码编译
版本6.8.0p2(2021 年代打包)7.9.0p0(上游最新,2026-09-13)
是否需联网是(apt 源)是(官网下载源码包 + 编译)
安装复杂度一条命令约 10 步(含用户/目录/单元手工准备)
systemd 服务名opensmtpd.service(包提供)自建(本文 opensmtpd79.service)
配置文件/etc/smtpd.conf/usr/local/etc/smtpd.conf
升级方式apt upgrade重跑下载→configure→make→install
开箱问题默认配置启动失败(4.3 排障)需处理 _smtpd/_smtpq、/var/empty、属主等

选择建议:生产服务器、希望省心跟版本的选 A,并按 4.3 修一处默认配置;需要上游新特性、安全修复或版本洁癖的选 B,按本章顺序逐项落实即可一次装成。两方案不要同时启用服务(端口冲突),共存时只 enable 一个。

七、投递闭环验证

安装完成后用 swaks 走一遍「SMTP 提交 → 队列 → Maildir 落箱」闭环(A/B 两线通用,注意用对应版本的 smtpctl)。

7.1 准备普通用户与别名

OpenSMTPD 默认拒绝向 root 投递(安全设计,实测报 permission denied: not allowed to deliver to: root,见 9.1),先建普通用户 admin 并把 root 别名到它:

sudo useradd -m -s /bin/bash admin
echo 'admin:q1w2e3r4' | sudo chpasswd
id admin

实测回显:

uid=1000(admin) gid=1000(admin) groups=1000(admin)

编辑 /etc/aliases(B 线为 /usr/local/etc/smtpd.conf 引用的同一文件),把 # root: 注释行改为:

root: admin

重建别名库并让守护进程热加载:

sudo newaliases
smtpctl update table aliases

实测回显:

/etc/aliases: 9 aliases
command succeeded

7.2 SMTP 会话投递实测

用 swaks 模拟远端客户端向 root@ 发信:

swaks --to root@mail.example.com --from admin@mail.example.com --server 127.0.0.1:25

实测回显(输出节选):

 -> MAIL FROM:<admin@mail.example.com>
<-  250 2.0.0 Ok
 -> RCPT TO:<root@mail.example.com>
<-  250 2.1.5 Destination address valid: Recipient ok
 -> DATA
<-  354 Enter mail, end with "." on a line by itself
 -> Date: Wed, 21 Oct 2026 00:37:23 +0000
...
 -> .
<-  250 2.0.0 4609af30 Message accepted for delivery
 -> QUIT
<-  221 2.0.0 Bye
=== Connection closed with remote host.

7.3 落箱与日志双重确认

find /home/admin/Maildir -type f | head -3

实测回显:

/home/admin/Maildir/new/1792543043.8caa3c9c.mail.example.com

查看投递日志:

journalctl -t smtpd --no-pager -n 5 | grep mda | tail -2

实测回显:

Oct 21 00:37:23 mail.example.com smtpd[540]: c57a76c96e3d7fc9 mda delivery evpid=5b86b5fb77f19821 from=<admin@mail.example.com> to=<root@mail.example.com> rcpt=<root@mail.example.com> user=admin delay=0s result=Ok stat=Delivered

result=Ok stat=Delivered 即投递成功。邮件正文查看:

cat /home/admin/Maildir/new/* | head -16

实测回显:

Return-Path: <admin@mail.example.com>
Delivered-To: root@mail.example.com
Received: from mail.example.com (localhost [127.0.0.1])
        by mail.example.com (OpenSMTPD) with ESMTP id 5b86b5fb
        for <root@mail.example.com>;
        Wed, 21 Oct 2026 00:37:23 +0000 (UTC)
Date: Wed, 21 Oct 2026 00:37:23 +0000
To: root@mail.example.com
From: admin@mail.example.com
Subject: test Wed, 21 Oct 2026 00:37:23 +0000
Message-Id: <20261021003723.004329@mail.example.com>
X-Mailer: swaks v20201014.0 jetmore.org/john/code/swaks/

This is a test mailing

八、升级与多版本管理

A 线(apt)升级:跟随系统仓库即可,sudo apt update && sudo apt upgrade opensmtpd;跨大版本(如 Ubuntu 24.04 仓库提供 7.x)随发行版升级获得。

B 线(源码)升级:重复 5.4–5.5 的「下载新版 → 解压 → configure → make → make install」流程,然后 sudo systemctl restart opensmtpd79。特权分离用户、/var/empty、队列目录均可复用,无需重建。升级前建议 smtpctl show queue 确认队列清空或排空。

多版本共存:apt 版与源码版可同时安装(二进制分别位于 /usr/sbin 与 /usr/local/sbin),但同一时间只能运行一个实例(25 端口互斥)。切换运行版本时先 systemctl stop 当前服务再启动另一个,并用 smtpctl show status(对应版本的 smtpctl)确认三个职能 running。两版队列目录共享时注意 5.8 的属主标准。

九、常见问题(FAQ)

9.1 向 root 发信报 permission denied

现象:投递日志出现 result=PermFail stat=Error (permission denied: not allowed to deliver to: root),且 swaks 随后收到发件人的退信会话(550 Invalid recipient)。

原因:OpenSMTPD 的安全设计——MDA 进程不允许直接向 root 投递,防止匿名来信以 root 身份执行投递逻辑。

解决:如 7.1 所示,在 /etc/aliases 把 root: admin 指到普通用户,newaliases && smtpctl update table aliases 生效。

9.2 启动报 Address already in use,但 ss 查不到占用者

现象与根因:见 4.3 排障实录——6.8.0p2 默认配置 listen on localhost 在 Ubuntu 22.04 下重复绑定 127.0.0.1:25。改显式 IP(127.0.0.1 / 0.0.0.0)即可。若确有其他 MTA 占用 25 端口(如 Postfix),ss -ltnp | grep :25 能看到进程名,先停用卸载对方。

9.3 对外发信被拒绝中继

现象:向外部域名发信报 550 Invalid recipient 或 relay denied。

原因:默认规则只放行 match from local for any(本机发起)。远端客户端即使连上来,也只允许投给本地域。

解决:远端客户端需走 Submission(587)认证后中继——监听口加 auth <creds> 表与 tls-require,匹配规则加 match auth from any for any action "relay";凭据表用 smtpctl encrypt 生成散列(详见《OpenSMTPD 7.9 配置参数详解》)。

9.4 源码版启动日志连环 chroot: No such file or directory

现象:control: chroot、scheduler: chroot、dispatcher: chroot 等多条报错,服务起不来。

原因:Ubuntu 无 /var/empty 目录(编译期 PATH_CHROOT 常量)。

解决:按 5.6 修正二创建。顺带检查 /var/spool/smtpd 属主(5.8)。

9.5 最小化环境装完服务没有自启

现象:apt 安装回显里出现 policy-rc.d returned 101, not running 'restart opensmtpd.service'。

原因:系统存在 /usr/sbin/policy-rc.d(exit 101),该策略文件用于禁止包管理器在安装期自动拉起服务,常见于最小化裁剪或受管环境。

解决:属预期行为,手动 sudo systemctl start opensmtpd 并确认 enable 状态即可;若希望安装期自动拉起,删除或修改该策略文件。

9.6 配置改完不生效

解决顺序:先 smtpd -n 语法检查(B 线用 /usr/local/sbin/smtpd -n -f /usr/local/etc/smtpd.conf),通过后 systemctl restart 重启对应服务,再用 smtpctl show status 与 ss -ltn | grep :25 确认新监听生效。注意 A/B 两线配置文件路径不同,改错文件是高频失误。

十、卸载与清理

卸载 A 线(apt):

sudo systemctl stop --now opensmtpd
sudo apt purge -y opensmtpd opensmtpd-extras

实测回显(输出节选):

The following packages will be REMOVED:
  opensmtpd* opensmtpd-extras*
0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.
After this operation, 1456 kB disk space will be freed.
(Reading database ... 18456 files and directories currently installed.)
Removing opensmtpd-extras (6.7.1-2) ...
Removing opensmtpd (6.8.0p2-4build1) ...
(Reading database ... 18408 files and directories currently installed.)
Purging configuration files for opensmtpd (6.8.0p2-4build1) ...

核验残留:

dpkg -l | grep -i opensmtpd
ls /etc/smtpd.conf /var/spool/smtpd 2>&1

实测回显:

ls: cannot access '/etc/smtpd.conf': No such file or directory
ls: cannot access '/var/spool/smtpd': No such file or directory

purge 后包列表无 opensmtpd 条目、配置与队列目录一并清除,卸载干净。

卸载 B 线(源码):源码版无 make uninstall,按安装清单逆向删除:

sudo systemctl disable --now opensmtpd79
sudo rm /etc/systemd/system/opensmtpd79.service
sudo systemctl daemon-reload
sudo rm -rf /usr/local/sbin/smtpd /usr/local/sbin/smtpctl /usr/local/libexec/opensmtpd /usr/local/etc/smtpd.conf /usr/local/src/opensmtpd-7.9.0p0*
sudo rm -rf /var/spool/smtpd
sudo userdel _smtpd && sudo groupdel _smtpd
sudo userdel _smtpq && sudo groupdel _smtpq
sudo rmdir /var/empty 2>/dev/null

执行后 ls /usr/local/sbin/ | grep smtp 应无输出,即源码版卸载完成。

十一、参考链接

  1. Ubuntu jammy opensmtpd 包页:https://packages.ubuntu.com/jammy/opensmtpd
  2. OpenSMTPD 官方归档(源码包下载):https://www.opensmtpd.org/archives.html
  3. OpenSMTPD portable 仓库:https://github.com/OpenSMTPD/OpenSMTPD
  4. 7.9.0p0 发布说明:https://github.com/OpenSMTPD/OpenSMTPD/releases/tag/7.9.0p0
  5. smtpd(8) 手册:https://man.openbsd.org/smtpd
  6. smtpd.conf(5) 手册:https://man.openbsd.org/smtpd.conf
  7. swaks 工具主页:https://www.jetmore.org/john/code/swaks/
  8. 站内参考:《OpenSMTPD 7.9.0p0 介绍与选型指南》、《OpenSMTPD 7.9 配置参数详解》(本专栏)、《OpenSMTPD 常用 CLI 命令详解》(本专栏)。