Tuning Perimeter Sendmail Servers

By unwire, January 5, 2006

Another post from my old website, moving it here:

Tuning Perimeter Sendmail Servers

Recently Ive needed to manage a large amount of double bounced spam on perimeter sendmail servers. The main problem was the bounced messages were filling up the sendmail queue directory to the point where there were
tens of thousands of rejected messages. This would seriously delay legitimate email.

The workaround was to move email out of the primary queue at a certain threshold and to process mail in the secondary queue with different options. The move of the email from primary to secondary is accomplished by using the qtool.pl script that is included in the sendmail distribution.

The primary queue continues to get lots of attention from sendmail and at the same time email that has been retried many times is moved and delivery
attempts are reduced.

Four times per hour the following script is run in cron:

# Move low priority mail to /var/spool/mqueue2
5,20,35,50 * * * * /usr/local/bin/qtool.pl -e ‘($msg{sender} =~ /MAILER-DAEMON|<>/) or ($msg{num_delivery_attempts} >=16)’ /var/spool/mqueue2 /var/spool/mqueue/q0 > /dev/null 2>&1


The above options ($msg{sender} =~ /MAILER-DAEMON|<>/) will move all double bounced email and all email with a null sender to the secondary queue. The

($msg{num_delivery_attempts} >=16) option moves all mail where sendmail has made more than 16 attempts to deliver it.

Three times per hour another sendmail queue runner is started for the secondary

# Queue Run on /var/spool/mqueue2

15,35,55 * * * * /usr/lib/sendmail -q -O QueueDirectory=/var/spool/mqueue2 -O MinQueueAge=8h > /dev/null 2>&1

The MinQueueAge=8h option forces this secondary queue runner to ignore all mail that has been processed within the last eight hours. This drastically speeds up processing of the mail in the secondary queue. Normally with this, all mail in the secondary queue is retried at least three times per day. Reducing the frequency of attempts has been critical when the queue starts to have tens of thousands of messages.

And finally, we need some way to monitor the two sendmail queues. These cron jobs place a mail message every two hours into each of the queues. I can monitor the performance by comparing the time the email was sent vs. the time it was delivered by the next queue runner.

# Monitor Mail Queues

35 1,3,5,7,9,11,13,15,17,19,21,23 * * * /usr/bin/echo SUBJECT: QueueTime 0 `/usr/bin/hostname |/usr/bin/cut -d. -f1; /usr/bin/date` | /usr/lib/sendmail -Am -OQueueDirectory=/var/spool/mqueue/q0 -odq me@mycompany.com > /dev/null 2>&1

# Monitor Queue2
35 1,3,5,7,9,11,13,15,17,19,21,23 * * * /usr/bin/echo SUBJECT: Queue2Time `/usr/bin/hostname |/usr/bin/cut -d. -f1; /usr/bin/date` | /usr/lib/sendmail -Am -OQueueDirectory=/var/spool/mqueue2 -odq me@mycompany.com > /dev/null

Here are my sendmail.mc settings.

define(`TO’,                       `60s’)dnl
define(`confTO_ICONNECT’,          `TO’)dnl
define(`confTO_CONNECT’,           `TO’)dnl
define(`confTO_COMMAND’,           `TO’)dnl
define(`confTO_DATAINIT’,          `TO’)dnl
define(`confTO_HELO’,              `TO’)dnl

define(`confTO_HOSTSTATUS’,        `TO’)dnl
define(`confTO_INITIAL’,           `TO’)dnl

define(`confTO_MAIL’,              `TO’)dnl
define(`confTO_QUIT’,              `TO’)dnl
define(`confTO_RCPT’,              `TO’)dnl
define(`confTO_RCPT’,              `TO’)dnl
define(`confTO_RESOLVER_RETRANS’,  `TO’)dnl
define(`confTO_RESOLVER_RETRY’,    `4′)dnl
define(`confTO__RSET’,             `TO’)dnl

define(`confTO_DATABLOCK’,         `5m’)dnl

define(`confTO_DATAFINAL’,         `5m’)dnl
define(`confMESSAGE_TIMEOUT’,      `3d’)dnl

You are responsible for any changes to your sendmail environment. Your environment will likely need tuning of many parameters for optimal
sendmail performance.
See the Sendmail website for more

One Comment

  1. Christina says:

    Thanks for the tip! I do hate those double-bounces…