MIMEDefang

From Wikislax
Jump to: navigation, search

What is MIMEDefang ?

MIMEDefang is a plugin specific to the Sendmail Milter interface and affords scanning modifying filtering or bouncing mails while they are being received by sendmail.

MIMEDefang consist of four major components: mimedefang, mimedefang-multiplexor, mimedefang.pl, and mimedefang-filter. MIMEDefang, written in C, splits incoming messages into parts. Mimedefang-multiplexor creates and manages a pool of perl processes that execute mimedefang.pl, a perl script.

Installing MIMEDefang

MIMEDefang requires a few perl modules that can be installed as below :

# perl -MCPAN -e shell
. . .
cpan> install Digest::SHA1
cpan> install IO::Stringy
cpan> install MailTool
cpan> install MIME::Tools
cpan> install MIME::Base64
cpan> install Unix::Syslog
cpan> install Net::DNSBL::Client
quit

Download MIMEDefang untar and install as below. Mickey Hill's MIMEDefang HOWTO includes detailed installation information and tips.

# tar -C /usr/local -xvf mimedefang-x.y.tar.gz
# cd /usr/local
# chown -R root:root mimedefang-x.y
# cd mimedefang-x.y
# ./configure --help | less
# ./configure --libdir=/usr/local/lib64 \
--mandir=/usr/local/man --with-user=milter
# make
# make install
# make clean

Configuring MIMEDefang

MIMEDefang uses a single configuration file in /etc/mail/sa-mimedefang.cf. Add the lines below for DCC Pyzor and Bayes. The bayes_path seems required for SpamAssassin to find the Bayes database :

use_dcc 1
dcc_timeout 10
dcc_path /usr/local/bin/dccproc

use_pyzor 1
pyzor_timeout 10
pyzor_path /usr/local/bin/pyzor

# Set Bayes parameters
#
use_bayes 1
use_learner 1
use_bayes_rules 1
bayes_auto_learn 1
bayes_auto_expire 1
bayes_file_mode 700
bayes_expiry_max_db_size 150000
bayes_path /var/spool/MD-Quarantine/.spamassassin/bayes

#   Set headers which may provide inappropriate cues to the Bayesian classifier
#
bayes_ignore_header X-Scanned-By
bayes_ignore_header X-Spam-Check
bayes_ignore_header X-Spam-Score
bayes_ignore_header X-Probably-Spam-Tag

/etc/mail/mimedefang-filter is a perl fragment read by mimedefang.pl where customization can take place. Be sure to check man mimedefang-filter. Global variable $SALocalTestsOnly has a default value of 1 to to disable Receive, RBL and Razor tests. Add line $SALocalTestsOnly = 0; at the beginning of mimedefang-filter to enable these tests. The code snipet below extracted from filter_end in mimedefang-filter calls for a few interesting comments:

  • Messages of 100K or more are unlikely to be spam so are not scanned to avoid a waste of resources.
  • The number of stars in X-Spam-Score is easy to use in your MUA rules to classify mail as ham or spam.
  • We disabled the spamassassin report to collect spam unmodified for the Bayes module initialization.
  • We added line action_sm_quarantine("$hits ($score) $names"); to test the Sendmail quarantine feature.
   # Spam checks if SpamAssassin is installed
   if ($Features{"SpamAssassin"}) {
       if (-s "./INPUTMSG" < 100*1024) {
           # Only scan messages smaller than 100kB.  Larger messages
           # are extremely unlikely to be spam, and SpamAssassin is
           # dreadfully slow on very large messages.
           my($hits, $req, $names, $report) = spam_assassin_check();
           my($score);
           if ($hits < 40) {
               $score = "*" x int($hits);
           } else {
               $score = "*" x 40;
           }
           # We add a header which looks like this:
           # X-Spam-Score: 6.8 (******) NAME_OF_TEST,NAME_OF_TEST
           # The number of asterisks in parens is the integer part
           # of the spam score clamped to a maximum of 40.
           # MUA filters can easily be written to trigger on a
           # minimum number of asterisks...
           if ($hits >= $req) {
               action_change_header("X-Spam-Score", "$hits ($score) $names");
               md_graphdefang_log('spam', $hits, $RelayAddr);
               # If you find the SA report useful, add it, I guess...
               action_add_part($entity, "text/plain", "-suggest",
                               "$report\n",
                             "SpamAssassinReport.txt", "inline");
               # action_quarantine_entire_message("$hits ($score) $names");
               # action_sm_quarantine("$hits ($score) $names");
               # send_quarantine_notifications();
               # action_discard();
           } else {
               # Delete any existing X-Spam-Score header?
               action_delete_header("X-Spam-Score");
           }
       }
   }

There is nothing special to configure in Sendmail to use the quarantine feature. mailq -qQ affords viewing the content of the quarantine queue, sendmail -qQ -qIsubstr -Q affords unquarantining a specific mail.

Note : if anything goes wrong it is possible to get all SpamAssassin debug information in the maillog file by adding a debug => 1, parameter when creating the SpamAssassin object in function spam_assassin_init of /usr/local/bin/mimedefang.pl :

#***********************************************************************
# %PROCEDURE: spam_assassin_init
# %ARGUMENTS:
#  config -- optional spamassassin config file
# %RETURNS:
#  A Mail::SpamAssassin object.
# %DESCRIPTION:
#  Scans message using SpamAssassin (http://www.spamassassin.org)
#***********************************************************************
sub spam_assassin_init (;$) {
    my($config) = @_;
    my $LOCAL_RULES_DIR = '/etc/mail/spamassassin';
    my $LOCAL_STATE_DIR = '/var/lib';

    . . .

        my $sa_args = {
                debug              => 1,
                local_tests_only   => $SALocalTestsOnly,
                dont_copy_prefs    => 1,
                userprefs_filename => $config,
                user_dir           => $Features{'Path:QUARANTINEDIR'},
        };

Configuring Milter

Add the INPUT_MAIL_FILTER macro to sendmail.mc to send all mails trough the specified filter :

# cd /usr/local/sendmail-*/cf/cf
# vi sendmail.mc
a
INPUT_MAIL_FILTER(`mimedefang', `S=unix:/var/spool/MIMEDefang/mimedefang.sock, F=T, T=S:5m;R:5m')dnl
<esc>
:x
# m4 ../m4/cf.m4 sendmail.mc > sendmail.cf
# cp sendmail.mc /etc/mail
# cp sendmail.cf /etc/mail

Reconfiguring rc.sendmail

MIMEDefang must be started before and stopped after sendmail. Copy the init-script provided under /etc/rc.d then call it from rc.sendmail.

# cp examples/init-script /etc/rc.d/rc.mimedefang
# vi /etc/rc.d/rc.sendmail
. . .
# Start sendmail:
sendmail_start() {
  /etc/rc.d/rc.mimedefang start
  sleep 2
  if [ -x /usr/sbin/sendmail ]; then
    echo "Starting sendmail MTA daemon:  /usr/sbin/sendmail -L sm-mta -bd -q25m"
    /usr/sbin/sendmail -L sm-mta -bd -q25m
    echo "Starting sendmail MSP queue runner:  /usr/sbin/sendmail -L sm-msp-queue -Ac -q25m"
    /usr/sbin/sendmail -L sm-msp-queue -Ac -q25m
  fi
}

# Stop sendmail:
sendmail_stop() {
  /etc/rc.d/rc.mimedefang stop
  killall sendmail
  sleep 6
}
. . .
<esc>
:x

Running Sendmail with MIMEDefang

As we have installed and configured SpamAssassin, ClamAV and MIMEDefang previously, all the pieces are now in place and ready to interlock. Just restart sendmail :

# /etc/rc.d/rc.sendmail start
Starting mimedefang-multiplexor:                            [  OK  ]
Starting mimedefang:                                        [  OK  ]
Starting sendmail MTA daemon:  /usr/sbin/sendmail -L sm-mta -bd -q25m
Starting sendmail MSP queue runner:  /usr/sbin/sendmail -L sm-msp-queue -Ac -q25m
root@inner:/etc/rc.d#

Check behaviour in file /var/log/maillog.

A MIMEDefang issue

Sometimes the message Milter (mimedefang): local socket name /var/spool/MIMEDefang/mimedefang.sock unsafe can be found in file /var/log/maillog for each incoming mail, in this case not processed. As the socket is created automatically by MIMEDefang at run time, the error message itself is mistaken. What actually happens is that the socket is not created at all.

The root cause is unclear. Buggy perl modules have been mentionned on some websites. A list of the perl modules used by MIMEDefang can be obtained by "mimedefang.pl -features" and upgraded with the upgrade command of perl. Another likely cause is that MIMEDefang seems to need some time to properly wrap-up on termination. To work around this, we added as above some sleep commands in file /etc/rc.d/rc.sendmail.

The presence of the socket can be tested with the command :

# ls -al /var/spool/MIMEDefang/
total 16
drwxr-x---  2 milter root   4096 Oct 10 14:08 ./
drwxr-xr-x 18 root   root   4096 Oct  7 08:22 ../
srw-rw-rw-  1 milter milter    0 Oct  9 12:48 clamd.sock=
-rw-------  1 milter milter    6 Oct 10 14:08 mimedefang-multiplexor.pid
srwx------  1 milter milter    0 Oct 10 14:08 mimedefang-multiplexor.sock=
-rw-------  1 milter milter    6 Oct 10 14:08 mimedefang.pid
srwx------  1 milter milter    0 Oct 10 14:08 mimedefang.sock=


Milter Main Page MySQL