Postfix
- 的说法,它力求做到快速、易于管理和安全,同时又能与 sendmail 兼容,不至于引起现有用户的反感。因此,其外部具有 sendmail 的风格,但内部完全不同。
本文以 邮件服务器 为基础。本文的目的是设置 Postfix 并解释基本配置文件。其中包含设置仅本地系统用户传递的说明,以及一个指向虚拟用户传递指南的链接。
安装
配置
有关更多信息,请参阅 Postfix Basic Configuration。默认情况下,配置文件位于 /etc/postfix。最重要的两个文件是:
master.cf,定义了启用的 Postfix 服务以及客户端如何连接它们,请参阅 master(5)main.cf,主配置文件,请参阅 postconf(5)
配置更改需要 重载 postfix.service 服务,或者运行 postfix reload 命令才能生效。
别名 (Aliases)
请参阅 aliases(5)。
您可以在 /etc/postfix/aliases 文件中指定别名(也称为转发器)。
您应该将所有发送给 root 的邮件映射到另一个账户,因为以 root 身份阅读邮件不是一个好主意。
取消注释以下行,并将 you 替换为真实的账户。
root: you
完成编辑 /etc/postfix/aliases 文件后,您必须运行 postalias 命令。
# postalias /etc/postfix/aliases
对于后续的更改,您可以使用:
# newaliases
~/.forward 文件,例如,root 的 /root/.forward。指定应将 root 邮件转发到的用户,例如 user@localhost。/root/.forward
user@localhost
本地邮件
要仅将邮件传递给本地系统用户(存在于 /etc/passwd 中),请将 /etc/postfix/main.cf 更新为以下配置。取消注释、修改或添加以下行:
myhostname = localhost mydomain = localdomain mydestination = $myhostname, localhost.$mydomain, localhost inet_interfaces = $myhostname, localhost mynetworks_style = host default_transport = error: outside mail is not deliverable
所有其他设置可以保持不变。设置完以上配置文件后,您可能希望设置一些 #别名,然后 #启动 Postfix。
虚拟邮件
虚拟邮件是指不映射到用户账户(/etc/passwd)的邮件。
虚拟别名
虚拟别名用于重写所有本地、虚拟和远程目标的收件人地址。这可用于重写单个收件人或整个域的目标地址。
虚拟地址别名
为单个地址设置虚拟别名。
启用虚拟别名表
/etc/postfix/main.cf
virtual_alias_maps = lmdb:/etc/postfix/virtual
填充虚拟别名表
/etc/postfix/virtual
user@domain address
重建索引文件
# postmap /etc/postfix/virtual
重新启动 postfix.service 服务。
检查配置
运行 postfix check 命令。它应该会输出您在配置文件中可能犯的任何错误。
要查看所有配置,请键入 postconf。要查看与默认值有何不同,请尝试 postconf -n。
启动 Postfix
newaliases 才能启动,即使您没有设置任何 #别名。启动/启用 postfix.service 服务。
TLS
有关更多信息,请参阅 Postfix TLS Support。
安全 SMTP(发送)
默认情况下,Postfix/sendmail 不会将电子邮件加密发送给其他 SMTP 服务器。要使用 TLS(如果可用),请将以下行添加到 main.cf:
/etc/postfix/main.cf
smtp_tls_security_level = may
要*强制*使用 TLS(并在远程服务器不支持时失败),请将 may 更改为 encrypt。但请注意,如果 SMTP 服务器是公开引用的,这违反了 RFC:2487。
安全 SMTP(接收)
默认情况下,Postfix 不接受安全邮件。
您需要 获取证书。通过将以下行添加到 main.cf,将 Postfix 指向您的 TLS 证书:
/etc/postfix/main.cf
smtpd_tls_security_level = may smtpd_use_tls = yes smtpd_tls_cert_file = /path/to/cert.pem smtpd_tls_key_file = /path/to/key.pem
有两种方法可以接受安全邮件:STARTTLS over SMTP(端口 587,也称为“submission”端口)和 SMTPS(端口 465,也称为“submissions”端口)。后者之前已被弃用,但已被 RFC:8314 恢复。
要启用 STARTTLS over SMTP(端口 587),请在 master.cf 中取消注释以下行:
/etc/postfix/master.cf
submission inet n - n - - smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_tls_auth_only=yes -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_relay_restrictions= -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING
smtpd_*_restrictions 选项保持注释状态,因为 $mua_*_restrictions 默认未在 main.cf 中定义。如果您决定设置任何 $mua_*_restrictions,请也取消注释那些行。
要启用 SMTPS(端口 465),请在 master.cf 中取消注释以下行:
/etc/postfix/master.cf
submissions inet n - n - - smtpd -o syslog_name=postfix/smtps -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes -o smtpd_reject_unlisted_recipient=no # -o smtpd_client_restrictions=$mua_client_restrictions # -o smtpd_helo_restrictions=$mua_helo_restrictions # -o smtpd_sender_restrictions=$mua_sender_restrictions -o smtpd_relay_restrictions= -o smtpd_relay_restrictions=permit_sasl_authenticated,reject -o milter_macro_daemon_name=ORIGINATING
上面关于 $smtpd_*_restrictions 行的理由与上面相同。
后量子 TLS
从 Postfix 3.10 和 OpenSSL 3.5.0 开始,可以为 TLS 提供后量子密钥交换。为此,需要向 OpenSSL 提供一个配置文件,因为 Postfix 本身不支持新的密钥交换语法。
要启用此功能,请在您的配置中添加以下内容(请参阅 [1]):
/etc/postfix/main.cf
tls_eecdh_auto_curves =
tls_ffdhe_auto_groups =
tls_config_file = ${config_directory}/openssl.cnf
tls_config_name = postfix
然后,您需要添加一个适当的 OpenSSL 配置:
/etc/postfix/openssl.cnf
postfix = postfix_settings [postfix_settings] ssl_conf = postfix_ssl_settings [postfix_ssl_settings] system_default = baseline_postfix_settings [baseline_postfix_settings] Groups = *X25519MLKEM768 / *X25519:X448 / P-256:P-384:P-521:ffdhe2048:ffdhe3072
这会启用新的后量子安全密钥交换 X25519MLKEM768,以及用于传统、非量子安全曲线的先前默认设置。
技巧与提示
阻止传入邮件
使用 Postfix 可以轻松地通过发件人地址手动阻止传入邮件。
创建并打开 /etc/postfix/blacklist_incoming 文件,并附加发件人电子邮件地址。
user@example.com REJECT
然后使用 postmap 命令创建数据库。
# postmap lmdb:blacklist_incoming
在 main.cf 的第一个 permit 规则之前添加以下代码:
smtpd_recipient_restrictions = check_sender_access lmdb:/etc/postfix/blacklist_incoming
最后,重新启动 postfix.service 服务。
隐藏发件人的 IP 和用户代理在 Received 头部
这主要是出于隐私考虑,如果您使用 Thunderbird 发送电子邮件。Received 头部会包含您的局域网和广域网 IP 以及您使用的电子邮件客户端的信息。(原始来源:AskUbuntu)我们的目标是删除传出电子邮件中的 Received 头部。这可以通过以下步骤完成:
将以下行添加到 main.cf:
smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
用以下内容创建 /etc/postfix/smtp_header_checks:
/^Received: .*/ IGNORE /^User-Agent: .*/ IGNORE
最后,重新启动 postfix.service 服务。
Postfix 在 chroot 监狱中
默认情况下,Postfix 不会放在 chroot 监狱中。Postfix 文档 [2] 提供了有关如何实现此类监狱的详细信息。以下概述了步骤,这些步骤基于 Postfix 源代码中提供的 chroot-setup 脚本。
首先,进入 /etc/postfix 目录下的 master.cf 文件,并将所有 chroot 条目更改为 'yes'(y),除了 qmgr、proxymap、proxywrite、local 和 virtual 服务。
其次,创建两个函数,以便稍后帮助我们将文件复制到 chroot 监狱中(参见最后一步)。
$ alias CP="cp -p"
cond_copy() {
# find files as per pattern in $1
# if any, copy to directory $2
dir=$(dirname "$1")
pat=$(basename "$1")
lr=$(find "$dir" -maxdepth 1 -name "$pat")
if test ! -d "$2" ; then exit 1 ; fi
if test "x$lr" != "x" ; then $CP $1 "$2" ; fi
}
接下来,创建监狱的新目录。
$ set -e
$ umask 022
$ POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
$ cd ${POSTFIX_DIR}
$ mkdir -p etc lib usr/lib/zoneinfo
$ test -d /lib64 && mkdir -p lib64
查找 localtime 文件。
$ lt=/etc/localtime $ if test ! -f $lt ; then lt=/usr/lib/zoneinfo/localtime ; fi $ if test ! -f $lt ; then lt=/usr/share/zoneinfo/localtime ; fi $ if test ! -f $lt ; then echo "cannot find localtime" ; exit 1 ; fi $ rm -f etc/localtime
将 localtime 和其他一些系统文件复制到 chroot 的 etc 目录中。
$ CP -f $lt /etc/services /etc/resolv.conf /etc/nsswitch.conf etc $ CP -f /etc/host.conf /etc/hosts /etc/passwd etc $ ln -s -f /etc/localtime usr/lib/zoneinfo
确保 resolv.conf 的所有者是 root。
$ chown root /var/spool/postfix/etc/resolv.conf
使用之前创建的 cond_copy 函数将所需库复制到 chroot 中。
$ cond_copy '/usr/lib/libnss_*.so*' lib $ cond_copy '/usr/lib/libresolv.so*' lib $ cond_copy '/usr/lib/libdb.so*' lib
别忘了 重载 Postfix。
DANE (DNSSEC)
资源记录
DANE 支持多种记录类型,但并非所有类型都适用于 Postfix。
证书使用 0 不受支持,1 被映射到 3,2 是可选的,因此建议发布“3”记录。更多关于 DANE#资源记录 的信息。
配置
机会性 DANE 配置如下:
/etc/postfix/main.cf
smtpd_use_tls = yes smtp_dns_support_level = dnssec smtp_tls_security_level = dane
/etc/postfix/master.cf
dane unix - - n - - smtp -o smtp_dns_support_level=dnssec -o smtp_tls_security_level=dane
要使用每个域的策略,例如,example.org 的机会性 DANE 和 example.com 的强制 DANE,可以使用类似以下内容:
/etc/postfix/main.cf
indexed = ${default_database_type}:${config_directory}/
# Per-destination TLS policy
#
smtp_tls_policy_maps = ${indexed}tls_policy
# default_transport = smtp, but some destinations are special:
#
transport_maps = ${indexed}transport
transport
example.com dane example.org dane
tls_policy
example.com dane-only
smtp_tls_security_level 更改为 dane-only。请注意,这将导致 Postfix 对所有根本不使用 DANE 的传递返回 tempfail(响应 4.X.X 错误代码)!完整的文档可以在 这里找到。
附加功能
- PostfixAdmin — Postfix 的 Web 管理界面。
Postgrey
Postgrey 可用于为 Postfix 邮件服务器启用 灰名单。
安装
安装 postgrey 软件包。要快速运行它,请编辑 Postfix 配置文件并添加以下行:
/etc/postfix/main.cf
smtpd_recipient_restrictions = check_policy_service inet:127.0.0.1:10030
然后 启动/启用 postgrey 服务。之后,重载 postfix 服务。现在应该已经启用了灰名单。
配置
配置通过 扩展单元 postgrey.service 完成。
白名单
要添加自动白名单(成功的邮件会被列入白名单,无需再等待),请添加 --auto-whitelist-clients=N 选项,并将 N 替换为一个合适的较小的数字(或保留其默认值 5)。
/etc/systemd/system/postgrey.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/postgrey --inet=127.0.0.1:10030 \
--pidfile=/run/postgrey/postgrey.pid \
--group=postgrey --user=postgrey \
--daemonize \
--greylist-text="Greylisted for %%s seconds" \
--auto-whitelist-clients
要添加您自己的白名单客户端列表(除了默认列表),请创建 /etc/postfix/postgrey_whitelist_clients.local 文件,每行输入一个主机或域名,然后重新启动 postgrey.service 服务使更改生效。
故障排除
如果您指定了 --unix=/path/to/socket 并且套接字文件未创建,请确保您已从服务文件中删除了默认的 --inet=127.0.0.1:10030。
有关可能选项的完整文档,请参阅 perldoc postgrey。
SpamAssassin
本节介绍如何集成 SpamAssassin。
SpamAssassin 独立通用设置
编辑 /etc/postfix/master.cf,在 smtp 下添加内容过滤器。
smtp inet n - n - - smtpd -o content_filter=spamassassin
另外,为 SpamAssassin 添加以下服务条目:
spamassassin unix - n n - - pipe
flags=R user=spamd argv=/usr/bin/vendor_perl/spamc -e /usr/bin/sendmail -oi -f ${sender} ${recipient}
现在您可以 启动 并 启用 spamassassin.service 服务。
SpamAssassin 结合 Dovecot LDA / Sieve(邮件过滤)
按照 Dovecot#Sieve 中的说明设置 LDA 和 Sieve 插件。但是,请忽略最后一行 mailbox_command...。
取而代之的是,在 /etc/postfix/master.cf 中添加一个管道:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/bin/vendor_perl/spamc -u spamd -e /usr/lib/dovecot/dovecot-lda -f ${sender} -d ${recipient}
并在 /etc/postfix/main.cf 中激活它:
virtual_transport = dovecot
或者,如果您不想使用虚拟传输,您可以使用 mailbox_command。后者以本地用户和组身份运行,而管道则使用 user 设置以指定的特权用户身份运行。
mailbox_command = /usr/bin/vendor_perl/spamc -u spamd -e /usr/lib/dovecot/dovecot-lda -f "$SENDER" -a "$RECIPIENT"
SpamAssassin 结合 Dovecot LMTP / Sieve
按照 Dovecot#Sieve 中的说明设置 LMTP 和 Sieve。
编辑 /etc/dovecot/conf.d/90-plugin.conf 并添加:
sieve_before = /etc/dovecot/sieve.before.d/ sieve_extensions = +vnd.dovecot.filter sieve_plugins = sieve_extprograms sieve_filter_bin_dir = /etc/dovecot/sieve-filter sieve_filter_exec_timeout = 120s #this is often needed for the long running spamassassin scans, default is otherwise 10s
创建目录并将 spamassassin 作为 dovecot 可以运行的二进制文件放入其中。
# mkdir /etc/dovecot/sieve-filter # ln -s /usr/bin/vendor_perl/spamc /etc/dovecot/sieve-filter/spamc
创建一个新文件 /etc/dovecot/sieve.before.d/spamassassin.sieve,其中包含:
require [ "vnd.dovecot.filter" ]; filter "spamc" [ "-d", "127.0.0.1", "--no-safe-fallback" ];
编译 sieve 规则 spamassassin.svbin。
# cd /etc/dovecot/sieve.before.d # sievec spamassassin.sieve
最后,重新启动 dovecot.service 服务。
基于规则的邮件处理
使用策略服务,您可以轻松地精细调整 Postfix 的邮件传递行为。 postfwd 提供了执行此操作的服务。这允许您例如实现时间感知的发件人和收件人灰名单/黑名单,以及 SPF 策略检查。
策略服务是独立的服务,并像这样连接到 Postfix:
/etc/postfix/main.cf
smtpd_recipient_restrictions = ... check_policy_service unix:/run/policyd.sock check_policy_service inet:127.0.0.1:10040
将策略服务放在队列的末尾可以减少负载,因为只处理合法的邮件。请确保将其放在第一个 permit 语句之前,以捕获所有传入的消息。
发件人策略框架
要将 发件人策略框架 与 Postfix 一起使用,您可以 安装 python-spf-engineAUR、python-postfix-policyd-spfAUR 或 postfix-policyd-spf-perlAUR。
使用 spf-engine 或 python-postfix-policyd-spf
根据您的需要编辑 /etc/python-policyd-spf/policyd-spf.conf。一个详细注释的版本可以在 /etc/python-policyd-spf/policyd-spf.conf.commented 中找到。请额外注意 HELO 检查策略,因为标准设置会严格拒绝 HELO 失败。
在 main.cf 文件中,为 policyd 添加超时设置:
/etc/postfix/main.cf
policy-spf_time_limit = 3600s
然后添加一个传输:
/etc/postfix/master.cf
policy-spf unix - n n - 0 spawn user=nobody argv=/usr/bin/policyd-spf
最后,您需要将 policyd 添加到 smtpd_recipient_restrictions。为了最小化负载,请将其放在限制列表的末尾,但在任何 reject_rbl_client DNSBL 行之前。
/etc/postfix/main.cf
smtpd_recipient_restrictions=
...
permit_sasl_authenticated
permit_mynetworks
reject_unauth_destination
check_policy_service unix:private/policy-spf
现在重载 postfix 服务。
您可以使用以下方法测试您的设置:
/etc/python-policyd-spf/policyd-spf.conf
defaultSeedOnly = 0
使用 postfix-policyd-spf-perl
使用 postfix 执行与 使用 python-postfix-policyd-spf 相同お的流程,但有以下区别:
main.cf 文件中 policyd 的超时设置:
/etc/postfix/main.cf
policy_time_limit = 3600
传输:
/etc/postfix/master.cf
policy unix - n n - 0 spawn
user=nobody argv=/usr/lib/postfix/postfix-policyd-spf-perl
将 policyd 添加到 smtpd_recipient_restrictions:
check_policy_service 指定在 reject_unauth_destination 之后,否则您的系统可能成为开放中继。/etc/postfix/main.cf
smtpd_recipient_restrictions=
...
reject_unauth_destination
check_policy_service unix:private/policy
...
发件人重写方案
要将 发件人重写方案 与 Postfix 一起使用,请 安装 postsrsdAUR 并调整设置:
/etc/postsrsd/postsrsd.conf
domains = { "yourdomain.tld", "yournextdomain.tld", "yournextdomain.tld" }
unprivileged-user = "postsrsd"
启用并启动守护进程,确保它在重启后也能运行。然后通过调整以下行来相应地配置 Postfix:
/etc/postfix/main.cf
sender_canonical_maps = socketmap:unix:srs:forward sender_canonical_classes = envelope_sender recipient_canonical_maps = socketmap:unix:srs:reverse recipient_canonical_classes = envelope_recipient, header_recipient
重新启动 Postfix 并开始转发邮件。
故障排除
警告:“database /etc/postfix/*.db is older than source file ..”
如果您在 journalctl 中看到一个或两个警告:
warning: database /etc/postfix/virtual.db is older than source file /etc/postfix/virtual warning: database /etc/postfix/transport.db is older than source file /etc/postfix/transport
然后,您可以根据收到的消息,使用以下命令修复它:
postmap /etc/postfix/transport postmap /etc/postfix/virtual
然后 重新启动 postfix.service 服务。
Host or domain name not found. Name service error for name=...
如果您在 journalctl 中收到以下警告:
Host or domain name not found. Name service error for name=...
这可能是因为您在 chroot 中运行 Postfix,并且缺少 /etc/resolv.conf。如果是这样,您可以按照以下方法修复:
mkdir -p /var/spool/postfix/etc cp /etc/resolv.conf /var/spool/postfix/etc/resolv.conf
然后 重新启动 postfix.service 服务。
error: require command: unknown Sieve capability `vnd.dovecot.filter'
spamassassin: line 1: error: require command: unknown Sieve capability `vnd.dovecot.filter'. spamassassin: line 2: error: unknown command 'filter' (only reported once at first occurrence). spamassassin: error: validation failed. sievec(root): Fatal: failed to compile sieve script 'spamassassin.sieve'
如果您在按照 #SpamAssassin 结合 Dovecot LMTP / Sieve 操作后运行 sievec 时收到此错误,请将 /etc/dovecot/sieve.before.d/spamassassin.sieve 中的 sieve_extensions 替换为 sieve_global_extensions。
重新启动 dovecot.service 服务。