subject: Sendmail Tips (incl. fixing broken mailqueue)
posted: Wed, 18 Aug 2004 09:42:33 +0100


http://networking.ringofsaturn.com/Unix/sendmailtips.php

Sendmail Tips

This is a quick document on how to get yourself out of some binds
I've run into with sendmail. These aren't going to be the most
organized, but I figure someone else may find these useful.

Mail Spool

Sendmail generally stores its queued mail in the /var/spool/mqueue
folder. Queued messages are messages that have not reached their
final destination yet. There are two files associated with each e-
mail message, one beginning with qf, the other beginning df. qf files
contain the message header, df files contain the body of the mail
message. You can tell which files are tied together because they have
the same ending; for example the header file qfPAA22846 has an
associated "body" file named dfPAA22846.

Stopping/Starting Sendmail

Depending on which type of OS you are running on, here's some of the
ways you may start/stop sendmail:

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

FreeBSD

cd /etc/mail
make stop | start

Solaris

/etc/rc2.d/S88sendmail stop

You'll generally want to let sendmail slowly come to a halt -- it
tries to stop its connections gracefully. When you're being mail
bombed you might want to be a little more insistant on killing off
sendmail. Note that people local to the machine (e.g. pine users and
certain cgi-bin programs) may still be able to put their new messages
into mqueue for delivery even while sendmail is stopped.

Large Mail Spool

If sendmail is having problems, after stopping it you might want to
move the current queue directory to someplace else, to be processed
specially. This is simple enough --

mv /var/spool/mqueue /var/spool/mqueue-fixme
mkdir /var/spool/mqueue
chmod 755 /var/spool/mqueue
chown root:daemon /var/spool/mqueue

Cleaning the Mail Spool

There could be a lot of "trash" qf or df files left behind following
a bout of misbehaving sendmails. If the size of either file is 0, you
should be able to trash them safely.

cd /var/spool/mqueue-fixme

to get into your queue directory, and

find . -size 0 -exec rm {} \;

to find everything with a size of 0 and execute the remove command on
the found files. This is unwise to run in your default queue
directory, even when sendmail is stopped.

Perhaps a sleazy spammer, cretinous chain-mailer, naughty Novell
server, or administrator accidentally sending out e-mail to everyone
is the cause of your mail woes. You can pull these messages from the
mail queue thusly:

cd /var/spool/mqueue-fixme
mkdir /var/tmp/EVIDENCE-OF-ILLDOING
grep idiot@wherever qf* | cut -d":" -f1 | uniq | cut -d"f" -f2 | \
xargs -i echo "mv *{} /var/tmp/EVIDENCE-OF-ILLDOING" > RUNME
chmod 700 RUNME
./RUNME

A sendmail problem could result in lots of "qf" files with no
corresponding "df" file, and vice versa. You can get rid of these
unmatched files with:

cd /var/spool/mqueue-fixme
ls *f* | cut -d"f" -f2 | sort | uniq -c | sort -n | grep " 1 " | \
awk '{print $2}' | xargs -i echo "rm *{}" > RUNME
chmod 700 RUNME
./RUNME

Parsing an Alternate Mail Spool

To process mail lurking in an alternate queue, you can run sendmail
manually. For example, to see exactly what happens:

sendmail -oQ/var/spool/mqueue-fixme -q -v

will process the mail queue (-q) located in /var/spool/mqueue-fixme (-
oQ/var/spool/mqueue-fixme) verbosely one message at a time (-v). This
should produce something like the following:

Running /home/rnejdl/var/spool/mqueue/i05HgAGV098325 (sequence 3352
of 4476)
<[email protected]>... Connecting to 7218.j8j87hyrf.com. via
esmtp...

Filtering Bad HELO's
by Neil W Rickert <[email protected]>

There has been recent discussion on bad HELO parameters. I have been
experimenting with the rules below. Use at your own risk. They may
require some local changes.

You can put at the top of "Local_check_mail". In my case, I
am using `delay_checks' so I put them in a "check_mail" ruleset.

They should not be in "Local_check_relay" because you would want to
first know if the client has authenticated.

Basic strategy:

Allow any HELO parameter if:

The client authenticated, or
the client is one of ours (its IP address begins with a component
in class $=R).

Else reject if the HELO hostname is our own name or our own
IP address (tested against $=w), or if the HELO hostname is
unqualified (no "." in the middle).

This is a conservative check. I don't require that the HELO
parameter match the sending hostname -- only that it not match
our name and be syntactically valid at least to the extent of
containing a ".".

I have been testing this afternoon. So far it has only rejected one
message that didn't look obviousl spammish. But if the client says

HELO LIILXQMAIL01

I am not going to shed any tears over blocking that message. I
suspect (from recent history) that this is to a "User unknown" and
the sender never cleans up its mailing lists.

Limitations:

This might not stop a lot of spam. It is blocking about 1 message
every 4 minutes. But most of those would have been blocked anyway.
It is blocking and viruses,
and some other viruses. It is blocking a lot of asian mail that I
was probably blocked before. So far I haven't seen any 200.*
addresses blocked.

The spammers will probably retune their spamware, so within a few
months this might stop having much effect.

I check for SASL authentication, but not for SSL/client certificate
authentication. If you use that, you will need to make changes.

I check for the connecting client having an IP that starts in $=R.
I do not check for the client hostname ending in $=R. If that
is important, you may need to add a line or two.

There is no provision to whitelist particular clients. If you need
that, you will need to add rules that do an access lookup.

Also read the comments in the m4 rules source below (they begin
"dnl`'").

Note that what this will mainly do for me (until spammers retool) is
reduce the amount of spam sent to postmaster. With `delay_checks' I
was exempting postmaster from blocking. But I have placed these
rules where they will reject mail prior to that exempting.

# helo/ehlo checks of $s
dnl`'Rationale:
dnl`'Client software is often broken. We don't want to reject
dnl`'our own users client connections. Therefore we attempt
dnl`'to allow our users to pass the checks. Otherwise, block
dnl`'sites with a HELO/EHLO hostname that is unqualified, or
dnl`'is one of our own names
dnl`'
dnl`'Note that I had to at "127.0.0.1" to class $=R, so that
dnl`'local client software would bypass these tests. I also
dnl`'added "[127.0.0.1]" to class $=w, so that the localhost
dnl`'IP would count as one of our IPs.
dnl`'
R$*$:$1 $| <$&{auth_authen}>Check if authenticated
dnl`'Bypass the test for users who have authenticated.
R$* $| <$+>$:$1skip if auth
R$* $| <$*>$:$1$|<$&{client_addr}>[$&s]Get connection info
dnl`'Bypass for local clients -- IP address starts with $=R
R$* $| <$=R $*>[$*]$:$1skip if local client
dnl`'Bypass a "sendmail -bs" session, which use 0 for client ip
address
R$* $| <0>[$*]$:$1skip if sendmail -bs
dnl`'Reject our IP - assumes "[ip]" is in class $=w
R$* $| <$*> $=w$#error $@5.7.1 $:"550 Access denied - bogus HELO "
$&s
dnl`'Reject our hostname
R$* $| <$*> [$=w]$#error $@5.7.1 $:"550 Access denied - bogus HELO "
$&s
dnl`'Pass anything else with a "." in the domain parameter
R$* $| <$*> [$+.$+]$:$1qualified domain ok
dnl`'Reject if there was no "." or only an initial or final "."
R$* $| <$*> [$*]$#error $@5.7.1 $:"550 Access denied - bogus HELO "
$&s

Unresolvable client address

Some people want to accept only mail from systems which have a valid
PTR entry in DNS. In many cases this will reject also legitimate mail
hence it is not a feature provided by sendmail. However, if you
really want to do this, here is how:

LOCAL_RULESETS
SLocal_check_relay
R$*$: $&{client_resolve}
RTEMP$#error $@ 4.7.1 $: "450 Access denied. Cannot resolve PTR
record for " $&{client_addr}
RFORGED$#error $@ 4.7.1 $: "450 Access denied. IP name possibly
forged " $&{client_name}
RFAIL$#error $@ 4.7.1 $: "450 Access denied. IP name lookup failed "
$&{client_name}

You can put these rules in any of the Local_check_* rulesets
depending on your needs.

This page was created in 0.1589 seconds
Last modified: February 07 2004.

---
* Origin: [adminz] tech, security, support (192.168.0.2)

generated by msg2page 0.06 on Jul 21, 2006 at 19:04:09

 search: