Retrieving queued mail on DMZ Sendmail server

Situation: we have a Sendmail server in a DMZ that is used to receive email addressed to one of our company's domains. Unfortunately, we cannot permit SMTP connections from this DMZ SMTP server to our internal SMTP server. Therefore, we have to retrieve the mail from an internal SMTP server and process it locally.

Before attempting this, please read this comp.mail.sendmail thread. Ideally, SMTP connections from your DMZ SMTP server should be allowed to internal SMTP hosts. This "pull queued mail" solution should only be used when you have no alternative.

To retrieve queued mail on a DMZ Sendmail server, we need to perform the following steps:

1. Configure the DMZ SMTP server to queue mail rather than attempt immediate delivery. This is accomplished by adding the following to your sendmail.mc file:
define(`confDELIVERY_MODE', `queue')dnl

After adding this line, rebuild and install the sendmail.cf file, and send the Sendmail daemon a SIGHUP to reread the new configuration.
./Build install-cf
kill -HUP `head -n1 /var/run/sendmail.pid`

2. Remove the queue runner from the Sendmail startup and shutdown script on the DMZ SMTP server.

Example lines to change in /etc/init.d/sendmail on DMZ SMTP server:
        # Start the MTA
        /usr/lib/sendmail -L sm-mta -bd -q1h

Change to:
        # Start the MTA; no queue runner
        /usr/lib/sendmail -L sm-mta -bd

Restart Sendmail for the change to take effect.

/etc/init.d/sendmail stop
/etc/init.d/sendmail start

3. On our internal SMTP server, create a separate mqueue directory for mail queued on our DMZ SMTP server.
mkdir /var/spool/mqueue/DMZ_SMTP_server

4. Create a script on the internal SMTP server to retrieve and process the queued messages. I will call the script retrieve_DMZ_mail and place it in the /etc/mail directory.

#!/bin/sh

# Variables
SSH=/usr/local/bin/ssh
SCP=/usr/local/bin/scp
SENDMAIL=/usr/lib/sendmail
DMZ_SMTP=DMZ_SMTP_server
REMOTE_MQUEUE_DIR=/var/spool/mqueue
LOCAL_MQUEUE_DIR=/var/spool/mqueue/$DMZ_SMTP

# If $REMOTE_MQUEUE_DIR is not empty, create an archive of the messages
$SSH $DMZ_SMTP "cd $REMOTE_MQUEUE_DIR; [ -f * ] && tar cf $$.tar * || exit 1"

# If there are no files in $REMOTE_MQUEUE_DIR, exit
[ $? -eq 1 ] && exit

# Immediately remove $REMOTE_MQUEUE_DIR files to prevent another occurrence
# of this script from retrieving and processing the same files
$SSH $DMZ_SMTP "cd $REMOTE_MQUEUE_DIR; tar tf $$.tar | xargs rm"

# Retrieve remove queued messages
cd $LOCAL_MQUEUE_DIR
$SCP $DMZ_SMTP:$REMOTE_MQUEUE_DIR/$$.tar .


# Remove remote archive
$SSH $DMZ_SMTP rm $REMOTE_MQUEUE_DIR/$$.tar

# Extract queued messages locally
tar xf $$.tar
rm $$.tar

5. Add the above script to the root user's crontab to regularly retrieve and process queued mail. In this example, I will run the script every 5 minutes.

crontab -e

Add:

# Retrieve queued DMZ mail every 5 minutes
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /etc/mail/retrieve_DMZ_mail > /dev/null 2>&1

6. Add a "persistent queue runner" to your Sendmail startup and shutdown script for $LOCAL_MQUEUE_DIR. The persistent queue runner will regularly check $LOCAL_MQUEUE_DIR for new messages to process.

Run the following command to start the persistent queue runner immediately, and add the command to your Sendmail startup/shutdown script (/etc/init.d/sendmail):
/usr/lib/sendmail -qp -oQ/var/spool/mqueue/DMZ_smtp_server

Back to brandonhutchinson.com.
Last modified: 12/13/2005