跳转到主要内容

于 2025年04月22日 摘录自 Postfix Installation From Source Code

1 - 本文档的目的

如果您使用的是 Postfix 的预编译版本,应从 BASIC_CONFIGURATION_README 开始,并参考其中引用的通用文档。INSTALL 仅是一个引导文档,用于以最少的步骤从头开始安装并运行 Postfix;它不应被视为通用文档的一部分。

本文档描述了如何构建、安装和配置 Postfix 系统,使其能够实现以下目标之一:

  • 仅发送邮件,不修改现有 Sendmail 安装。
  • 通过虚拟主机接口发送和接收邮件,仍不修改现有 Sendmail 安装。
  • 使用 Postfix 替代 Sendmail。

本文档涵盖的主题:

  1. 本文档的目的
  2. 排版约定
  3. 文档参考
  4. 在受支持系统上构建
  5. 将 Postfix 移植到不支持的系统
  6. 编译成功后安装软件
  7. 配置 Postfix 仅发送邮件
  8. 配置 Postfix 通过虚拟接口发送和接收邮件
  9. 使用 Postfix 替代 Sendmail
  10. 必修的配置文件修改
  11. 是否使用 chroot
  12. Postfix 系统的维护与管理

2 - 排版规范

在下面的说明中,以

# 命令

应以超级用户身份执行。

以以下形式书写的命令

$ 命令

应以普通用户身份执行。

3 - 文档

文档以 README 文件(从文件 README_FILES/AAAREADME 开始)、HTML 网页(将浏览器指向 "html/index.html")以及 UNIX 风格的手册页形式提供。

建议使用 more(1) 或 less(1) 等分页工具查看 README 文件,因为这些文件使用退格字符来生成 粗体 字体。若要打印不含退格字符的 README 文件,请使用 col(1) 命令。例如:

$ col -bx <;file | lpr

在安装 Postfix 之前查看手册页,请将 MANPATH 环境变量指向 "man" 子目录;确保使用绝对路径。

$ export MANPATH; MANPATH="`pwd`/man:$MANPATH"
$ setenv MANPATH "`pwd`/man:$MANPATH"

特别值得注意的是 postconf(5) 手册页,其中列出了所有 500 多个配置参数。该文本的 HTML 版本便于浏览。

所有 Postfix 源文件均内置了手册页。用于提取这些嵌入手册页的工具可在 mantools 目录中找到。

4 - 在受支持的系统上构建

Postfix 的开发工作在 FreeBSD 和 MacOS X 上进行,并在 Linux(Fedora、Ubuntu)和 Solaris 上进行定期测试。对其他系统的支持依赖于用户反馈,可能无法始终保持最新。

OpenBSD 部分支持。libc 解析器未实现文档中所述的"通过修改 _res 结构中的字段设置的内部解析器选项"(详见 OpenBSD 5.6 中的 resolver(3) 手册页)。这会导致过多的 DNS 查询,并可能对本应失败的查询返回错误结果。

主题概述:

4.1 - 开始

在 Solaris 系统中,"make" 命令和其他开发工具位于 /usr/ccs/bin 目录下,因此您必须将 /usr/ccs/bin 添加到命令搜索路径中。如果这些文件不存在,您需要先安装开发包。

如果您需要从单个源代码树为多个架构构建 Postfix,请使用 "lndir" 命令构建一个包含源文件符号链接的影子树。

在构建过程中,如果您遇到类似 "make: don't know how to ..." 的消息,您可以通过在 Postfix 顶级目录下运行以下命令恢复:

$ make -f Makefile.init makefiles

如果您在另一台机器上编译后复制了 Postfix 源代码,建议先进入顶级目录并执行以下操作:

$ make tidy

这将清除在其他地方编译软件时留下的任何系统依赖项。

4.2 - 使用哪个编译器

要使用 GCC 编译,或使用他人建议的更适合您系统的原生编译器,只需进入 Postfix 源代码树的顶级目录,并输入以下命令:

$ make

若要使用非默认编译器,需指定编译器名称。以下是几个示例:

$ make makefiles CC=/opt/SUNWspro/bin/cc (Solaris)
$ make
$ make makefiles CC="/opt/ansic/bin/cc -Ae" (HP-UX)
$ make
$ make makefiles CC="purify cc"
$ make

等等。在某些情况下,优化会自动关闭。

4.3 - 使用 Postfix 位置独立可执行文件进行构建(Postfix ≥ 3.0)

在某些系统上,Postfix 可以使用位置独立可执行文件进行构建。PIE 用于地址空间布局随机化(ASLR)漏洞缓解技术:

$ make makefiles pie=yes ...其他参数...

(指定 "make makefiles pie=no" 以明确禁用 Postfix 位置无关可执行文件支持)。

Postfix PIE 支持似乎在 Fedora Core 20、Ubuntu 14.04、FreeBSD 9 和 10,以及 NetBSD 6(均使用默认系统编译器)上正常工作。

上述 "pie=yes" 是否有效取决于编译器。部分编译器始终生成 PIE 可执行文件,而部分编译器甚至可能提示 Postfix 构建选项是多余的。

4.4 - 使用 Postfix 动态链接库和数据库插件进行构建(Postfix ≥ 3.0)

Postfix 动态链接库和数据库插件支持存在于 Linux、FreeBSD 和 MacOS X 的近期版本中。动态链接库构建可能在未来某个时间点成为默认设置。

主题概述:

注意:包含 Postfix 动态链接库或数据库插件的目录应仅包含与 Postfix 相关的文件。Postfix 动态链接库和数据库插件不应安装在"公共"系统目录(如 /usr/lib 或 /usr/local/lib)中。将 Postfix 动态链接库或数据库插件文件链接到非 Postfix 程序不被支持。Postfix 动态链接库和数据库插件实现了一个 Postfix 内部 API,该 API 会在不保持兼容性的情况下进行更改。

4.4.1 启用 Postfix 动态链接库支持

Postfix 可与 Postfix 动态链接库(通常命名为 libpostfix-*.so)一起构建。Postfix 动态链接库会增加少量运行时开销,但可显著减小 Postfix 可执行文件的大小。

在 "make makefiles" 命令行中指定 "shared=yes" 以构建支持动态链接库的 Postfix。

$ make makefiles shared=yes ...其他参数...
$ make

(指定 "make makefiles shared=no" 以明确禁用 Postfix 的动态链接库支持)。

这将动态链接库安装到 $shlib_directory,通常为 /usr/lib/postfix 或 /usr/local/lib/postfix,文件名为 libpostfix-name。 其中,name 是源代码目录名称,例如 "util" 或 "global"。

请参阅下方第 4.4.3 节"自定义 Postfix 动态链接库和数据库插件"以了解如何自定义 Postfix 动态链接库的位置,包括在不影响运行中的邮件系统的情况下进行升级的支持。

4.4.2 启用 Postfix 数据库插件支持

此外,Postfix 可通过 Debian 风格的 dynamicmaps 功能支持动态加载 Postfix 数据库客户端(数据库插件)。Postfix 3.0 支持动态加载 cdbldaplmdbmysql:, pcre:, pgsql:, sdbm:, 和 sqlite: 数据库客户端。动态加载在分发或安装预编译的 Postfix 包时非常有用。

在 "make makefiles" 命令行中指定 "dynamicmaps=yes",以构建支持通过 Debian 风格的 dynamicmaps 功能动态加载 Postfix 数据库客户端的 Postfix。

$ make makefiles dynamicmaps=yes ...其他参数...
$ make

(指定 "make makefiles dynamicmaps=no" 以显式禁用 Postfix 数据库插件支持)。

这会隐式启用动态链接库支持,将配置文件 dynamicmaps.cf 安装到 $meta_directory(通常为 /etc/postfix 或 /usr/local/etc/postfix),并将数据库插件安装到 $shlib_directory(见上文)。数据库插件命名为 postfix-type.so,其中 type 是数据库类型,如 "cdb" 或 "ldap"。

注意:Postfix 3.0 的构建流程假设您已通过名为 AUXLIBS_CDBAUXLIBS_LDAP 等。在 Postfix 3.0 及更高版本中,旧的 AUXLIBS 变量仍支持构建静态加载的数据库客户端,但仅新的 AUXLIBS_CDB 等变量支持构建动态加载或静态加载的 CDB 等数据库客户端。请参阅 CDB_READMELDAP_README 等文档以获取详细信息。

不遵循此建议将使动态数据库客户端加载失去意义。每个 Postfix 可执行文件都将依赖数据库库。而这正是动态数据库客户端加载旨在避免的情况。

请参阅下一节,了解如何自定义 Postfix 数据库插件的位置和版本以及 dynamicmaps.cf 文件的位置。

4.4.3 自定义 Postfix 动态链接库和数据库插件

自定义 Postfix 动态链接库和数据库插件的构建时和运行时选项

构建时环境变量 SHLIB_CFLAGS、SHLIB_RPATH 和 SHLIB_SUFFIX 用于控制 Postfix 库和插件的编译、链接及命名方式。

$ make makefiles SHLIB_CFLAGS=flags SHLIB_RPATH=rpath SHLIB_SUFFIX=suffix ...其他参数...
$ make

请参阅下方第 4.7 节"覆盖其他编译时特性"以获取详细信息。

自定义 Postfix 动态链接库和数据库插件的位置

提醒:包含 Postfix 动态链接库或数据库插件的目录应仅包含与 Postfix 相关的文件。不支持将这些文件链接到其他程序。

要覆盖 Postfix 动态链接库和数据库插件的默认位置,例如:

$ make makefiles shared=yes shlib_directory=/usr/local/lib/postfix ...

如果您计划在不停止邮件系统的情况下升级 Postfix,则应将 Postfix 发布版本附加到 shlib_directory 路径名中,以消除程序可能链接到错误 Postfix 版本的动态链接库或数据库插件的可能性。例如:

$ make makefiles shared=yes \
shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ...

命令 "make makefiles name=value..." 会将配置参数值末尾的字符串 MAIL_VERSION 替换为 Postfix 发布版本。请勿在此命令行中尝试指定类似 $mail_version 的内容。这会导致不同版本的 make(1) 命令产生不一致的结果。

您可以在 Postfix 构建完成后,通过 "make install" 或 "make upgrade" 更改 shlib_directory 设置。然而,如果您在 Postfix 构建后更改了 shlib_directory,可能需要运行 ldconfig(症状是 Postfix 程序因运行时链接器无法找到 libpostfix-*.so 文件而失败)。如果将 libpostfix-*.so 文件保留在编译时默认的 $shlib_directory 位置,则无需执行 ldconfig 命令。

# make upgrade shlib_directory=/usr/local/lib/postfix ...
# make install shlib_directory=/usr/local/lib/postfix ...

若要将 Postfix 发布版本附加到路径名以在不停止邮件系统的情况下升级 Postfix:

# make upgrade shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ...
# make install shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ...

参见上文关于使用 "make makefiles" 命令附加 MAIL_VERSION 的注释。

自定义 dynamicmaps.cf 及其他文件的位置

meta_directory 参数与 config_directory 参数具有相同的默认设置,通常为 /etc/postfix 或 /usr/local/etc/postfix。

您可以在编译时或 Postfix 构建完成后覆盖默认的 meta_directory 位置。要在编译时覆盖默认位置,请指定例如:

% make makefiles meta_directory=/usr/libexec/postfix ...

如果您希望路径名依赖于 Postfix 发布版本,这里有一个技巧:命令 "make makefiles name=value..." 会将配置参数值末尾的字符串 MAIL_VERSION 替换为 Postfix 发布版本。请勿在命令行中指定类似 $mail_version 的内容。这会导致不同版本的 make(1) 命令产生不一致的结果。

您可以在 Postfix 构建完成后,通过 "make install" 或 "make upgrade" 覆盖 meta_directory 设置。

# make upgrade meta_directory=/usr/libexec/postfix ...
# make install meta_directory=/usr/libexec/postfix ...

与命令 "make makefiles" 类似,命令 "make install/upgrade name=value..." 会将配置参数值末尾的字符串 MAIL_VERSION 替换为 Postfix 发布版本。请勿在此命令行中指定类似 $mail_version 的内容。这会导致不同版本的 make(1) 命令产生不一致的结果。

4.4.4 分发维护人员的提示

  • shlib_directory 参数设置还为数据库插件文件提供了默认目录,该目录在 dynamicmaps.cf 文件中以相对路径名指定。
  • meta_directory 参数指定了 dynamicmaps.cf、postfix-files 以及一些多实例模板文件的位置。meta_directory 参数与 config_directory 参数具有相同的默认值(通常为 /etc/postfix 或 /usr/local/etc/postfix)。为了向后兼容 Postfix 2.6 至 2.11 版本,请指定 "meta_directory = $daemon_directory" 在 main.cf 中,或在安装或升级 Postfix 之前,在 "make makefiles"、"make install" 或 "make upgrade" 命令行中指定 "meta_directory = /path/name"。
  • 配置文件 dynamicmaps.cf 会自动包含 dynamicmaps.cf.d 目录下的文件,就像配置文件 postfix-files 会自动包含 postfix-files.d 目录下的文件一样。因此,您可以安装或卸载数据库插件包而无需编辑 postfix-files 或 dynamicmaps.cf。相反,您为该插件在 dynamicmaps.cf.d 和 postfix-files.d 目录下提供独立的配置文件,并在安装或卸载数据库插件时动态链接这些配置文件。
  • 目录 dynamicmaps.cf.d 下的每个配置文件必须与配置文件 dynamicmaps.cf 具有相同的格式。这些配置文件的 *名称* 没有特定的格式要求。
  • 目录 postfix-files.d 下的每个配置文件必须与配置文件 postfix-files 具有相同的格式。这些配置文件的 *名称* 没有特定的格式要求。

4.5 - 带可选功能的构建

默认情况下,Postfix 作为一个相对简单的邮件系统进行构建。对第三方数据库等的支持必须在编译 Postfix 时进行配置。以下文档描述了如何构建支持可选功能的 Postfix:

可选功能文档可用性
Berkeley DB 数据库DB_READMEPostfix 1.0
LMDB 数据库LMDB_READMEPostfix 2.11
LDAP 数据库LDAP_READMEPostfix 1.0
MongoDB 数据库MONGODB_READMEPostfix 3.9
MySQL 数据库MYSQL_READMEPostfix 1.0
Perl 兼容正则表达式PCRE_READMEPostfix 1.0
PostgreSQL 数据库PGSQL_READMEPostfix 2.0
SASL 认证SASL_READMEPostfix 1.0
SQLite 数据库SQLITE_READMEPostfix 2.8
STARTTLS 会话加密TLS_READMEPostfix 2.2

注意:IP 版本 6 支持已编译到支持 IPv6 的操作系统上的 Postfix 中。有关详细信息,请参阅 IPV6_README 文件。

4.6 - 覆盖内置参数默认设置

4.6.1 - Postfix 3.0 及更高版本

所有 Postfix 配置参数均可通过编辑 Postfix 配置文件进行修改,但有一个例外:指定 Postfix 配置文件位置的参数。若要使用除 /etc/postfix 以外的配置目录构建 Postfix,请使用:

$ make makefiles config_directory=/some/where ...其他参数...
$ make

命令 "make makefiles name=value ..." 将用 Postfix 发布版本替换配置参数值末尾的字符串 MAIL_VERSION。请勿在此命令行中尝试指定类似 $mail_version 的内容。这会导致不同版本的 make(1) 命令产生不一致的结果。

可以通过此方式指定默认值的参数列表如下。请参阅 postconf(5) 手册页以获取描述(命令: "nroff -man man/man5/postconf.5 | less")。

参数名称典型默认值
command_directory/usr/sbin
config_directory/etc/postfix
default_database_typehash
daemon_directory/usr/libexec/postfix
data_directory/var/lib/postfix
html_directoryno
mail_spool_directory/var/mail
mailq_path/usr/bin/mailq
manpage_directory/usr/local/man
meta_directory/etc/postfix
newaliases_path/usr/bin/newaliases
openssl_pathopenssl
队列目录/var/spool/postfix
readme_directoryno
sendmail_path/usr/sbin/sendmail
shlib_directory/usr/lib/postfix

4.6.2 - 所有 Postfix 版本

所有 Postfix 配置参数均可通过编辑 Postfix 配置文件进行修改,但有一个例外:指定 Postfix 配置文件位置的参数。若需使用除 /etc/postfix 以外的配置目录构建 Postfix,请使用:

$ make makefiles CCARGS="-DDEF_CONFIG_DIR=\\\"/some/where\\\""
$ make

重要提示:请确保引号正确。这些细节非常重要。

以下列出了可以通过此方式指定默认值的参数。请参阅 postconf(5) 手册页以获取详细说明(命令: "nroff -man man/man5/postconf.5 | less")。

宏名称默认值用于典型默认值
DEF_COMMAND_DIRcommand_directory/usr/sbin
DEF_CONFIG_DIRconfig_directory/etc/postfix
DEF_DB_TYPEdefault_database_typehash
DEF_DAEMON_DIRdaemon_directory/usr/libexec/postfix
DEF_DATA_DIRdata_directory/var/lib/postfix
DEF_MAILQ_PATHmailq_path/usr/bin/mailq
DEF_HTML_DIRhtml_directoryno
DEF_MANPAGE_DIRmanpage_directory/usr/local/man
DEF_NEWALIAS_PATHnewaliases_path/usr/bin/newaliases
DEF_QUEUE_DIR队列目录/var/spool/postfix
DEF_README_DIRreadme_directoryno
DEF_SENDMAIL_PATHsendmail_path/usr/sbin/sendmail

注意:data_directory 参数(用于缓存和伪随机数)在 Postfix 2.5 版本中引入。

4.7 - 覆盖其他编译时特性

覆盖 Postfix 编译时功能的一般方法如下:

$ make makefiles name=value name=value...
$ make

以下是名称和值的详细列表。

名称/值描述
AUXLIBS="object_library..."指定一个或多个非默认对象库。Postfix 3.0 及更高版本使用 AUXLIBS_CDBAUXLIBS_LDAPAUXLIBS_LMDBAUXLIBS_MYSQLAUXLIBS_PCREAUXLIBS_PGSQL、AUXLIBS_SDBM 和 AUXLIBS_SQLITE,分别对应。
CC=编译器命令指定非默认编译器。在许多系统上,默认值为 gcc
CCARGS="compiler_arguments..."指定非默认编译器参数,例如非默认的 include 目录。以下指令在编译时禁用 Postfix 功能:
 ;-DNO_DB不包含 Berkeley DB 支持。默认情况下,Berkeley DB 支持会在已知支持此功能的平台上编译进去。如果覆盖此设置,则应按照第 4.6 节的描述覆盖 DEF_DB_TYPE。
 ;-DNO_DNSSEC不带 DNSSEC 支持进行构建,即使解析库似乎支持该功能。
 ;-DNO_DEVPOLL不带 Solaris /dev/poll 支持进行编译。默认情况下,/dev/poll 支持在已知支持此功能的 Solaris 版本中编译进去。
 ;-DNO_EPOLL不带 Linux EPOLL 支持进行编译。默认情况下,EPOLL 支持在已知支持此功能的平台上编译进去。
 ;-DNO_EAI不带 EAI (SMTPUTF8) 支持进行编译。默认情况下,EAI 支持在找到 "icuuc" 库和头文件时编译进去。
 ;-DNO_INLINE不要求支持 C99 "inline" 函数。相反,对于非 printf/scanf 类函数,使用三元运算符和不可达代码实现参数类型检查。
 ;-DNO_IPV6不包含 IPv6 支持。默认情况下,IPv6 支持会在已知支持 IPv6 的平台上编译进去。注意:此指令仅用于调试和测试。不保证在所有平台上都能正常工作。若不希望启用 IPv6 支持,请在 main.cf 中设置 "inet_protocols = ipv4"。
 ;-DNO_KQUEUE不带 FreeBSD / NetBSD / OpenBSD / MacOSX KQUEUE 支持进行编译。默认情况下,KQUEUE 支持在已知支持该功能的平台上编译进去。
 ;-DNO_NIS不包含 NIS 或 NISPLUS 支持。NIS 在某些较新的 Linux 发行版中不可用。
 ;-DNO_NISPLUS不带 NISPLUS 支持进行构建。NISPLUS 在某些较新的 Solaris 发行版中不可用。
 ;-DNO_PCRE不带 PCRE 支持进行编译。默认情况下,当 pcre-config 工具安装时,PCRE 支持会被编译进去。
 ;-DNO_POSIX_GETPW_R禁用对 POSIX getpwnam_r/getpwuid_r 的支持。默认情况下,Postfix 在已知可用时使用这些函数。
 ;-DNO_RES_NCALLS不使用线程安全的解析器 (5) API(res_ninit() 等)。
 ;-DNO_SIGSETJMP使用 setjmp()/longjmp() 代替 sigsetjmp()/siglongjmp()。默认情况下,Postfix 在这些函数可用时使用 sigsetjmp()/siglongjmp()
 ;-DNO_SNPRINTF使用 sprintf() 代替 snprintf()。默认情况下,Postfix 使用 snprintf(),除非在古老系统上。
DEBUG=debug_level指定非默认编译器调试级别。默认值为 "-g"。设置 DEBUG= 以关闭调试。
OPT=优化级别指定非默认优化级别。默认值为 "-O"。设置 OPT= 以关闭优化。
POSTFIX_INSTALL_OPTS=-option...指定 postfix-install 命令的选项,用空格分隔。目前仅支持 "-keep-build-mtime" 选项。
SHLIB_CFLAGS=flags指定用于构建 Postfix 动态链接库和数据库插件的非默认编译选项。典型默认值为 "-fPIC"。
SHLIB_RPATH=rpath指定 Postfix 动态链接库的非默认运行路径。典型默认值为 "'-Wl,-rpath,${SHLIB_DIR}'"。
SHLIB_SUFFIX=suffix指定 Postfix 动态链接库和数据库插件的非默认后缀。典型默认值为 ".so"。
WARN="warning_flags..."指定在源代码子目录中调用 "make" 时使用的非默认编译器警告选项。

4.8 - 支持数千个进程

Postfix 同时管理的连接数受其可运行的进程数限制。而这个数量又受单个进程可打开的文件和套接字数量的限制。例如,Postfix 队列管理器与每个交付进程都有单独的连接,而 anvil(8) 服务器每个 smtpd(8) 进程都有一个连接。

Postfix 2.4 及更高版本在编译于支持以下系统时,不存在打开文件或套接字的内置限制:

  • BSD kqueue(2) (FreeBSD 4.1, NetBSD 2.0, OpenBSD 2.9),
  • Solaris 8 /dev/poll,
  • Linux 2.6 epoll(4)。

对于其他 Postfix 版本或操作系统,每个进程的文件描述符数量受 FD_SETSIZE 宏的值限制。如果您预计运行超过 1000 个邮件投递进程,可能需要覆盖 FD_SETSIZE 宏的定义以确保 select() 正常工作:

$ make makefiles CCARGS=-DFD_SETSIZE=2048

警告:上述操作对某些 Linux 版本无效。显然,在这些系统中,FD_SETSIZE 的值只能通过未文档化的接口进行修改。目前这意味着需要直接包含 <;bits/types.h>;(这不被允许)并覆盖 __FD_SETSIZE 宏。请注意,未文档化的接口可能随时更改且不会提前通知。

但等等,还有更多:除非操作系统已配置为处理数千个连接,否则上述操作均无效。请参阅 TUNING_README 指南,了解如何增加打开的套接字或文件数量的示例。

4.9 - 编译 Postfix,终于到了这一步

如果命令

$ make

执行成功,则可以继续进行 安装 Postfix(第 6 节)。

如果命令产生编译器错误信息,可能需要搜索网络或咨询[email protected]邮件列表,但请务必先搜索邮件列表存档。部分邮件列表存档可通过http://www.postfix.org/访问。

5 - 将 Postfix 移植到不支持的系统

Postfix 识别的每种系统类型都有一个唯一的名称。例如:SUNOS5、FREEBSD4 等。在将 Postfix 移植到新系统时,第一步是为新系统选择一个 SYSTEMTYPE 名称。您必须使用包含操作系统主要版本(如 SUNOS4 或 LINUX2)的名称,以便在不同版本的同一系统上支持 Postfix 而不产生混淆。

在源代码顶级目录中的 "makedefs" 壳脚本中添加一个 case 语句,以可靠地识别新系统,并输出正确的系统特定信息。确保代码对用户 PATH 设置具有鲁棒性;如果系统提供多个 UNIX 变体(例如 BSD 和 SYSV),请确保构建原生变体,而非模拟变体。

在中央 util/sys_defs.h 包含文件中添加一个 "#ifdef SYSTEMTYPE" 部分。您可能需要发明新的功能宏名称。请选择合理的功能宏名称,例如 HAS_DBM 或 FIONREAD_IN_SYS_FILIO_H。

我强烈建议不要在单个源文件中使用"#ifdef SYSTEMTYPE"。虽然这看起来像是最快的解决方案,但当需要支持同一 SYSTEMTYPE 的新版本时,这会造成混乱。您很可能最终会在源代码的各个地方再次放置"#ifdef"部分。

6 - 编译成功后安装软件

本文描述了如何从源代码安装 Postfix。如果您正在为其他系统构建可分发包,请参阅 PACKAGE_README 文件。

6.1 - 保存现有 Sendmail 二进制文件

重要:如果您正在用 Postfix 替换现有的 Sendmail 安装,可能需要在一段时间内继续运行旧的 sendmail 程序以清空邮件队列。

  • 某些系统实现了邮件切换机制,允许同时安装多个 MTA(如 Postfix、Sendmail 等),但实际仅使用其中一个。此类切换机制的示例包括 FreeBSD 的 mailwrapper(8) 或 Linux 的邮件切换机制。在这种情况下,您应在安装 Postfix 之前尝试将切换开关设置为 "Postfix"。
  • 如果您的系统没有邮件切换机制,请执行以下命令(您的sendmail、newaliases和mailq程序可能位于不同位置):

    # mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF
    # mv /usr/bin/newaliases /usr/bin/newaliases.OFF
    # mv /usr/bin/mailq /usr/bin/mailq.OFF
    # chmod 755 /usr/sbin/sendmail.OFF /usr/bin/newaliases.OFF \
    /usr/bin/mailq.OFF
    

6.2 - 创建账户和组

在首次安装 Postfix 之前,您需要创建一个账户和一个组:

  • 创建一个名为 "postfix" 的用户账户,其用户 ID 和组 ID 均未被其他用户账户使用。建议此账户为无法登录的账户。该账户无需可执行登录 shell,且无需现有 home 目录。我的密码和组文件条目如下:

    /etc/passwd:
    postfix:*:12345:12345:postfix:/no/where:/no/shell
    /etc/group:
    postfix:*:12345:
    

    注意:在 "postfix:" 前不应有空格。

  • 创建一个名为"postdrop"的组,其组ID不得被其他任何用户账户使用,甚至不能被postfix用户账户使用。我的组文件条目如下:

    /etc/group:
    postdrop:*:54321:
    

    注意:在"postdrop:"前面不应有空格。

6.3 - 安装 Postfix

要从源代码编译并安装或升级 Postfix,请以超级用户身份运行以下命令之一:

# make install(交互式版本,首次安装)
# make upgrade(非交互式版本,用于升级)
  • 交互式版本("make install")会提示输入 Postfix 数据和程序文件的路径,并将您的首选项存储在 main.cf 文件中。如果您不希望 Postfix 覆盖非 Postfix 的 "sendmail"、"mailq" 和 "newaliases" 文件,请指定以 ".postfix" 结尾的路径名
  • 非交互式版本("make upgrade")需要从之前安装中获取 /etc/postfix/main.cf 文件。如果该文件不存在,请改用交互式安装("make install")。
  • 如果在 "make install" 或 "make upgrade" 命令行中指定了 name=value 参数,则这些参数将优先于编译时默认设置或 main.cf 中的设置。

    命令 "make install/upgrade name=value ..." 将用 Postfix 发布版本替换配置参数值末尾的字符串 MAIL_VERSION。请勿在此命令行中尝试指定类似 $mail_version 的内容。这会导致不同版本的 make(1) 命令产生不一致的结果。

6.4 - 配置 Postfix

根据您希望在特定机器上运行 Postfix 的方式,继续到相应部分:

  • 仅发送邮件,不修改现有 Sendmail 安装(第 7 节)。
  • 发送和接收邮件通过虚拟主机接口,仍不修改现有 Sendmail 安装(第 8 节)。
  • 运行 Postfix 代替 Sendmail(第 9 节)。

7 - 配置 Postfix 仅发送邮件

如果您仅使用 Postfix 发送邮件,无需更改现有 Sendmail 配置。相反,请配置您的邮件用户代理,使其直接调用 Postfix 的 sendmail 程序。

按照第 10 节中的"必选配置文件修改"部分的说明操作,并查看第 11 节中的"是否使用 chroot"文本。

您必须注释掉 /etc/postfix/master.cf 中的 "smtp inet" 条目,以避免与真正的 sendmail 发生冲突。在定义 smtpd 服务的行前添加一个 "#" 字符:

/etc/postfix/master.cf:
#smtp inet n - n - - smtpd

启动 Postfix 系统:

# postfix start

或者,如果你怀旧,可以使用 Postfix 的 sendmail 命令:

# sendmail -bd -qwhatever

并查看 maillog 文件中的错误信息。路径可能是 /var/log/maillog、/var/log/mail、/var/log/syslog 或其他路径。通常,路径在 /etc/syslog.conf 文件中定义。

$ grep -E '(reject|warning|error|fatal|panic):' /some/log/file

注意:最重要的错误消息会首先被记录。后续消息可能不太有用。

要检查邮件队列,请使用以下命令之一:

$ mailq
$ sendmail -bp
$ postqueue -p

参见下文第 12 节的"维护与管理"部分。

8 - 配置 Postfix 通过虚拟接口发送和接收邮件

或者,您可以使用 Postfix 系统发送和接收邮件,同时保留 Sendmail 配置,方法是在虚拟接口地址上运行 Postfix。只需配置您的邮件用户代理直接调用 Postfix 的 sendmail 程序。

要创建虚拟网络接口地址,请查阅系统 ifconfig 手册页。命令语法可以是以下任何一种:

# ifconfig le0:1 <;地址>; 网掩码 <;掩码>; up
# ifconfig en0 别名 <;地址>; 网掩码 255.255.255.255

在 /etc/postfix/main.cf 文件中,我会指定

/etc/postfix/main.cfmyhostname = virtual.host.tld
inet_interfaces = $myhostname
mydestination = $myhostname

按照第10节中的"必修配置文件修改"部分的说明操作,并查看第11节中的"是否使用chroot"文本。

启动Postfix系统:

# postfix start

或者,如果你怀旧,可以使用 Postfix 的 sendmail 命令:

# sendmail -bd -qwhatever

并查看 maillog 文件中的任何错误消息。路径名可能是 /var/log/maillog、/var/log/mail、/var/log/syslog 或其他路径。通常,路径名在 /etc/syslog.conf 文件中定义。

$ grep -E '(reject|warning|error|fatal|panic):' /some/log/file

注意:最重要的错误消息会首先被记录。后续消息可能不太有用。

要检查邮件队列,请使用以下命令之一:

$ mailq
$ sendmail -bp
$ postqueue -p

参见下文第 12 节的"维护与管理"部分。

9 - 使用 Postfix 替代 Sendmail

在安装 Postfix 之前,您应按照第 6 节的说明保存任何现有的 sendmail 程序文件。确保在至少运行旧的 sendmail 几天以清除任何未发送的邮件。为此,停止 sendmail 守护进程并重新启动它:

# /usr/sbin/sendmail.OFF -q

注意:这是旧版 sendmail 的语法。新版使用独立进程处理邮件提交和队列运行。

在访问下方"必修配置文件修改"部分后,可使用以下命令启动 Postfix 系统:

# postfix start

或者,如果您怀旧,可以使用 Postfix 的 sendmail 命令:

# sendmail -bd -qwhatever

并查看 maillog 文件中的错误信息。路径名可能是 /var/log/maillog、/var/log/mail、/var/log/syslog 或其他名称。通常,路径名在 /etc/syslog.conf 文件中定义。

$ grep -E '(reject|warning|error|fatal|panic):' /some/log/file

注意:最重要的错误消息会首先被记录。后续消息可能不太有用。

要检查邮件队列,请使用以下命令之一:

$ mailq
$ sendmail -bp
$ postqueue -p

参见下文第 12 节的"维护与管理"部分。

10 - 必须修改的配置文件

注意:本节内容在BASIC_CONFIGURATION_README文档中已有详细说明。以下信息针对有经验的系统管理员。

10.1 - Postfix 配置文件

默认情况下,Postfix 配置文件位于 /etc/postfix 目录下。其中最重要的两个文件是 main.cfmaster.cf;这些文件必须由 root 用户所有。授予其他人对 main.cfmaster.cf(或其父目录)的写权限,相当于授予该用户 root 权限。

在 /etc/postfix/main.cf 中,您需要设置少量配置参数。Postfix 配置参数类似于 shell 变量,但有两个重要区别:第一个区别是 Postfix 不认识 UNIX shell 中的引号。

您以以下方式指定配置参数:

/etc/postfix/main.cf:
parameter = value

并在使用时在其名称前添加一个 "$" 字符:

/etc/postfix/main.cf:
other_parameter = $parameter

可以在参数未赋值前使用 $参数(这是与 UNIX shell 变量的第二个主要区别)。Postfix 配置语言采用懒惰评估,仅在运行时需要时才解析参数值。

每次修改 main.cfmaster.cf 文件后,请执行以下命令以刷新运行中的邮件系统:

# postfix reload

10.2 - 未指定域名的默认域名

首先,您必须指定将附加到未指定域名的地址(即不包含 @domain.tld 的地址)的域。 "myorigin" 参数默认设置为本地主机名,但这可能仅适用于非常小的站点。

一些示例(仅使用其中一个):

/etc/postfix/main.cfmyorigin = $myhostname (以 "user@$myhostname" 身份发送邮件)
myorigin = $mydomain (以 "user@$mydomain" 身份发送邮件)

10.3 - 本地接收的域名

接下来,您需要指定 Postfix 应本地投递的邮件地址。

一些示例(仅使用其中一个):

/etc/postfix/main.cfmydestination = $myhostname, localhost.$mydomain, localhost
mydestination = $myhostname, localhost. $mydomain, localhost, $mydomain
mydestination = $myhostname

第一个示例适用于工作站,第二个示例适用于整个域的邮件服务器。第三个示例应在虚拟主机接口上运行时使用。

10.4 - 代理/NAT 接口地址

proxy_interfaces 参数指定 Postfix 通过代理或网络地址转换单元接收邮件的所有网络地址。您可以使用符号主机名代替网络地址。

重要提示:当您的系统作为其他域的备用 MX 主机时,必须指定代理/NAT 的外部地址,否则在主 MX 主机不可用时会发生邮件投递循环。

示例:位于 NAT 设备后方的运行备份 MX 主机的主机。

/etc/postfix/main.cfproxy_interfaces = 1.2.3.4(代理/NAT外部网络地址)

10.5 - 允许转发邮件的本地客户端

如果您的机器位于开放网络中,则必须指定哪些客户端 IP 地址被授权通过您的机器将邮件转发到互联网。默认设置包括机器所连接的所有子网。这可能会授予过多客户端转发权限。我的设置如下:

/etc/postfix/main.cfmynetworks = 168.100.189.0/28, 127.0.0.0/8

10.6 - 接受来自陌生用户的转发目的地

如果您的机器处于开放网络中,则必须指定 Postfix 是否转发来自陌生人的邮件。默认设置会将邮件转发至 $mydestination 中列出的所有域(及子域)。这可能会为太多目的地授予中继权限。推荐设置(仅使用其中一个):

/etc/postfix/main.cfrelay_domains = (不转发来自陌生人的邮件)
relay_domains = $mydomain (我的域名及其子域名)
relay_domains = $mydomain, other.domain.tld, ...

10.7 - 可选:配置远程投递的智能主机

如果您位于防火墙之后,应设置一个 relayhost。如果可能,请指定组织域名,以便 Postfix 可使用 DNS 解析,并在主 MX 主机不可用时回退到备用 MX 主机。否则,只需指定一个硬编码的主机名。

一些示例(仅使用其中一个):

/etc/postfix/main.cfrelayhost = $mydomain
relayhost = [mail.$mydomain

[]括起来的形式会消除DNS MX查询。

默认情况下,SMTP 客户端即使指定了 中继主机,也会进行 DNS 查询。如果您的机器无法访问 DNS 服务器,请按以下方式关闭 SMTP 客户端的 DNS 查询:

/etc/postfix/main.cfdisable_dns_lookups = yes

STANDARD_CONFIGURATION_README 文件中包含更多关于防火墙和/或拨号网络的提示和技巧。

10.8 - 创建别名数据库

Postfix 使用与 Sendmail 兼容的 aliases(5) 表来重定向发送到 local(8) 收件人的邮件。通常,这些信息保存在两个文件中:文本文件 /etc/aliases 和索引文件 /etc/aliases.db。命令 "postconf alias_maps" 将告诉你文本文件的确切位置。

首先,确保文本文件中包含将 root、postmaster 和 "postfix" 转发给实际用户的别名。Postfix 提供了一个示例别名文件 /etc/postfix/aliases,您可以根据本地情况进行修改。

/etc/aliases:
root: you
postmaster: root
postfix: root
bin: root
等等...

注意:冒号前不应有空格。

最后,使用以下命令之一生成索引别名文件:

# newaliases
# sendmail -bi
# postalias /etc/aliases(路径名因系统而异!)

11 - 是否使用 chroot

Postfix 守护进程可以通过 master.cf 配置为在 chroot 环境中运行。这些进程以固定的低权限运行,仅能访问 Postfix 队列目录(/var/spool/postfix)。这为系统提供了一道重要的入侵屏障。虽然这道屏障并非绝对安全,但每一份防护都至关重要。

除本地投递邮件或执行非 Postfix 命令的 Postfix 守护进程外,所有 Postfix 守护进程均可运行在 chroot 环境中。

对安全性要求较高的站点应考虑将所有与网络通信的守护进程放入 chroot 环境:smtp(8)smtpd(8) 进程,以及可能的 lmtp(8) 客户端。作者自己的 porcupine.org 邮件服务器将所有可进行 chroot 的守护进程都运行在 chroot 环境中。

默认的 /etc/postfix/master.cf 文件指定不以 chroot 方式运行 Postfix 守护进程。要启用 chroot 操作,请编辑文件 /etc/postfix/master.cf。文件中包含相关说明。

请注意,chroot 环境中的守护进程会将所有文件名解析为 Postfix 队列目录(/var/spool/postfix)下的相对路径。为了成功使用 chroot 监狱,大多数 UNIX 系统需要您引入一些文件或设备节点。源代码分发中的 examples/chroot-setup 目录包含一组脚本,可帮助您在不同操作系统上设置 Postfix chroot 环境。

此外,您几乎肯定需要配置 syslogd,使其监听 Postfix 队列目录内的一个套接字。具体系统示例:

FreeBSD:

# mkdir -p /var/spool/postfix/var/run
# syslogd -l /var/spool/postfix/var/run/log

Linux, OpenBSD:

# mkdir -p /var/spool/postfix/dev
# syslogd -a /var/spool/postfix/dev/log

12 - Postfix 系统的维护与管理

Postfix 守护进程在后台运行,并将问题和正常活动记录到 syslog 守护进程中。日志文件的名称在 /etc/syslog.conf 中指定。至少需要以下内容:

/etc/syslog.conf:
mail.err /dev/console
mail.debug /var/log/maillog

重要提示:syslogd 不会自动创建日志文件。您必须在启动或重启 syslogd 之前手动创建这些文件。

重要提示:在 Linux 系统中,路径名前需添加 "-" 符号,例如 -/var/log/maillog,否则 syslogd 会占用比 Postfix 更多的系统资源。

希望问题数量较少,但建议在 syslog 文件轮换前每天晚上运行以下命令:

# postfix check
# grep -E '(reject|warning|error|fatal|panic):' /some/log/file
  • 第一行(postfix check)会让 Postfix 报告文件权限/所有者不一致的问题。
  • 第二行查找邮件软件的问题报告,并报告中继和垃圾邮件访问阻止的有效性。这可能会产生大量输出。您可能需要进行一些后处理以消除不感兴趣的信息。

DEBUG_README 文档解释了 Postfix 日志中"警告"等标签的含义。