5

I am running a Debian GNU/Linux 8.7 box with Postfix 2.11.3-1 as MTA. All of a sudden, that is, with no change to the MTA setup, mails stopped being delivered, and the following error started showing up in /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

According to the Postfix documentation and two other similar questions on ServerFault, this is because postfix runs chrooted, but lacks the necessary files, presumably, /etc/services, in its spool directory, namely, /var/spool/postfix.

I checked and, indeed, /etc/services was missing from /var/spool/postfix. So I copied (not symlinked) /etc/services to /var/spool/postfix/etc. Alas, to no avail.

I then played around with disabling the chroot jail for postfix' smtp binary in /etc/postfix/master.cf and found that, when I disable chrooting for the unix service type, mail gets delivered normally. That is, the following /etc/postfix/master.cf works fine:

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}

I figured that something else, that is, other than /etc/services not being present in the chroot jail at /var/spool/services, must be wrong with my chroot setup.

So I re-enabled chrooting, downloaded the Postfix source, checked the chroot setup script for Linux that ships with the Postfix source distribution and ran it:

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

Again, however, this did not fix my setup.

I also tried adding "-v" to the smtp configuration at /etc/postfix/master.cf, but the error reports didn't get more verbose.

At this point, I'm at my wits end. What else can I check? How can I fix my setup so that I can re-enable chrooting for postfix' smtp binary?

For reference, my setup:

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

Postfix is not (yet) protected by AppArmor:

root@schroeder:~# apparmor_status
apparmor module is loaded.
apparmor filesystem is not mounted.

I checked whether this is a known bug on Postfix' homepage and Debian's bug tracker for the postfix package.

I also searched though the resources linked on the Postfix homepage and the mailing lists, but the only 'solution' I've found is to build Postfix from source. I gave that a try, too, but the error persisted.

3 Answers 3

2

I stumbled over the same issue. In my case this was due to my setup using zfs with /var/spool mounted with flag noexec set. Solution was to clear that flag on mounted file system.

See https://github.com/zfsonlinux/zfs/issues/6803#issuecomment-378271799 for more.

In conclusion Postfix apparently relies on a dynamically linked library also put in chroot jail in /var/spool/postfix for reading its services database. In case of running this folder or any of its parent folders on a separate filesystem which is mounted with option noexec set this library won't get loaded for containing code to be executed. From Postfix' point of view this isn't considered in particular. Instead it sees and logs a more generic issue with reading the services database.

2
  • 1
    Please extend the answer to include the steps to solve the issue, although linking the source is generally useful, it's a good practice and a requirement in the stack network to make full answers as to avoid links going dead and losing the answer. Jul 21, 2018 at 3:39
  • Well it pretty depends on the actual issue. If you happen to know how to handle file systems e.g. in Linux you might have stumbled over mount options such as noexec, nosuid etc. I'd rather consider using man pages to learn more about it instead of providing one of several possible ways to fix them. In my case this was zfs related, but there are good reasons this might happen with other filesystems as well working with a different set of tools. At most it might be okay to draft the backgrounds provided in linked source ... Jul 21, 2018 at 22:35
1

This same problem I developed after trying to install postfix on Fedora 28 with chroot enabled for smtp through the /etc/postfix/master.cf file.

after reading one of the many readme files, specifically

/postfix-3.3.1/README_FILES/BASIC_CONFIGURATION_README

I was able to realize there was a script i needed to run in order to properly run 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.

the problem that i figured out was the culprit was that I needed to run the

LINUX2

script file located in

/postfix-3.3.1/examples/chroot-setup/

like so:

[[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

you must run this script as root or sudo as it copies files into the /var/spool/postfix directory from etc, lib, lib64, and usr, and they must be owned by root. It was only after executing the script, it ran fine, and reloaded postfix, but i still had errors, so i debugged the very ancient script and found there to be a missing slash in the cond_copy() function.

the correct cond_copy() function should look like

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
}

so if this is your error and you are running a chroot jailed postfix, first find the script that copies the correct files into /var/spool/postfix/ correct the error in the copy_cond() function and execute as root, or at least thats how i did it.

a little addendum:

for those that are running SELinux, it probably wouldnt be such a bad idea to enter /var/spool/postfix/ and run restorecon -Rv if you are concerned it might mess something up you can just run it on the files you moved over

[[email protected] postfix]# restorecon -Rv etc/ lib/ lib64/ usr/
0

I haven’t found the actual source of the error, but—to my surprise (and dismay)—I could fix it by:

apt remove --purge postfix
apt install postfix postfix-doc

What is more, as far as I can tell, this did not change any relevant setting. I kept a backup of the pre-purge configuration at /etc/postfix.backup, and /etc/postfix/main.cf does not differ relevantly from /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

And /etc/postfix/master.cf differs from /etc/postfix.backup/master.cf only insofar that chrooting is enabled again (and works):

root@schroeder:/etc/postfix# diff master.cf ../postfix.backup/master.cf
53c53
< smtp      unix  -       -       -       -       -       smtp
---
> smtp      unix  -       -       n       -       -       smtp

No other file in /etc/postfix differs from the corresponding copy in /etc/postfix/backup at all.

I, out of curiosity, checked what happens when I revert to using the old configuration file:

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>

The test mail arrives. So, the configuration files in /etc/postfix, apparently, did not cause the problem in the first place.

I still have no idea what did.

1
  • Removing and reinstalling postfix rebuilt the chroot, fixing whatever problem it had. As well as a problem with etc/services, this can be caused by the chroot not containing certain libnss shared libraries. If those libraries got copied into the chroot, but then libc was upgraded, postfix can be running using the new libc, which looks for newer versions than are in the chroot. The Debian package has a script that updates the chroot, but it could break or fail to run. In my case, it was confused about whether the chroot was needed due to a problem parsing my master.cf.
    – Joey
    Sep 26, 2021 at 22:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .