我正在运行 Debian GNU/Linux 8.7 系统,使用 Postfix 2.11.3-1 作为 MTA。突然间,即在未更改 MTA 设置的情况下,邮件停止投递,并且开始出现以下错误/var/log/mail.err
:
root@schroeder:~# tail /var/log/mail.err
Mar 21 12:51:01 schroeder postfix/smtp[25421]: fatal: unknown service: smtp/tcp
Mar 21 12:54:11 schroeder postfix/smtp[26397]: fatal: unknown service: smtp/tcp
Mar 21 12:54:12 schroeder postfix/smtp[26398]: fatal: unknown service: smtp/tcp
Mar 21 12:59:26 schroeder postfix/smtp[26553]: fatal: unknown service: smtp/tcp
Mar 21 12:59:26 schroeder postfix/smtp[26554]: fatal: unknown service: smtp/tcp
Mar 21 12:59:26 schroeder postfix/smtp[26555]: fatal: unknown service: smtp/tcp
Mar 21 12:59:26 schroeder postfix/smtp[26556]: fatal: unknown service: smtp/tcp
Mar 21 13:04:30 schroeder postfix/smtp[27797]: fatal: unknown service: smtp/tcp
根据Postfix 文档和二 其他ServerFault 上也有类似的问题,这是因为 postfix 运行在 chrooted 下,但缺少必要的文件,大概是/etc/services
,在它的 spool 目录中,也就是/var/spool/postfix
。
我检查了一下,确实如此,/etc/services
曾是缺失/var/spool/postfix
。所以我复制了(不是符号链接)/etc/services
到/var/spool/postfix/etc
。唉,无济于事。
然后,我尝试禁用 postfix 的 smtp 二进制文件的 chroot jail /etc/postfix/master.cf
,发现当我禁用 unix 服务类型的 chrooting 时,邮件可以正常传递。也就是说,以下/etc/postfix/master.cf
操作可以正常工作:
root@schroeder:~# grep -v ^# /etc/postfix/master.cf
smtp inet n - - - - smtpd
pickup unix n - - 60 1 pickup
cleanup unix n - - - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - - 1000? 1 tlsmgr
rewrite unix - - - - - trivial-rewrite
bounce unix - - - - 0 bounce
defer unix - - - - 0 bounce
trace unix - - - - 0 bounce
verify unix - - - - 1 verify
flush unix n - - 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
# The setting below is the one that I've changed.
# The vendor default is a dash in the fifth column.
smtp unix - - n - - smtp
relay unix - - - - - smtp
showq unix n - - - - showq
error unix - - - - - error
retry unix - - - - - error
discard unix - - - - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - - - - lmtp
anvil unix - - - - 1 anvil
scache unix - - - - 1 scache
maildrop unix - n n - - pipe
flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp unix - n n - - pipe
flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail unix - n n - - pipe
flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp unix - n n - - pipe
flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n n - 2 pipe
flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman unix - n n - - pipe
flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py
${nexthop} ${user}
我认为除了/etc/services
没有出现在 chroot jail 中之外/var/spool/services
,其他问题肯定是我的 chroot 设置出了问题。
因此我重新启用了 chrooting,下载了 Postfix 源代码,检查了 Postfix 源代码发行版附带的 Linux chroot 设置脚本并运行了它:
root@schroeder:~# cd /usr/local/src/
root@schroeder:/usr/local/src# curl https://fourdots.com/mirror/postfix/postfix-release/official/postfix-3.2.0.tar.gz | tar -xz
root@schroeder:/usr/local/src# sh postfix-3.2.0/examples/chroot-setup/LINUX2
postfix/postfix-script: refreshing the Postfix mail system
但是,这仍然没有修复我的设置。
我还尝试在 smtp 配置中添加“-v” /etc/postfix/master.cf
,但错误报告并没有变得更加详细。
到现在为止,我已经束手无策了。我还能检查什么?如何修复我的设置,以便重新启用 postfix 的 smtp 二进制文件的 chrooting?
作为参考,我的设置:
root@schroeder:~# postconf -n
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
inet_interfaces = 127.0.0.1 ::1
mailbox_size_limit = 0
mydestination = schroeder.phl.univie.ac.at, localhost.phl.univie.ac.at, localhost
myhostname = schroeder.phl.univie.ac.at
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_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_tls_cert_file = /etc/ssl/certs/phl.univie.ac.at.pem
smtpd_tls_key_file = /etc/ssl/private/phl.univie.ac.at.key
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtpd_use_tls = yes
后缀是不是(目前) 受到 AppArmor 保护:
root@schroeder:~# apparmor_status
apparmor module is loaded.
apparmor filesystem is not mounted.
我检查了 Postfix 主页和 Debian 的 postfix 包错误跟踪器上这是否是一个已知错误。
我还搜索了 Postfix 主页和邮件列表中链接的资源,但唯一'解决方案'我发现是从源代码构建 Postfix。我也尝试了,但错误仍然存在。
答案1
我偶然发现了同样的问题。就我而言,这是由于我使用 zfs 的设置,其中 /var/spool 挂载时设置了 noexec 标志。解决方案是在挂载的文件系统上清除该标志。
看https://github.com/zfsonlinux/zfs/issues/6803#issuecomment-378271799了解更多信息。
总之,Postfix 显然依赖于动态链接库,并且也被放入了 chroot jail 中/var/spool/postfix用于读取其服务数据库。如果在单独的文件系统上运行此文件夹或其任何父文件夹,并且noexec
该文件系统已设置选项,则不会加载此库,因为其中包含要执行。从 Postfix 的角度来看,这并没有特别考虑。相反,它看到并记录了读取服务数据库的更一般的问题。
答案2
在尝试通过 /etc/postfix/master.cf 文件在 Fedora 28 上安装 postfix 并为 smtp 启用 chroot 后,我也遇到了同样的问题。
在阅读了许多自述文件之后,具体来说
/postfix-3.3.1/README_FILES/基本配置_README
我意识到为了正确运行 postfix chrooted,我需要运行一个脚本。
Note that a chrooted daemon resolves all filenames relative to the Postfix
queue directory (/var/spool/postfix). For successful use of a chroot jail, most
UNIX systems require you to bring in some files or device nodes. The examples/
chroot-setup directory in the source code distribution has a collection of
scripts that help you set up Postfix chroot environments on different operating
systems.
我发现问题的根源是我需要运行
Linux2 系统
脚本文件位于
/postfix-3.3.1/示例/chroot 设置/
像这样:
[[email protected] ~]$ cd postfix-3.3.1/examples/chroot-setup/
[[email protected] chroot-setup]$ ls
AIX42 BSDI2 BSDI3 FreeBSD2 FREEBSD3 HPUX10 HPUX9 IRIX5 IRIX6 LINUX2 NETBSD1 NEXTSTEP3 OPENSTEP4 OSF1 Solaris10 Solaris2 Solaris8
[[email protected] chroot-setup]$ chmod +x LINUX2
[[email protected] chroot-setup]$ ./LINUX2
您必须以 root 或 sudo 身份运行此脚本,因为它会将文件从 etc、lib、lib64 和 usr 复制到 /var/spool/postfix 目录中,并且这些文件必须由 root 拥有。只有在执行脚本后,它才能正常运行,并重新加载 postfix,但我仍然遇到错误,因此我调试了这个非常古老的脚本,发现其中缺少一个斜线条件复制()功能。
正确的条件复制()函数应该看起来像
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
}
因此,如果这是您的错误,并且您正在运行 chroot 监禁的 postfix,请首先找到将正确文件复制到/var/spool/postfix/纠正错误复制条件()运行并以 root 身份执行,或者至少我是这样做的。
一点附录:
对于那些运行 SELinux 的人来说,输入/var/spool/postfix/并运行 restorecon -Rv 如果你担心它可能会弄乱一些东西,你可以直接在你移动的文件上运行它
[[email protected] postfix]# restorecon -Rv etc/ lib/ lib64/ usr/
答案3
我还没有找到错误的真正来源,但令我惊讶(和沮丧)的是,我可以通过以下方式修复它:
apt remove --purge postfix
apt install postfix postfix-doc
更重要的是,据我所知,这确实不是更改任何相关设置。我保留了预清除配置的备份/etc/postfix.backup
,并且/etc/postfix/main.cf
确实不是与以下相关不同/etc/postfix.backup/main.cf
:
root@schroeder:/etc/postfix# diff main.cf ../postfix.backup/main.cf
18c18
< readme_directory = /usr/share/doc/postfix
---
> readme_directory = no
21c21
< smtpd_tls_cert_file=/etc/ssl/certs/phl.univie.ac.at.crt
---
> smtpd_tls_cert_file=/etc/ssl/certs/phl.univie.ac.at.pem
38d37
< mailbox_command = procmail -a "$EXTENSION"
42d40
< html_directory = /usr/share/doc/postfix/html
/etc/postfix/master.cf
唯一不同的是,/etc/postfix.backup/master.cf
chrooting 再次被启用(并且工作正常):
root@schroeder:/etc/postfix# diff master.cf ../postfix.backup/master.cf
53c53
< smtp unix - - - - - smtp
---
> smtp unix - - n - - smtp
中的其他文件/etc/postfix
与中的相应副本没有/etc/postfix/backup
任何区别。
出于好奇,我检查了当我恢复使用旧配置文件时会发生什么:
root@schroeder:/etc/postfix# cp main.cf main.cf.backup
root@schroeder:/etc/postfix# cp ../postfix.backup/main.cf .
root@schroeder:/etc/postfix# postfix reload
postfix/postfix-script: refreshing the Postfix mail system
echo 'A test.' | mail -s Test <censored>
测试邮件到达。因此,配置文件/etc/postfix
显然确实不是首先导致问题。
我还是不知道发生了什么。