Linux HOWTOs

About | Home | Search


HOWTO: sendmail
Description: MTA (Mail Transport Agent)
Click here for ChangeLog
NOTE: I use GNU tar >= 1.13.25 so it's -j for .tar.bz2 files,
it's safe to assume that make, gcc, binutils, fileutils/coreutils, gawk, sed, and grep are prerequisites for almost everything


# sendmail 8.15.2
# ===============
# Versions included in Slackware packages:
# Slackware 13.37: sendmail, sendmail-cf 8.14.4
# Slackware 14.0: sendmail, sendmail-cf 8.14.5
# Slackware 14.1: sendmail, sendmail-cf 8.14.7
# Slackware 14.2: sendmail, sendmail-cf 8.15.2

# There is a 8.16.0.29 snapshot that builds with OpenSSL >= 1.1.0 without
# a patch, in here:
# ftp://ftp.sendmail.org/pub/sendmail/snapshots/
# Keep an eye on comp.mail.sendmail for announcements for updates:
# https://groups.google.com/forum/#!forum/comp.mail.sendmail

# In between the release of 8.14.7 and 8.14.8, Sendmail, Inc. was
# acquired by Proofpoint:
# http://www.sendmail.com/sm/open_source/community_letter/
# http://www.proofpoint.com/about-us/press-releases/10012013.php

# Prerequisites:
# m4
# OpenSSL (optional; for STARTTLS)
# Cyrus SASL (optional; for SMTP AUTH)
# OpenLDAP (optional; for LDAPMAP)
# Berkeley DB

# If you don't have user and group 'smmsp', add them:
su
getent group | grep "^smmsp:" > /dev/null || groupadd -g 25 smmsp
id smmsp > /dev/null 2>&1 || useradd -g 25 -u 25 smmsp
exit

# Get it
cd
test -f installed/sendmail.8.15.2.tar.gz &&
 mv installed/sendmail.8.15.2.tar.gz .
test ! -f sendmail.8.15.2.tar.gz &&
 wget ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.15.2.tar.gz

# Verify tarball w/ sha256sum:
# (this works too: openssl sha256 sendmail.8.15.2.tar.gz)
echo "24f94b5fd76705f15897a78932a5f2439a32b1a2fdc35769bb1a5f5d9b4db43\
9  sendmail.8.15.2.tar.gz" | sha256sum -c

# Verify PGP sig w/ sha256sum:
# (this works too: openssl sha256 sendmail.8.15.2.tar.gz.sig)
wget -nc ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.15.2.tar.gz.sig &&
 echo "48020a25ca9c2538b2c76d73abe1acf24eab5905e0929b2fc3e7c7d771d93ec\
e  sendmail.8.15.2.tar.gz.sig" | sha256sum -c

# Verify tarball w/ gpg:
wget -O - ftp://ftp.sendmail.org/pub/sendmail/PGPKEYS | gpg --import
( gpg --list-keys E2763A73 > /dev/null 2>&1 || gpg --recv-keys E2763A73 ) &&
 wget -nc ftp://ftp.sendmail.org/pub/sendmail/sendmail.8.15.2.tar.gz.sig &&
  gpg --verify sendmail.8.15.2.tar.gz.sig && rm sendmail.8.15.2.tar.gz.sig

# Create ~/src, it's used below
test ! -d ~/src && mkdir -p -m 0700 ~/src

# Back-up your existing sendmail configuration files.
#
# If your configuration files come from the 'sendmail-cf' Slackware package,
# they will be under /usr/share/sendmail
#
# If you have a source-installed sendmail in ~/src (where this howto puts
# it) with your sendmail.mc and submit.mc files in cf/cf/, you can run this
# blurb below to back them up for you.  It assumes that you only have one
# version of sendmail's source in ~/src/.
#
# NOTE: be careful - if you keep your sendmail.mc and submit.mc in the
# last version's cf/cf/ dir and something goes wrong with this blurb,
# the next blurb will wipe them out along with the source tree.
# Make sure your old config files really do make it into
# ~/backup/sendmail/$OLDVER before you move past this part.
cd ~/src
OLDVER=`find -maxdepth 1 -type d -name "sendmail-*" 2> /dev/null | tail -1`
test -n "$OLDVER" && (
 OLDVER=`basename $OLDVER` &&
 mkdir -p -m 0700 ~/backup/sendmail/${OLDVER} &&
 test -f ${OLDVER}/devtools/Site/site.config.m4 &&
  cp -f ${OLDVER}/devtools/Site/site.config.m4 ~/backup/sendmail/${OLDVER}/
 test -f ${OLDVER}/cf/cf/sendmail.mc &&
  cp -f ${OLDVER}/cf/cf/sendmail.mc ~/backup/sendmail/${OLDVER}/
 test -f ${OLDVER}/cf/cf/submit.mc &&
  cp -f ${OLDVER}/cf/cf/submit.mc ~/backup/sendmail/${OLDVER}/
 find ~/backup/sendmail/$OLDVER -type f -exec chmod 600 {} \;
)
unset OLDVER

# If you're replacing a Slackware installed sendmail, make sure everything
# is backed up that needs to be, then run "removepkg sendmail sendmail-cf"
# (as root) to remove it.  After removing the packages, you may still
# have a /usr/share/sendmail/cf/cf directory with your old .mc and .cf
# file in it.

# If you're upgrading, the old version's source directory may have files
# in it that are owned by root - like sendmail.cf and submit.cf  This will
# make everything owned by your non-root user.  Skip this if you're doing
# everything as root (directly, not using su/sudo).
find ~/src -maxdepth 1 -type d -name "sendmail-*" \
 -exec su -c "chown -R $(logname) {}" \;

# This will make all files in the source of an old version writable
# (u+w), otherwise you'll get something like this if you're not root:
# rm: remove write-protected regular file
# `./sendmail-8.15.2/cf/cf/generic-osf1.cf'?
find ~/src -maxdepth 1 -type d -name "sendmail-*" \
 -exec chmod -R u+w {} \;

# Extract the source
cd ~/src
find -maxdepth 1 -type d -name "sendmail-*" -exec rm -r {} \;
tar xzvf ~/sendmail.8.15.2.tar.gz
cd sendmail-8.15.2
test $UID = 0 && chown -R root:root .

## Apply the SMTP session reuse bugfix patch described here:
# https://marc.info/?l=sendmail-announce&m=145685360404049&w=2
## Get it
wget -nc ftp://ftp.sendmail.org/pub/sendmail/8.15.2.mci.p0
## Verify it
( gpg --list-keys E2763A73 > /dev/null 2>&1 || gpg --recv-keys E2763A73 ) &&
 wget -nc ftp://ftp.sendmail.org/pub/sendmail/8.15.2.mci.p0.sig &&
  gpg --verify 8.15.2.mci.p0.sig && rm 8.15.2.mci.p0.sig
## Apply it
patch -p0 < 8.15.2.mci.p0

# Apply this patch if you have OpenSSL >= 1.1.0 installed
# It is the same as this one
# with the Debian parts removed
wget -nc https://englanders.us/pub/linux/patches/notmine/\
sendmail-8.15.2-openssl-1.1.0.patch &&
 patch -p1 < sendmail-8.15.2-openssl-1.1.0.patch

# Before you configure the build and build it, make sure that
# /usr/lib/libdb.so (or /usr/lib64/libdb.so) and /usr/include/db.h are
# from the same version of Berkeley DB.  ie. if you see that libdb.so is
# a symlink pointing to libdb-4.so and db.h is a symlink to
# /usr/include/db3/db.h, then you'll need to fix it.
#
# sendmail will only build with NEWDB (see notes about it in devtools/README
# and sendmail/README) if it can find libdb.so and db.h  If you have yours
# installed as libdb-4.so (or something similar) and your include file is
# /usr/include/db4/db.h, create symlinks.

# Skip this section if you want to build a "normal" sendmail
#
# If you already have a site.config.m4 backed up for this version of
# sendmail, restore it and skip to the next section.  If you don't
# have one for this version, it will get one for the previous
# version.
test -f ~/backup/sendmail/sendmail-8.15.2/site.config.m4 &&
 cp ~/backup/sendmail/sendmail-8.15.2/site.config.m4 devtools/Site/
test ! -f devtools/Site/site.config.m4 &&
 test -f ~/backup/sendmail/sendmail-8.15.1/site.config.m4 &&
  cp ~/backup/sendmail/sendmail-8.15.1/site.config.m4 devtools/Site/
#
# See devtools/README and devtools/Site/site.config.m4.sample for
# more information about the _many_ available options
cd devtools/Site
#
# Add build settings to site.config.m4 to build sendmail with that
# particular feature.  If this is not your first run through with this
# version of sendmail, make sure you wipe the existing site.config.m4
#
# Install library files in /usr/lib64 instead of /usr/lib if this is
# a 64-bit system
test $(uname -m) = "x86_64" &&
 ( echo "APPENDDEF(\`confLIBDIR', \`/usr/lib64')" >> site.config.m4
   echo "APPENDDEF(\`confLIBDIRS', \`-L/usr/lib64')" >> site.config.m4 )
#
# Install man pages under /usr/man instead of /usr/share/man (which is
# usually a symlink anyway, in Slackware).
test -d /usr/man &&
 ( echo "APPENDDEF(\`confMANROOT', \`/usr/man/cat')" >> site.config.m4
   echo "APPENDDEF(\`confMANROOTMAN', \`/usr/man/man')" >> site.config.m4 )
#
# Install unformatted man pages.  Set this if your installed sendmail
# man pages have control codes showing in them like "[1msendmail"
# (If they were installed into /usr/man/catX, they would be OK, so you may
# want to look at confMANROOTMAN too)
#echo "APPENDDEF(\`confINSTALL_RAWMAN')" >> site.config.m4
#echo "APPENDDEF(\`confDONT_INSTALL_CATMAN')" >> site.config.m4
#
# MILTER (MIMEDefang, Amavis, etc.)
echo "APPENDDEF(\`conf_sendmail_ENVDEF', \`-DMILTER')" >> site.config.m4
echo "APPENDDEF(\`confLIBS', \`-lpthread')" >> site.config.m4
#
# SASL2 (SMTP authentication)
echo "APPENDDEF(\`conf_sendmail_ENVDEF', \`-DSASL=2')" >> site.config.m4
echo "APPENDDEF(\`conf_sendmail_LIBS', \`-lsasl2')" >> site.config.m4
#
# STARTTLS (SMTP + TLS/SSL)
echo "APPENDDEF(\`conf_sendmail_ENVDEF', \`-DSTARTTLS')" >> site.config.m4
echo "APPENDDEF(\`conf_sendmail_LIBS', \`-lssl -lcrypto')" >> site.config.m4
#
# If doing STARTTLS with 32-bit source-installed OpenSSL < 1.1.0
test $(uname -m) != 'x86_64' &&
 test -d /usr/local/ssl/include &&
  ( echo "APPENDDEF(\`confINCDIRS', \`-I/usr/local/ssl/include')" >> \
     site.config.m4
    echo "APPENDDEF(\`confLIBDIRS', \`-L/usr/local/ssl/lib')" >> \
     site.config.m4 )
#
# If doing STARTTLS with 64-bit source-installed OpenSSL < 1.1.0
test $(uname -m) = 'x86_64' &&
 test -d /usr/local/ssl/include &&
  ( echo "APPENDDEF(\`confINCDIRS', \`-I/usr/local/ssl/include')" >> \
     site.config.m4
    echo "APPENDDEF(\`confLIBDIRS', \`-L/usr/local/ssl/lib64')" >> \
     site.config.m4 )
#
# LDAPMAP (ldap mail routing - ie. aliases, virtusertable, etc. in LDAP)
echo "APPENDDEF(\`confMAPDEF', \`-DLDAPMAP')" >> site.config.m4
echo "APPENDDEF(\`confLIBS', \`-lldap -llber')" >> site.config.m4
#
# Source-installed Berkeley DB 4.2.x
test -d /usr/local/BerkeleyDB.4.2 &&
 ( echo "APPENDDEF(\`confINCDIRS', \`-I/usr/local/BerkeleyDB.4.2/include')" \
    >> site.config.m4
   echo "APPENDDEF(\`confLIBDIRS', \`-L/usr/local/BerkeleyDB.4.2/lib')" \
    >> site.config.m4 )
#
# SOCKETMAP
echo "APPENDDEF(\`confMAPDEF', \`-DSOCKETMAP')" >> site.config.m4
#
cd ../..

## I haven't tried this lately
# If you want to patch sendmail to work with libspf (install it first), run
# this (if you have the libspf source, the same patch should be in
# ~/src/libspf-1.0.0-RC5/patches/Sendmail/8.13.x/ on your system):
#wget -nc http://englanders.us/pub/linux/patches/notmine/\
#sendmail-8.13.1-libspf-1.0-RC5.diff &&
# patch -p1 < sendmail-8.13.1-libspf-1.0-RC5.diff

# Build sendmail
./Build

## If sendmail failed to build with errors like this:
# /usr/lib/gcc-lib/i486-slackware-linux/3.3.6/../../../libdb.so: undefined
# reference to `pthread_condattr_setpshared'
## tell it to build it with libpthread by doing this and then tell it to
## re-build (-c):
echo "APPENDDEF(\`confLIBS', \`-lpthread')" >> devtools/Site/site.config.m4
./Build -c

# /usr/lib64/gcc/x86_64-slackware-linux/4.7.1/../../../../
#  x86_64-slackware-linux/bin/ld: domain.o: undefined reference to symbol
#  '__res_querydomain@@GLIBC_2.2.5'
# /usr/lib64/gcc/x86_64-slackware-linux/4.7.1/../../../../
#  x86_64-slackware-linux/bin/ld: note: '__res_querydomain@@GLIBC_2.2.5'
#  is defined in DSO /lib64/libresolv.so.2 so try adding it to the linker
#  command line
# /lib64/libresolv.so.2: could not read symbols: Invalid operation
# collect2: error: ld returned 1 exit status
echo "APPENDDEF(\`confLIBS', \`-lresolv')" >> devtools/Site/site.config.m4
./Build -c

# Now become root, which is necessary for installing everything
su

# Don't use this on HP-UX or Solaris! - see the README in mail.local/
# (that is why 'force-install' is run).  If you use Cyrus, make that your
# local mailer (don't use mail.local).  If building mail.local (to use
# instead of procmail):
( cd mail.local ; ./Build ; ./Build force-install )

# If building milter (this won't do anything if it's not configured to build):
grep '\-DMILTER' devtools/Site/site.config.m4 > /dev/null 2>&1 &&
 ( cd libmilter ; ./Build ; ./Build install )

# Install it
./Build install

# Make sure your non-root user can remove the source later
chown -R $(logname) .
chmod -R u+w .

# If you don't have an aliases file, install a sample.  Make sure you run
# 'newaliases' once you have a working sendmail configuration to create
# /etc/mail/aliases.db (which is what sendmail actually uses).
test ! -f /etc/mail/aliases && cp sendmail/aliases /etc/mail/

# If you don't have a local-host-names file, install a blank one:
test ! -e /etc/mail/local-host-names &&
 echo -e "# names of hosts for which we receive email\n" \
  > /etc/mail/local-host-names

# Create directories, update permissions
mkdir -p /var/spool/clientmqueue /var/spool/mqueue
chmod go-w / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue
chown root / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue
find /etc/mail -type f -name "*.db" -exec chown root:root {} \;
test -f /etc/mail/aliases.db && chown root:smmsp /etc/mail/aliases.db
find /etc/mail -type f -name "*.db" -exec chmod 640 {} \;
test ! -f /etc/mail/statistics && touch /etc/mail/statistics
chmod 640 /etc/mail/aliases /etc/mail/statistics
touch /etc/mail/sendmail.cf /etc/mail/submit.cf
chown root:wheel /etc/mail/sendmail.cf /etc/mail/submit.cf
chmod 444 /etc/mail/sendmail.cf /etc/mail/submit.cf
test -f /var/run/sendmail.pid && chmod 600 /var/run/sendmail.pid
chown smmsp:smmsp /var/spool/clientmqueue
chmod 770 /var/spool/clientmqueue
chown -R root:wheel /var/spool/mqueue
chmod -R 700 /var/spool/mqueue
ln -sf /usr/sbin/sendmail /usr/lib/sendmail

# If you patched sendmail for libspf, add a "FEATURE(spf)dnl" line to your
# sendmail.mc, re-create a sendmail.cf, and restart sendmail.  See the libspf
# docs for more info.

# If you need a /etc/rc.d/rc.sendmail startup script, I have the script
# from Slackware here (the same script is in at least 9.0 through 10.2):
# http://englanders.us/pub/linux/misc/notmine/rc.sendmail
#
# And if you want another one that'll handle starting/stopping/restarting
# sendmail, MIMEDefang, clamd, sophie, trophie, etc., grab this one:
cd /etc/rc.d
test -f rc.sendmail &&
 ( mv -f rc.sendmail rc.sendmail.old ; chmod 600 rc.sendmail.old )
wget http://englanders.us/pub/linux/misc/rc.sendmail
chmod 700 rc.sendmail

# If you want a Makefile so you can just run 'make' to update access.db,
# aliases.db, domaintable.db, mailertable.db, and virtusertable.db (whichever
# one(s) have updated text file counterparts):
cd /etc/mail
test -f Makefile &&
 ( mv -f Makefile Makefile.old ; chmod 600 Makefile.old )
wget http://englanders.us/pub/linux/misc/notmine/Makefile-etc-mail \
 -O Makefile

# Become yourself again:
exit

# Restore backed up config files for this version if you already have them,
# from the previous version if not.  This just tries 8.15.9, 8.15.8, ...,
# 8.14.9, 8.14.8, ... until one exists.
cd cf/cf
for mcfile in sendmail.mc submit.mc; do
  test -f $mcfile && mv -f $mcfile ${mcfile}.old
  for maj in 8.15 8.14; do
    for min in $(seq -s ' ' 9 -1 0); do
      test -f ./${mcfile} && break
      test -f ~/backup/sendmail/sendmail-${maj}.${min}/${mcfile} &&
       cp -f ~/backup/sendmail/sendmail-${maj}.${min}/${mcfile} .
    done
  done
done

# After (re-)setting your sendmail.mc and submit.mc in
# ~/src/sendmail-8.15.2/cf/cf/, run this to generate the .cf files and
# install them into /etc/mail:
su -c "make install-cf"

# Save the source for later
cd
mkdir -p -m 0700 installed
rm -f installed/sendmail.*.tar.*
mv sendmail.8.15.2.tar.gz installed/


# SSL Certs
# =========
# To create SSL certs for sendmail, first follow the instructions at the
# bottom of the OpenSSL howto, then come back here
#
# Now that you've created the certs, become root and put them in place:
cd
su
mkdir -p -m 0700 /etc/mail/certs
cp demoCA/cacert.pem /etc/mail/certs/CAcert.pem
cp newcert.pem /etc/mail/certs/cert.pem
cp newkey.pem /etc/mail/certs/key.pem
chmod 600 /etc/mail/certs/*
exit


# MSP Usage (all should be run as root)
# =========
# Run this from cron every so often (every 15 minutes?) to flush
# the client queue.  Do this if you don't want/need to have a sendmail
# daemon running like the next example.
/usr/sbin/sendmail -Ac -q

# Run as an msp daemon with submit.cf  The -L part will make it log
# 'sm-msp-queue' as the program name in syslog instead of 'sendmail'.
# -Ac means use submit.cf instead of sendmail.cf  The -q part tells it
# to flush the queue every 30 minutes.  This one will fork a process
# to run the queue.
/usr/sbin/sendmail -L sm-msp-queue -Ac -q30m

# Start a persistant queue runner (see -qp in the sendmail man page) using
# submit.cf, 'sm-msp-queue' program name for syslog, sleep time of 1 minute.
# This one will have one persistant queue runner process that sleeps for
# a minute in between runs.
/usr/sbin/sendmail -L sm-msp-queue -Ac -qp1m

# View the msp mail queue:
/usr/sbin/sendmail -bp -Ac


# MTA Usage (all should be run as root)
# =========
# Run from cron to flush the MTA queue:
/usr/sbin/sendmail -q

# Run as an MTA daemon with sendmail.cf  Use 'sm-mta' as the program
# name in syslog, flush the queue every 15 minutes.
/usr/sbin/sendmail -L sm-mta -bd -q15m

# View the MTA mail queue(s):
# (they all do the same thing)
/usr/sbin/sendmail -bp -Am
/usr/sbin/sendmail -bp
/usr/bin/mailq


# If you ever want to uninstall Sendmail, here's how:
cd
su
test -x /etc/rc.d/rc.sendmail && /etc/rc.d/rc.sendmail stop
sleep 5
killall -9 sendmail
# There may be other things using /etc/mail, so you may want to pick and
# choose in there rather than just blow away the whole directory
#test -d /etc/mail && rm -r /etc/mail
( cd /usr/bin
  rm -f hoststat mailq newaliases praliases purgestat rmail sendmail\
   vacation )
find /usr/doc -maxdepth 1 -name "sendmail-*" -exec rm -r {} \;
test -d /usr/include/libmilter && rm -r /usr/include/libmilter
( cd /usr/lib ; rm -f libmilter.a sendmail )
( /usr/man/man1
  rm -f mailq.1* newaliases.1* vacation.1* )
( cd /usr/man/man8
  rm -f editmap.8* mail.local.8* mailstats.8* makemap.8* praliases.8*\
   rmail.8* sendmail.8* smrsh.8* )
( cd /usr/sbin
  rm -f editmap mail.local mailstats makemap praliases sendmail smrsh )
test -d /usr/share/sendmail && rm -r /usr/share/sendmail
test -d /var/spool/clientmqueue && rm -r /var/spool/clientmqueue
test -d /var/spool/mqueue && rm -r /var/spool/mqueue
rm -f /etc/rc.d/rc.sendmail /usr/lib64/libmilter.a /usr/man/man5/aliases.5*
exit
find ~/src -maxdepth 1 -type d -name "sendmail-*" -exec rm -r {} \;
rm -f ~/installed/sendmail-*.tar.*

Back to the list


Last updated: Tue, 07 Aug 2018 12:06:17 -0400
Jason Englander <jason at englanders dot us>