Running a second sendmail instance

Situation: We want to separate core mail from "higher-risk" mail (i.e. mail sent from application servers in a DMZ) on our sendmail servers. In the event that one of our DMZ servers for which we relay mail is compromised, we do not want our mail server placed on a DNS blacklist. Therefore, we will have separate IP addresses for core mail and "higher-risk" mail. In this example, the system has only one physical network interface, so we will create and enable a virtual interface for "higher-risk" mail.

1. Create and enable the virtual interface. In this example, the primary network interface is eri0 with IP address 192.168.1.1. The virtual interface has an IP address of 192.168.1.2, and has a fully-qualified domain name of virt-int.example.com.

# ifconfig eri0:1 plumb
# ifconfig eri0:1 192.168.1.1 netmask 255.255.255.0 up

2. Modify /etc/hosts and /etc/hostname.eri0:1 to enable the virtual interface after each system boot.

# echo "virt-int" > /etc/hostname.eri0:1
# echo "192.168.1.1\tvirt-int.example.com\tvirt-int" >> /etc/hosts

3. Make a copy of the main sendmail.mc file. This copy will be used to configure the second sendmail instance.
$ cp sendmail.mc virt-int.mc

4. By default, the main sendmail instance will bind to TCP port 25 on all network interfaces. We want the main sendmail instance to only bind to TCP port 25 on its IP address and the localhost interface. In the main sendmail.mc file, add the following lines:

DAEMON_OPTIONS(`Addr=192.168.1.1')dnl
DAEMON_OPTIONS(`Addr=127.0.0.1')dnl

By default, the sendmail mail submission agent (MSA, used to submit mail on the local system to an MTA) attempts to connect to an MTA on the localhost (127.0.0.1) interface. The second line above binds the primary sendmail instance to the localhost interface in addition to its IP address. The MSA configuration file, submit.mc, could have instead been modified to use the MTA on the primary interface or the virtual interface.

5. Configure the second sendmail instance by adding the following lines to virt-int.mc:

FEATURE(no_default_msa)dnl
define(`QUEUE_DIR',`/var/spool/mqueue/virt-int/q*')dnl
define(`confPID_FILE',`/var/run/sendmail_virt-int.pid')dnl
define(`confDOMAIN_NAME',`virt-int.example.com')dnl

CLIENT_OPTIONS(`Addr=192.168.1.2')dnl

DAEMON_OPTIONS(`Addr=192.168.1.2')dnl

The first line above prevents the second sendmail instance from attempting to start its own Mail Submission Agent (MSA) on TCP port 587. The main sendmail instance will have its own MSA bound to this port, and the second sendmail instance will not start if it attempts to also bind to TCP port 587.

The second line specifies an alternate mail queue directory for the second sendmail instance. If mail processed by the second sendmail instance cannot be immediately delivered, it will be queued. If mail queue directories are not separated for the two sendmail instances, the main sendmail instance's queue runner could process mail queued by the second sendmail instance.

The third line specifies a process ID (PID) file for the second sendmail instance. Having a separate PID file makes it easy to stop the second sendmail instance from an /etc/init.d script.

The fourth line populates sendmail's $j macro with the fully-qualified domain name of the second sendmail instance. Without it, mail processed by the second sendmail instance may contain hostname information of the main sendmail instance.

The fifth line is needed so that the second sendmail instance uses its IP address when acting as a client (i.e. when relaying mail).

The sixth line is needed to bind the second sendmail instance to the virtual interface.

Note: if you use RELAY_DOMAINS_FILE in virt-int.mc and do not want values from /etc/mail/relay-domains in class R, you must add undefine(`confCR_FILE') to virt-int.mc.

Otherwise, entries from both /etc/mail/relay-domains and the file specified in RELAY_DOMAINS_FILE will be added to class R. This is because cf/m4/cfhead.m4 populates confCR_FILE with /etc/mail/relay-domains by default.

If you use confCR_FILE instead of RELAY_DOMAINS_FILE in virt-int.mc to populate class R, the confCR_FILE value in virt-int.mc will supersede cf/m4/cfhead.m4, and only entries from confCR_FILE in virt-int.mc will be listed in class R.

6. Create the mail queue directory for the second sendmail instance.
# mkdir -p /var/spool/mqueue/virt-int/q1 /var/spool/mqueue/virt-int/q2 \ /var/spool/mqueue/virt-int/q3 /var/spool/mqueue/virt-int/q4 /var/spool/mqueue/virt-int/q5

7. Build and install the sendmail configuration files.

$ ./Build sendmail.cf
$ ./Build virt-int.cf
# cp sendmail.cf virt-int.cf /etc/mail

8. Reread the configuration file of the main sendmail instance.
# kill -HUP `head -1 /var/run/sendmail.pid`

9. Start the second sendmail instance.
# sendmail -L sm-mta-virt-int -C /etc/mail/virt-int.cf -bd -q30m

10. Modify the sendmail startup and shutdown script for the second sendmail instance.

/etc/init.d/sendmail changes in bold.

#!/bin/sh

case "$1" in
'start')
   # Start the MTA
   /usr/lib/sendmail -L sm-mta -bd -q30m
   # Start the second MTA instance
   /usr/lib/sendmail -L sm-mta-virt-int -C /etc/mail/virt-int.cf -bd -q30m
   # Start the MSP
   /usr/lib/sendmail -L sm-msp-queue -Ac -q30m
   ;;
'stop')
   # Stop the MTA
   [ -f /var/run/sendmail.pid ] && \
/usr/bin/kill `/usr/bin/head -1 /var/run/send
mail.pid`
   # Stop the second MTA instance
   [ -f /var/run/sendmail_virt-int.pid ] && \
/usr/bin/kill `/usr/bin/head -1 /var/run/sendmail_virt-int.pid`

   # Stop the MSP
   MSP_PID=`/usr/bin/ps -e -o pid,args | /usr/bin/grep [s]m-msp-queue | \
/usr/bin
/awk '{print $1}'`
   [ -n "$MSP_PID" ] && /usr/bin/kill $MSP_PID
   ;;
*)
   echo "Usage: $0 { start | stop }"
   exit 1
   ;;
esac
exit 0

Back to brandonhutchinson.com.
Last modified: 2006/04/17