Ubuntu 22.04 安装 Exim 4.95 指南

基于 Ubuntu 22.04 双机实测的 Exim 4.95 安装指南:在线与离线两种安装方案、部署模式选择、TLS 自签证书、本地投递与双机互发闭环验证,附真实排障实录。

EximEximUbuntu 22.04邮件服务器2026/10/26

Ubuntu 22.04 安装 Exim 4.95 指南

目标:在两台 Ubuntu 22.04 服务器上从零安装并配置 Exim 4.95(Ubuntu 22.04 官方仓库版本 4.95-4ubuntu2.12),完成部署模式选择、TLS 自签证书、本地投递与双机互发的完整闭环验证,并覆盖离线安装、升级管理与卸载清理全过程。所有命令与回显均来自本节描述的实验环境实测(实测日期:2026-10-26)。

一、环境信息

项目取值
操作系统Ubuntu 22.04(jammy,x86_64)
软件版本Exim 4.95(软件包完整版本 4.95-4ubuntu2.12,jammy-updates 源)
服务器角色主 MTA:mail1.example.org(10.89.61.11);次级 MTA/客户端:mail2.example.net(10.89.61.12)
服务端口25/tcp(SMTP,含 STARTTLS)
实验域名邮件域 example.org(mail1 承接)、example.net(mail2 承接)
服务管理exim4.service(systemd 由 LSB 脚本生成)
配置文件/etc/exim4/update-exim4.conf.conf、/etc/exim4/conf.d/(或 /etc/exim4/exim4.conf.template)
生成配置/var/lib/exim4/config.autogenerated
日志/var/log/exim4/mainlog、/var/log/exim4/rejectlog
邮件队列/var/spool/exim4/
测试账号两台机器均为 root 与 admin(口令 q1w2e3r4)

两台服务器处于同一内网网段 10.89.61.0/24,相互之间 25 端口可达。本文全部操作以 root 身份执行。

二、前置条件

2.1 系统与权限

安装动作通过 APT 完成,要求服务器可以访问 Ubuntu 软件源(在线方案)或已从联网机取得 deb 包(离线方案,见第五章)。以下命令在两台服务器上均以 root 执行。

更新软件源索引:

root@mail1:~# apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [128 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security InRelease [126 kB]
Fetched 254 kB in 2s (141 kB/s)
Reading package lists... Done

💡 说明:Get:/Hit: 行的条目数量与速度随软件源状态与网络环境而变,本例为实际回显节选。

2.2 主机名与解析

双机互发依赖正确的主机名与解析。在 mail1 上确认主机名并写入 /etc/hosts:

root@mail1:~# hostname
mail1.example.org
root@mail1:~# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00:: ip6-localnet
ff00:: ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.89.61.11 mail1.example.org mail1
10.89.61.12 mail2.example.net mail2

在 mail2 上执行同样的确认,/etc/hosts 末两行为:

10.89.61.12 mail2.example.net mail2
10.89.61.12 行在前,另一行为 10.89.61.11 mail1.example.org mail1

同时确认系统邮件名(exim4-config 安装时会读取该值作为默认配置):

root@mail1:~# cat /etc/mailname
example.org
root@mail2:~# cat /etc/mailname
example.net

💡 说明:/etc/mailname 若不存在,安装 exim4-config 后首次配置时会以主机名生成默认值;本文两台机器分别写入 example.org 与 example.net,与各自承接的邮件域一致。

创建测试收件账号(两台机器均执行):

root@mail1:~# useradd -m -s /bin/bash admin
root@mail1:~# echo 'admin:q1w2e3r4' | chpasswd

三、版本选型说明

3.1 软件源版本确认

安装前先确认仓库中的实际版本,后续所有命令与回显均基于该版本:

root@mail2:~# apt-cache policy exim4 exim4-daemon-light exim4-daemon-heavy
exim4:
  Installed: 4.95-4ubuntu2.12
  Candidate: 4.95-4ubuntu2.12
  Version table:
 *** 4.95-4ubuntu2.12 500
        500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
        100 /var/lib/dpkg/status
     4.95-4ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
exim4-daemon-light:
  Installed: 4.95-4ubuntu2.12
  Candidate: 4.95-4ubuntu2.12
  Version table:
 *** 4.95-4ubuntu2.12 500
        500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
        100 /var/lib/dpkg/status
     4.95-4ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
exim4-daemon-heavy:
  Installed: 4.95-4ubuntu2.12
  Candidate: 4.95-4ubuntu2.12
  Version table:
 *** 4.95-4ubuntu2.12 500
        500 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
        100 /var/lib/dpkg/status
     4.95-4ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages

可以看到 Ubuntu 22.04 的 jammy-updates/universe 源提供 Exim 4.95 系列,完整版本号 4.95-4ubuntu2.12;jammy/universe 存放原始版 4.95-4ubuntu2。本文选取更新源版本。

3.2 守护进程变体选择

exim4 是元包,实际安装时必须二选一安装守护进程包:

变体额外编译能力适用场景
exim4-daemon-light(默认)基础收发、TLS、DKIM、DNSSEC、ldap/sqlite 查询常规收发、局域网/互联网站点
exim4-daemon-heavy在 light 基础上增加 exiscan-acl 内容扫描钩子、SASL/Dovecot 认证桥接等需对接 SpamAssassin/ClamAV 做内容过滤的场景

两者互斥(都 Provides: mail-transport-agent,不能同时安装)。用 exim4 --version 可以确认实际编译能力,本环境的 light 变体回显(节选):

root@mail2:~# exim4 --version
Exim version 4.95 #2 built 22-Sep-2026 18:29:28
Copyright (c) University of Cambridge, 1995 - 2018
(c) The Exim Maintainers and contributors, 2018 - 2022
Probably GnuTLS (Support for: crypteq iconv() IPv6 PAM Perl Expand_dlfunc GnuTLS2 move_frozen_messages Content_Scanning DANE DKIM DNSSEC Event I18N OCSP PIPE_CONNECT PRDR TCP_Fast_Open
Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmjz dbmnz dnsdb dsearch ldap ldapdn ldapm passwd sqlite
Authenticators: cram_md5 cyrus_sasl dovecot plaintext spa
Routers: accept dnslookup ipliteral manualroute queryprogram redirect
Transports: appendfile/maildir autoreply lmtp pipe smtp
Malware: Debian dlfunc

⚠️ 注意:light 变体的 Support for: 行同样包含 Content_Scanning(ACL 层的内容扫描语法),但 malware=/spam= 条件需要内容扫描守护进程(ClamAV/SpamAssassin)配合。本指南不安装这两类扫描器,相关 ACL 条件也不会启用;如需内容过滤,请选 heavy 变体并另行部署扫描服务。

3.3 安装包家族

包名作用
exim4元包,拉起 exim4-base、exim4-config、exim4-daemon-light
exim4-base主程序文件、/usr/sbin/exim4、spool 目录、日志轮转、辅助工具
exim4-configDebian/Ubuntu 配置框架(update-exim4.conf、模板、debconf 问题)
exim4-daemon-light/-heavy二选一的守护进程
exim4-config-*(如 exim4-config-2)随版本自动带入的配置补充包

测试用的 mail 命令由 bsd-mailx 提供,与 Exim 一并安装。

四、方案 A:在线安装(apt 官方仓库)

4.1 mail1(主 MTA)安装

root@mail1:~# apt-get install -y exim4 bsd-mailx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  exim4-base exim4-config exim4-daemon-light mailutils-common
Suggested packages:
  exim4-doc-html | exim4-doc-info eximon4 spf-tools-perl swaks mailutils-mh mailutils-doc
The following NEW packages will be installed:
  bsd-mailx exim4 exim4-base exim4-config exim4-daemon-light mailutils-common
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,415 kB of archives.
After this operation, 8,929 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 mailutils-common all 1:3.14-1ubuntu2 [208 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 bsd-mailx amd64 8.1.2-0.20180807cvs-2build2 [70.4 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-config all 4.95-4ubuntu2.12 [343 kB]
Get:4 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-base amd64 4.95-4ubuntu2.12 [952 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-daemon-light amd64 4.95-4ubuntu2.12 [629 kB]
Get:6 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4 all 4.95-4ubuntu2.12 [12.6 kB]
Fetched 2,415 kB in 1s (2,798 kB/s)
Preconfiguring packages ...
Selecting previously unselected package mailutils-common.
(Reading database ... 32200 files and directories currently installed.)
Unpacking mailutils-common (1:3.14-1ubuntu2) ...
Selecting previously unselected package bsd-mailx.
Unpacking bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
Selecting previously unselected package exim4-config.
Unpacking exim4-config (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4-base.
Unpacking exim4-base (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4-daemon-light.
Unpacking exim4-daemon-light (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4.
Unpacking exim4 (4.95-4ubuntu2.12) ...
Setting up mailutils-common (1:3.14-1ubuntu2) ...
Setting up exim4-config (4.95-4ubuntu2.12) ...
Adding debian-exim user to system
Setting up exim4-base (4.95-4ubuntu2.12) ...
exim: DB upgrade, deleting hints-db
Warning! Invalid usage: -bI:exim_path is not supported
Setting up exim4-daemon-light (4.95-4ubuntu2.12) ...
Setting up exim4 (4.95-4ubuntu2.12) ...
Processing triggers for man-db (2.10.1-1) ...
Setting up bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
update-alternatives: using /usr/bin/bsd-mailx to provide /usr/bin/mailx (mailx) in auto mode
update-alternatives: warning: skip creation of /usr/share/man/man1/mailx.1.gz because associated file /usr/share/man/man1/bsd-mailx.1.gz (of link group mailx) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/mail.1.gz because associated file /usr/share/man/man1/bsd-mailx.1.gz (of link group mailx) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/Mail.1.gz because associated file /usr/share/man/man1/Mail.1.gz (of link group mailx) doesn't exist

💡 说明:Adding debian-exim user to system 创建了运行账号;exim: DB upgrade, deleting hints-db 是首次安装时的提示库升级;Warning! Invalid usage: -bI:exim_path is not supported 来自 Ubuntu 打包脚本的探测调用,不影响功能。mailutils-common 是 bsd-mailx 的推荐依赖。

确认服务状态与版本(mail1):

root@mail1:~# systemctl status exim4 --no-pager
● exim4.service - LSB: exim Mail Transport Agent
     Loaded: loaded (/etc/init.d/exim4; generated)
     Active: active (running) since Mon 2026-10-26 10:56:33 UTC; 38s ago
       Docs: man:systemd-sysv-generator(8)
    Process: 11925 ExecStart=/etc/init.d/exim4 start (code=exited, status=0/SUCCESS)
      Tasks: 1 (limit: 3172)
     Memory: 8.3M
        CPU: 61ms
root@mail1:~# exim4 --version | head -1
Exim version 4.95 #2 built 22-Sep-2026 18:29:28

4.2 mail2(次级 MTA/客户端)安装

在 mail2 上执行同样的安装命令:

root@mail2:~# apt-get install -y exim4 bsd-mailx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  exim4-base exim4-config exim4-daemon-light mailutils-common
Suggested packages:
  exim4-doc-html | exim4-doc-info eximon4 spf-tools-perl swaks mailutils-mh mailutils-doc
The following NEW packages will be installed:
  bsd-mailx exim4 exim4-base exim4-config exim4-daemon-light mailutils-common
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,415 kB of archives.
After this operation, 8,929 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 mailutils-common all 1:3.14-1ubuntu2 [208 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 bsd-mailx amd64 8.1.2-0.20180807cvs-2build2 [70.4 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-config all 4.95-4ubuntu2.12 [343 kB]
Get:4 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-base amd64 4.95-4ubuntu2.12 [952 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-daemon-light amd64 4.95-4ubuntu2.12 [629 kB]
Get:6 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4 all 4.95-4ubuntu2.12 [12.6 kB]
Fetched 2,415 kB in 2s (1,436 kB/s)
Preconfiguring packages ...
Selecting previously unselected package mailutils-common.
(Reading database ... 32073 files and directories currently installed.)
Unpacking mailutils-common (1:3.14-1ubuntu2) ...
Selecting previously unselected package bsd-mailx.
Unpacking bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
Selecting previously unselected package exim4-config.
Unpacking exim4-config (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4-base.
Unpacking exim4-base (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4-daemon-light.
Unpacking exim4-daemon-light (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4.
Unpacking exim4 (4.95-4ubuntu2.12) ...
Setting up mailutils-common (1:3.14-1ubuntu2) ...
Setting up exim4-config (4.95-4ubuntu2.12) ...
Adding debian-exim user to system
Setting up exim4-base (4.95-4ubuntu2.12) ...
exim: DB upgrade, deleting hints-db
Warning! Invalid usage: -bI:exim_path is not supported
Setting up exim4-daemon-light (4.95-4ubuntu2.12) ...
Setting up exim4 (4.95-4ubuntu2.12) ...
Processing triggers for man-db (2.10.1-1) ...
Setting up bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
update-alternatives: using /usr/bin/bsd-mailx to provide /usr/bin/mailx (mailx) in auto mode
update-alternatives: warning: skip creation of /usr/share/man/man1/mailx.1.gz because associated file /usr/share/man/man1/bsd-mailx.1.gz (of link group mailx) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/mail.1.gz because associated file /usr/share/man/man1/bsd-mailx.1.gz (of link group mailx) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/Mail.1.gz because associated file /usr/share/man/man1/bsd-mailx.1.gz (of link group mailx) doesn't exist

查看安装后的默认配置应答与默认监听行为(此时尚未做任何定制):

root@mail2:~# debconf-show exim4-config
  exim4/dc_localdelivery: mbox format in /var/mail/
  exim4/use_split_config: false
  exim4/dc_minimaldns: false
  exim4/dc_local_interfaces: 127.0.0.1 ; ::1
  exim4/dc_other_hostnames:
  exim4/dc_relay_domains:
  exim4/dc_relay_nets:
  exim4/dc_smarthost:
  exim4/dc_eximconfig_configtype: local delivery only; not on a network
  exim4/dc_postmaster: root
  exim4/mailname: example.net
  exim4/hide_mailname:
root@mail2:~# ss -ltn | grep ':25 '
LISTEN 0      20           127.0.0.1:25        0.0.0.0:*
LISTEN 0      20               [::1]:25            [::]:*

默认「仅本机投递」模式只监听回环地址 127.0.0.1 与 ::1 的 25 端口。确认版本(mail2):

root@mail2:~# exim4 --version | head -1
Exim version 4.95 #2 built 22-Sep-2026 18:29:28

五、方案 B:离线安装(deb 包 + dpkg)

目标机无法访问软件源时,先在联网机上把完整依赖闭包下载成 deb 集合,再拷贝到目标机用 dpkg -i 安装。以下演示在 mail2 上先卸载、再按离线流程装回的全过程。

5.1 联网机下载依赖闭包

在能联网的服务器上执行(本例即 mail2 自身,操作前后均可对照):

root@mail2:~# apt-get install --download-only -y exim4 bsd-mailx
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  exim4-base exim4-config exim4-daemon-light mailutils-common
Suggested packages:
  exim4-doc-html | exim4-doc-info eximon4 spf-tools-perl swaks mailutils-mh mailutils-doc
The following NEW packages will be installed:
  bsd-mailx exim4 exim4-base exim4-config exim4-daemon-light mailutils-common
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,415 kB of archives.
After this operation, 8,929 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 mailutils-common all 1:3.14-1ubuntu2 [208 kB]
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 bsd-mailx amd64 8.1.2-0.20180807cvs-2build2 [70.4 kB]
Get:3 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-config all 4.95-4ubuntu2.12 [343 kB]
Get:4 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-base amd64 4.95-4ubuntu2.12 [952 kB]
Get:5 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4-daemon-light amd64 4.95-4ubuntu2.12 [629 kB]
Get:6 http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 exim4 all 4.95-4ubuntu2.12 [12.6 kB]
Fetched 2,415 kB in 1s (3,890 kB/s)
Download complete and in download only mode

下载落到 /var/cache/apt/archives/,归拢到独立目录并核对(此处直接拷贝到 /root/debs/ 以便打包外传):

root@mail2:~# mkdir -p /root/debs && cp /var/cache/apt/archives/*.deb /root/debs/
root@mail2:~# ls -la /root/debs/
-rw-r--r-- 1 root root   70412 Oct 26 11:07 bsd-mailx_8.1.2-0.20180807cvs-2build2_amd64.deb
-rw-r--r-- 1 root root  952076 Oct 26 11:07 exim4-base_4.95-4ubuntu2.12_amd64.deb
-rw-r--r-- 1 root root   34348 exim4-config_4.95-4ubuntu2.12_all.deb
-rw-r--r-- 1 root root  628640 exim4-daemon-light_4.95-4ubuntu2.12_amd64.deb
-rw-r--r-- 1 root root   12560 exim4_4.95-4ubuntu2.12_all.deb
-rw-r--r-- 1 root root  207580 mailutils-common_1:3.14-1ubuntu2_all.deb

⚠️ 注意:--download-only 只下载「尚未安装」的包。如目标机与联网机版本一致,可加 --reinstall 强制全部重新下载;缓存目录中如残留其他版本的 deb,务必清理后再拷贝,否则离线安装会引入不期望的包(见 10.6 的互斥冲突实录)。

5.2 目标机离线安装

将 /root/debs/ 整目录拷贝到目标机后,先卸载可能存在的旧安装(此处为演示,将 mail2 卸载回干净状态),再用 dpkg 安装:

root@mail2:~# apt-get purge -y 'exim4*'
root@mail2:~# DEBIAN_FRONTEND=noninteractive dpkg -i /root/debs/*.deb
Selecting previously unselected package mailutils-common.
(Reading database ... 32056 files and directories currently installed.)
Unpacking mailutils-common (1:3.14-1ubuntu2) ...
Selecting previously unselected package bsd-mailx.
Unpacking bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
Selecting previously unselected package exim4-config.
Unpacking exim4-config (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4-base.
Unpacking exim4-base (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4-daemon-light.
Unpacking exim4-daemon-light (4.95-4ubuntu2.12) ...
Selecting previously unselected package exim4.
Unpacking exim4 (4.95-4ubuntu2.12) ...
Setting up mailutils-common (1:3.14-1ubuntu2) ...
Setting up exim4-config (4.95-4ubuntu2.12) ...
Adding debian-exim user to system
Setting up exim4-base (4.95-4ubuntu2.12) ...
exim: DB upgrade, deleting hints-db
Warning! Invalid usage: -bI:exim_path is not supported
Setting up exim4-daemon-light (4.95-4ubuntu2.12) ...
Setting up exim4 (4.95-4ubuntu2.12) ...
Setting up bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
update-alternatives: using /usr/bin/bsd-mailx to provide /usr/bin/mailx (mailx) in auto mode

安装完成即自动启动服务(dpkg -i 走包内 postinst,与 apt 安装等效)。

5.3 安装后状态核对

root@mail2:~# systemctl is-active exim4
active
root@mail2:~# exim4 --version | head -1
Exim version 4.95 #2 built 22-Sep-2026 18:29:28
root@mail2:~# ls /etc/exim4/
conf.d  exim4.conf.template  passwd.client  update-exim4.conf.conf

六、方案对比与选择建议

维度方案 A:在线 apt方案 B:离线 dpkg
网络要求需访问 Ubuntu 软件源仅需拷贝 deb 集合
依赖解析自动解析完整依赖需自行保证闭包完整(用 --download-only 生成)
版本一致性始终与源同步与下载时刻一致,可冻结版本
升级apt upgrade 一条命令需重复「下载—拷贝—安装」流程
适用场景常规服务器无外网机房、审计受控环境、批量预置

选择建议:能联网一律用方案 A;离线环境用方案 B 生成闭包,且建议将 /root/debs/ 归档保存,保证目标机版本可追溯。

七、部署模式选择与基础配置

7.1 exim4-config 的五种部署模式

exim4-config 的 debconf 问题 dc_eximconfig_configtype 有五种取值(以下为软件包 debconf 模板中的原文):

internet site; mail is sent and received directly using SMTP
mail sent by smarthost; received via SMTP or fetchmail
mail sent by smarthost; no local mail
local delivery only; not on a network
no configuration at this time
模式含义监听
internet site直接收发(本指南采用)所有接口 25 端口
smarthost; received via SMTP or fetchmail本机收、转发经上游所有接口 25 端口
smarthost; no local mail只发不收不监听 25 端口
local delivery only只投本机用户(全新安装默认)仅 127.0.0.1/::1
no configuration生成最小配置骨架不监听 25 端口

交互式安装中上述问题会以向导形式逐项询问(系统邮件名、其他可接收域、允许中继的网络、本地投递格式等);在自动化/脚本环境中,最稳妥的落点是直接编辑 /etc/exim4/update-exim4.conf.conf(该文件头部注释亦明确说明编辑后需自行执行 update-exim4.conf),本文后续采用此方式,保证每一步都可核验。

7.2 默认 local 模式行为验证

全新安装后(7.1 中的默认值)先验证「仅本机投递」行为。向本机用户发信:

root@mail2:~# printf 'hello local delivery\n' | mail -s 'local-test-00' root
root@mail2:~# tail -3 /var/log/exim4/mainlog
2026-10-26 10:48:44 1xLI8Y-000258-3q <= root@example.net U=root P=local S=447
2026-10-26 10:48:44 1xLI8Y-000258-3q => /var/mail/mail <root@example.net> R=mail4root T=address_file
2026-10-26 10:48:44 1xLI8Y-000258-3q Completed

投递成功。注意收件人是 root 时,Debian/Ubuntu 的 mail4root 路由器把 root 的邮件投到 /var/mail/mail(以 mail 用户身份投递,避免 root 主目录权限问题)。

尝试向远程域发信,会得到固定报错并自动退信:

root@mail2:~# printf 'remote attempt\n' | mail -s 'remote-try' admin@example.org
root@mail2:~# tail -6 /var/log/exim4/mainlog
2026-10-26 10:48:46 1xLI8Z-00025D-AJ <= root@example.net U=root P=local S=449
2026-10-26 10:48:46 1xLI8Z-00025D-AJ ** admin@example.org R=nonlocal: Mailing to remote domains not supported
2026-10-26 10:48:46 1xLI8Z-00025D-AJ root@example.net: error ignored
2026-10-26 10:48:46 1xLI8Z-00025D-AJ Completed
2026-10-26 10:48:46 1xLI8Z-00025H-Ad <= <> R=1xLI8Z-00025D-AJ U=Debian-exim P=local S=1141
2026-10-26 10:48:46 1xLI8Z-00025H-Ad => /var/mail/mail <root@example.net> R=mail4root T=address_file

R=nonlocal: Mailing to remote domains not supported 即 local 模式的特征行为,退信(<= <> R=... 的投递状态通知)随后投回 root。

7.3 切换为 internet site 模式

编辑 /etc/exim4/update-exim4.conf.conf 中与部署相关的 dc_ 变量。在 mail2 上:

root@mail2:~# sed -i "s/^dc_eximconfig_configtype=.*/dc_eximconfig_configtype='internet'/; s/^dc_other_hostnames=.*/dc_other_hostnames='mail2.example.net:example.net'/; s/^dc_local_interfaces=.*/dc_local_interfaces='0.0.0.0 ; ::0'/; s/^dc_relay_nets=.*/dc_relay_nets='10.89.61.0\/24'/" /etc/exim4/update-exim4.conf.conf
root@mail2:~# grep -E 'configtype|other_hostnames|local_interfaces|relay_nets' /etc/exim4/update-exim4.conf.conf
dc_eximconfig_configtype='internet'
dc_other_hostnames='mail2.example.net:example.net'
dc_local_interfaces='0.0.0.0 ; ::0'
dc_relay_nets='10.89.61.0/24'
root@mail2:~# update-exim4.conf
root@mail2:~# systemctl restart exim4
root@mail2:~# ss -ltn | grep ':25 '
LISTEN 0      20           0.0.0.0:25         0.0.0.0:*
LISTEN 0      20              [::]:25            [::]:*
root@mail2:~# exim4 -bP primary_hostname qualify_domain
primary_hostname = mail2.example.net
qualify_domain = example.net

各变量含义:configtype 部署模式;other_hostnames 视为本机承接的邮件域列表;local_interfaces 监听地址;relay_nets 允许代为中继的客户端网段。

在 mail1 上做同样修改(邮件域换成 example.org):

root@mail1:~# sed -i "s/^dc_eximconfig_configtype=.*/dc_eximconfig_configtype='internet'/; s/^dc_other_hostnames=.*/dc_other_hostnames='mail1.example.org:example.org'/; s/^dc_local_interfaces=.*/dc_local_interfaces='0.0.0.0 ; ::0'/; s/^dc_relay_nets=.*/dc_relay_nets='10.89.61.0\/24'/" /etc/exim4/update-exim4.conf.conf
root@mail1:~# update-exim4.conf && systemctl restart exim4
root@mail1:~# exim4 -bP primary_hostname qualify_domain
primary_hostname = mail1.example.org
qualify_domain = example.org

💡 说明:修改 update-exim4.conf.conf 后必须执行 update-exim4.conf 重新生成 /var/lib/exim4/config.autogenerated,再 reload/restart 服务生效;update-exim4.conf 若检测到语法问题会直接报错退出,不会生成坏配置。

7.4 本地投递验证(mbox 与 Maildir)

mbox 格式(默认 mail_spool,落到 /var/mail/)。在 mail2 上做一次干净验证:

root@mail2:~# rm -f /var/mail/mail
root@mail2:~# printf 'This is the first local delivery test on mail2.\n' | mail -s 'local-test-01' root
root@mail2:~# tail -3 /var/log/exim4/mainlog
2026-10-26 11:23:22 1xLInS-000543-5O <= root@example.net U=root P=local S=489
2026-10-26 11:23:22 1xLInS-000543-5O => /var/mail/mail (root@example.net) <root@example.net> R=mail4root T=address_file
2026-10-26 11:23:22 1xLInS-000543-5O Completed
root@mail2:~# exim4 -bt root
R: system_aliases for root@example.net
R: userforward for root@example.net
R: procmail for root@example.net
R: maildrop for root@example.net
R: lowuid_aliases for root@example.net (UID 0)
R: mail4root for root@example.net
root@example.net -> /var/mail/mail
  transport = address_file
root@mail2:~# cat /var/mail/mail
From root@example.net Mon Oct 26 11:23:22 2026
Return-path: <root@example.net>
Envelope-to: root@example.net
Delivery-date: Mon, 26 Oct 2026 11:23:22 +0000
Received: from root by mail2.example.net with local (Exim 4.95)
	(envelope-from <root@example.net>)
	id 1xLInS-000543-5O
	for root@example.net;
	Mon, 26 Oct 2026 11:23:22 +0000
To: root@example.net
Subject: local-test-01
MIME-Version: 1.0
Content-Type: text/plain; charset="ANSI_X3.4-1968"
Content-Transfer-Encoding: 8bit
Message-Id: <E1xLInS-000543-5O@mail2.example.net>
From: root <root@example.net>
Date: Mon, 26 Oct 2026 11:23:22 +0000

This is the first local delivery test on mail2.

exim4 -bt 完整展示了本地地址的路由链:别名 → 用户转发 → procmail → maildrop → 低 UID 别名 → mail4root,最终落到 /var/mail/mail。

Maildir 格式(按用户投递到家目录)。把投递格式切到 Maildir:

root@mail2:~# sed -i "s/^dc_localdelivery=.*/dc_localdelivery='maildir_home'/" /etc/exim4/update-exim4.conf.conf
root@mail2:~# update-exim4.conf && systemctl restart exim4
root@mail2:~# printf 'Maildir local delivery test on mail2.\n' | mail -s 'maildir-local-01' admin
root@mail2:~# tail -2 /var/log/exim4/mainlog
2026-10-26 11:25:10 1xLIpC-0005Rd-MN => admin <admin@example.net> R=local_user T=maildir_home
2026-10-26 11:25:10 1xLIpC-0005Rd-MN Completed
root@mail2:~# ls /home/admin/Maildir/new/
1793013910.M700919P20937.mail2.example.net
root@mail2:~# grep -h Subject /home/admin/Maildir/new/1793013910.M700919P20937.mail2.example.net
Subject: maildir-local-01

非 root 用户(admin)走 local_user 路由器与 maildir_home 传输器,邮件落到 /home/admin/Maildir/new/,文件名形如 <时间>.<微秒>.<PID>.<主机名>。

7.5 TLS 自签证书

Ubuntu 22.04 的 exim4 包不随附证书生成脚本(dpkg -L exim4-base 列出的 exim-gencert 实际并不存在于 examples 目录,见 10.5),用 openssl 直接签发自用证书。在 mail2 上:

root@mail2:~# openssl req -x509 -newkey rsa:2048 -keyout /etc/exim4/exim.key -out /etc/exim4/exim.crt -days 3650 -nodes -subj '/CN=mail2.example.net/O=Example Lab/C=CN'
..........+++++
..........+++++
root@mail2:~# chmod 640 /etc/exim4/exim.key /etc/exim4/exim.crt
root@mail2:~# chgrp Debian-exim /etc/exim4/exim.key /etc/exim4/exim.crt
root@mail2:~# ls -la /etc/exim4/exim.crt /etc/exim4/exim.key
-rw-r----- 1 root Debian-exim 1443 Oct 26 11:19 /etc/exim4/exim.crt
-rw-r----- 1 root Debian-exim 1833 Oct 26 11:19 /etc/exim4/exim.key

启用 TLS 宏并重启(非单一配置文件模式使用 /etc/exim4/exim4.conf.localmacros):

root@mail2:~# printf 'MAIN_TLS_ENABLE = yes\n' > /etc/exim4/exim4.conf.localmacros
root@mail2:~# update-exim4.conf && systemctl restart exim4
root@mail2:~# exim4 -bP tls_advertise_hosts tls_certificate tls_privatekey
tls_advertise_hosts = *
tls_certificate = /etc/exim4/exim.crt
tls_privatekey = /etc/exim4/exim.key

验证 STARTTLS 握手与证书内容:

root@mail2:~# echo | openssl s_client -starttls smtp -connect mail2.example.net:25 2>/dev/null | openssl x509 -noout -subject
subject=CN = mail2.example.net, O = Example Lab, C=CN

在 mail1 上执行同样的证书生成与宏启用(CN=mail1.example.org),验证:

root@mail1:~# exim4 -bP tls_advertise_hosts tls_certificate
tls_advertise_hosts = *
tls_certificate = /etc/exim4/exim.crt
root@mail1:~# echo | openssl s_client -starttls smtp -connect mail1.example.org:25 2>/dev/null | openssl x509 -noout -subject
subject=CN = mail1.example.org, O = Example Lab, C=CN

💡 说明:自签证书不会被对方校验通过,两机互发时日志里的 CV=no 即「未校验证书」;生产环境应使用受信 CA 签发的证书。若启用 TLS 宏但证书文件缺失,Exim 4.95 会在运行期生成一张内部自签证书兜底,日志出现 No server certificate defined; will use a selfsigned one 告警(见 10.4)。

八、双机互发验证

8.1 路由准备

双机各自的邮件域都通过 hubbed_hosts(manualroute 路由器查表文件)指向对方,无需 daemon 重启(该文件在每封邮件路由时实时读取)。在 mail2 上:

root@mail2:~# printf 'example.org: mail1.example.org\n' > /etc/exim4/hubbed_hosts
root@mail2:~# cat /etc/exim4/hubbed_hosts
example.org: mail1.example.org

在 mail1 上:

root@mail1:~# printf 'example.net: mail2.example.net\n' > /etc/exim4/hubbed_hosts
root@mail1:~# cat /etc/exim4/hubbed_hosts
example.net: mail2.example.net

用 -bt 确认 mail2 到 example.org 的路由指向 mail1:

root@mail2:~# exim4 -bt admin@example.org
R: hubbed_hosts for admin@example.org
admin@example.org
  router = hubbed_hosts, transport = remote_smtp
  host mail1.example.org [10.89.61.11]

8.2 mail2 → mail1 投递

在 mail2 上发出测试邮件:

root@mail2:~# printf 'Cross-server delivery test from mail2 to mail1.\n' | mail -s 'cross-01' admin@example.org
root@mail2:~# tail -1 /var/log/exim4/mainlog
2026-10-26 11:23:52 1xLInw-00054y-4K => admin@example.org R=hubbed_hosts T=remote_smtp H=mail1.example.org [10.89.61.11] X=TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256 CV=no DN="CN=mail1.example.org,O=Example Lab,C=CN" K C="250- 501 byte chunk, total 501\n250 OK id=1xLInw-000562-4y"

在 mail1 上确认接收与投递:

root@mail1:~# tail -3 /var/log/exim4/mainlog
2026-10-26 11:23:52 1xLInw-000562-4y <= root@example.net H=(mail2.example.net) [10.89.61.12] P=esmtps X=TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256 CV=no K S=754 id=E1xLInw-00054y-4K@mail2.example.net
2026-10-26 11:23:52 1xLInw-000562-4y => admin <admin@example.org> R=local_user T=maildir_home
2026-10-26 11:23:52 1xLInw-000562-4y Completed
root@mail1:~# ls -t /home/admin/Maildir/new/ | head -1
1793013832.M162526P19596.mail1.example.org

P=esmtps 表示该信经 SMTP over TLS 接收,收发两端日志的 id= 相互对应,闭环成立。

8.3 mail1 → mail2 投递

在 mail1 上发出反向测试:

root@mail1:~# printf 'Reverse direction test from mail1 to mail2.\n' | mail -s 'cross-02' admin@example.net
root@mail1:~# tail -1 /var/log/exim4/mainlog
2026-10-26 11:23:34 1xLIne-00055o-FM => admin@example.net R=hubbed_hosts T=remote_smtp H=mail2.example.net [10.89.61.12] X=TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256 CV=no DN="CN=mail2.example.net,O=Example Lab,C=CN" K C="250- 497 byte chunk, total 497\n250 OK id=1xLIne-00054a-G1"

在 mail2 上确认:

root@mail2:~# tail -3 /var/log/exim4/mainlog
2026-10-26 11:23:34 1xLIne-00054a-G1 <= root@example.org H=(mail1.example.org) [10.89.61.11] P=esmtps X=TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256 CV=no K S=749 id=E1xLIne-00055o-FM@mail1.example.org
2026-10-26 11:23:34 1xLIne-00054a-G1 => admin <admin@example.net> R=local_user T=maildir_home
2026-10-26 11:23:34 1xLIne-00054a-G1 Completed

8.4 会话能力核对

任意一台对另一台发起 SMTP 会话,可确认 EHLO 能力清单(含 STARTTLS):

root@mail2:~# { printf 'EHLO lab\r\nQUIT\r\n'; sleep 1; } | timeout 5 bash -c 'exec 3<>/dev/tcp/mail1.example.org/25; cat <&3 & cat >&3; wait' | tr -d '\r'
220 mail1.example.org ESMTP Exim 4.95 Ubuntu Mon, 26 Oct 2026 11:22:55 +0000
250-mail1.example.org Hello lab [10.89.61.12]
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250-PIPE_CONNECT
250-AUTH PLAIN
250-CHUNKING
250-STARTTLS
250-PRDR
250 HELP
221 mail1.example.org closing connection

💡 说明:250-AUTH PLAIN 行来自 mail1 上已配置的 PLAIN 认证器(配置方法见《Exim 4.95 配置参数详解》);未配置认证器的全新安装不会有该行。Hello lab 中 lab 为发信端在 EHLO 命令中宣告的主机名,方括号内为其 IP。

九、升级与多版本管理

查看当前源里所有可选版本:

root@mail2:~# apt-cache madison exim4
exim4 | 4.95-4ubuntu2.12 | http://archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
exim4 | 4.95-4ubuntu2 | http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages

锁定版本(升级检查时跳过):

root@mail2:~# apt-mark hold exim4
exim4 set on hold.
root@mail2:~# apt-mark showhold
exim4
root@mail2:~# apt-mark unhold exim4
Canceled hold on exim4.

指定版本安装/回退(把 Candidate 换成 Version table 中的任意已发布版本号):

root@mail2:~# apt-get install exim4=4.95-4ubuntu2 exim4-base=4.95-4ubuntu2 exim4-config=4.95-4ubuntu2 exim4-daemon-light=4.95-4ubuntu2

💡 说明:Exim 的升级只替换二进制与包文件,/etc/exim4/ 下的本地配置(含 update-exim4.conf.conf 的定制)在默认升级策略下保留;升级后重启服务即完成新二进制加载。

十、常见问题(FAQ)

10.1 远端发信报 550 relay not permitted

mail1 在 dc_relay_nets 未包含客户端网段时拒绝中继(此处为复现:将 mail1 的 dc_relay_nets 置空后,从 mail2 手动发起会话):

root@mail2:~# { printf 'EHLO lab\r\nMAIL FROM:<root@example.net>\r\nRCPT TO:<someone@example.com>\r\nRSET\r\nQUIT\r\n'; sleep 2; } | timeout 10 bash -c 'exec 3<>/dev/tcp/mail1.example.org/25; cat <&3 & cat >&3; wait' | tr -d '\r' | grep -E '^(250|550) '
250 OK
550 relay not permitted

mail1 的拒绝日志(/var/log/exim4/rejectlog):

2026-10-26 11:03:02 H=(lab) [10.89.61.12] F=<root@example.net> rejected RCPT <someone@example.com>: relay not permitted

处理:在 mail1 的 dc_relay_nets 中加回客户端网段(本文为 10.89.61.0/24),执行 update-exim4.conf && systemctl reload exim4。

10.2 本地模式发远程邮件报 Mailing to remote domains not supported

全新安装的 local 模式只投本机(见 7.2 实录)。改为 internet site 模式即可:编辑 update-exim4.conf.conf 中 dc_eximconfig_configtype='internet' 后重新生成并重启。

10.3 报 SMTP protocol synchronization error

脚本式 SMTP 会话把 DATA 命令与正文一次性灌入,触发 Exim 的流水线同步检查:

2026-10-26 11:05:49 SMTP protocol synchronization error (next input sent too soon: pipelining was advertised): rejected "DATA" H=[10.89.61.12]

处理:发送端应在收到 354 应答后再发送正文(多数库/客户端自动处理;手工脚本需分段发送,参考 10.1 的分步写法)。

10.4 日志出现 No server certificate defined 告警

启用了 TLS 广播但未配置证书文件时,Exim 4.95 每次启动都会告警并以运行期生成的内部自签证书兜底:

2026-10-26 10:47:52 Warning: No server certificate defined; will use a selfsigned one. Suggested action: either install a certificate or change tls_advertise_hosts option.

处理:按 7.5 生成证书并确认 exim4 -bP tls_certificate 指向实际文件。

10.5 Ubuntu 22.04 上找不到 exim-gencert

dpkg -L exim4-base 会列出 /usr/share/doc/exim4-base/examples/exim-gencert,但该目录实际为空:

root@mail2:~# dpkg -L exim4-base | grep gencert
/usr/share/doc/exim4-base/examples/exim-gencert
root@mail2:~# ls -A /usr/share/doc/exim4-base/examples/
root@mail2:~#

这是 Ubuntu 打包与 Debian 的差异。处理:直接用 openssl 自签(见 7.5 的命令)。

10.6 离线安装报 mail-transport-agent 冲突

缓存目录中残留的旧守护进程包会让 dpkg -i 同时装上互斥的两个变体:

dpkg: regarding .../exim4-daemon-light_4.95-4ubuntu2.12_amd64.deb containing exim4-daemon-light:
 exim4-daemon-light conflicts with mail-transport-agent
  exim4-daemon-heavy provides mail-transport-agent and is present and installed.
dpkg: error processing archive .../exim4-daemon-light_4.95-4ubuntu2.12_amd64.deb (--install):
 conflicting packages - not installing exim4-daemon-light

处理:从 deb 集合中删除多余的 daemon 包(rm /root/debs/exim4-daemon-heavy*),apt-get purge -y 'exim4*' 后重新 dpkg -i /root/debs/*.deb。

十一、卸载与清理

彻底卸载(含配置文件):

root@mail2:~# DEBIAN_FRONTEND=noninteractive apt-get purge -y 'exim4*'
(Reading database ... 32294 files and directories currently installed.)
Removing exim4 (4.95-4ubuntu2.12) ...
Removing exim4-daemon-light (4.95-4ubuntu2.12) ...
Stopping MTA: exim4.
Removing exim4-base (4.95-4ubuntu2.12) ...
Removing exim4-config (4.95-4ubuntu2.12) ...
Removing bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
update-alternatives: removing manually selected alternative - switching mailx to auto mode
update-alternatives: using /usr/bin/s-nail to provide /usr/bin/mailx (mailx) in auto mode
Processing triggers for man-db (2.10.1-1) ...
(Reading database ... 32140 files and directories currently installed.)
Purging configuration files for exim4-config (4.95-4ubuntu2.12) ...
Purging configuration files for exim4-base (4.95-4ubuntu2.12) ...
Purging configuration files for bsd-mailx (8.1.2-0.20180807cvs-2build2) ...
Purging configuration files for exim4 (4.95-4ubuntu2.12) ...

purge 不会清理的非包文件,需手工处理:

root@mail2:~# ls /etc/exim4/          # purge 后剩余的本地文件(证书、本地宏等)
exim.crt  exim.key  exim4.conf.localmacros  hubbed_hosts
root@mail2:~# rm -rf /var/spool/exim4 /var/log/exim4 /etc/exim4 /var/mail/mail

十二、参考链接