Home

Search this site:
 

Horshack’s
very
own site

 

This is Bavaria, Germany!
You will find links to Perl,
bootdisks for system administration,
a lot of Linux,
Windows administration
and some personal belongings.
Installing a new Debian system

Installing MIMEdefang, Spamassassin

Installing MIMEdefang

mail2:/# apt-get install -t testing mimedefang
mail2:/# /etc/init.d/mimedefang start
Mimedefang runs now, there should be a file /var/spool/MIMEDefang/mimedefang.sock which is the pipe to put all mails in for sendmail.

Don't care for /var/spool/MIMEDefang/mimedefang-multiplexor.sock, this simply means that some mimedefang.pl programms are started in and endless loop. So the load of the system is much lower because there will not be a new programm started for every mail you get through your system.

Configure

Put this line into /etc/mail/sendmail.mc and run a make after that. This is not done by the installation of mimedefang. I found this hint in /usr/share/doc/mimedefang/README.Debian

# vim /etc/mail/sendmail.mc
...
LOCAL_CONFIG
...
INPUT_MAIL_FILTER(`mimedefang', `S=unix:/var/spool/MIMEDefang/mimedefang.sock, F=T, T=S:1m;R:1m')dnl
...
LOCAL_CONFIG
...

Localize mimedefang-message in mail-header:

# vim /etc/mail/mimedefang.conf   

...
# The contents of the "X-Scanned-By" header added to each mail.  Do
# not use the quote mark (') in this setting.  Setting it to "-"
# prevents the header from getting added at all.
# X_SCANNED_BY="MIMEDefang N.NN (www . roaringpenguin . com / mimedefang)"
# This seems not to work when there are spaces in the string!
X_SCANNED_BY="MIMEDefang_at_mail2.zdf__Stadt_Zirndorf"
...

Which mails get catched by MIMEdefang and what happens to this mails

Attachments with special names get catched. In /etc/mail/mimedefang-filter you will find this:

# Bad extensions
$bad_exts = '(ade|adp|app|......|exe|....|pif|....|scr|....|\{[^\}]+\})';

Bad mails will be moved to directory /var/spool/MIMEdefang. Take a look:

mail2:/etc/mail# ls -l /var/spool/MIMEDefang/
drwx------    2 defang   defang       4096 Mär 23 13:18 qdir-2004-03-23-13.18.05-001
drwx------    2 defang   defang       4096 Mär 23 13:24 qdir-2004-03-23-13.24.05-001
drwx------    2 defang   defang       4096 Mär 23 13:30 qdir-2004-03-23-13.30.16-001
drwx------    2 defang   defang       4096 Mär 23 13:58 qdir-2004-03-23-13.58.05-001
drwx------    2 defang   defang       4096 Mär 23 13:58 qdir-2004-03-23-13.58.07-001
drwx------    2 defang   defang       4096 Mär 23 14:00 qdir-2004-03-23-14.00.16-001
drwx------    2 defang   defang       4096 Mär 23 14:04 qdir-2004-03-23-14.04.05-001
drwx------    2 defang   defang       4096 Mär 23 14:30 qdir-2004-03-23-14.30.07-001
drwx------    2 defang   defang       4096 Mär 23 14:32 qdir-2004-03-23-14.32.06-001
drwx------    2 defang   defang       4096 Mär 23 14:34 qdir-2004-03-23-14.34.05-001
Create a cronjob which removes old defanged files from /var/spool/MIMEdefang
# crontab -e
# delete old mimedefang-dirs, older that 7 days
00 18 * * * (find /var/spool/MIMEDefang -type d -mtime +7 -maxdepth 1 -print | xargs rm -rf) >/dev/null 2>&1

Let it run

/etc/init.d/sendmail stop
/etc/init.d/mimedefang stop
sleep 2
/etc/init.d/mimedefang start
sleep 2
/etc/init.d/sendmail start

Test

Send a testmail like this which must be intercepted by mimedefang, because standard in /etc/mail/mimedefang-filter is to filter *.exe-files. Look in /var/spool/mail.log for mimedefangs behaviour:

mail2:~/bin/testmail# apt-get install sharutils    ### install uuencode
mail2:~/bin/testmail# echo dontcare-dontcare >bad.exe
mail2:~/bin/testmail# uuencode bad.exe bad.exe | mail -s "test 
for bad attach" lippmann@zirndorf.de
Remember that mimedefang checks attachment simply by their filenames! You should see something like this in /var/spool/mail.log:
 

Mar 19 07:31:21 mail2 mimedefang.pl[22067]: MDLOG,i2J7VKjB022691, bad_filename, bad.exe, application/octet-stream, <root@mail2.zdf>, <lippmann@zirndorf.de>, test for bad attach

Mar 19 07:31:21 mail2 mimedefang.pl[22067]: filter: i2J7VKjB022691:  quarantine=1

Mar 19 07:31:21 mail2 sm-mta[22691]: i2J7VKjB022691: Milter message: body replaced

Mar 19 07:31:21 mail2 sm-mta[22691]: i2J7VKjB022691: Milter add: header: X-Scanned-By: 'MIMEDefang 

German mimedefang warnings for your users

My users like to have a german warning-message, not like this:

[Variable $GeneralWarning] WARNING: This e-mail has been altered by MIMEDefang.  Following this paragraph are indications of the actual changes made.  For more information about your site's MIMEDefang policy, contact  <you-know-who@hogwarts.co.uk>.  For more information about MIMEDefang, see:

            http://www.roaringpenguin.com/mimedefang/enduser.php3

[Defined in sub filter of /etc/mail/mimedefang-filter] An attachment named bad.exe was removed from this document as it constituted a security hazard.  If you require this document, please contact the sender and arrange an alternate means of receiving it.

This is defined in /usr/bin/mimedefang.pl, look for if (!defined($GeneralWarning)) {

But it's a better idea to include a line like this in /etc/mail/mimedefang-filter:

# Put this new line at the very beginning
$GeneralWarning = "ACHTUNG: Hier ist der Rechner mail2.zdf der Stadt Zirndorf.\n\n"; ... sub filter ($$$$) { if (filter_bad_filename($entity)) { md_graphdefang_log('bad_filename', $fname, $type); return action_quarantine($entity, "Eine Datei mit dem Namen $fname wurde von dieser Mail entfernt weil sie im Verdacht steht ein Sicherheitsrisiko für unser Netzwerk zu sein. Wenn Sie diese Datei erwartet haben und sie benötigen wenden Sie sich bitte an Ihre PC-Systemverwaltung.\n"); } [*** TODO ***]

What has happened to the files? The user gets informed

Restart everything and test:

/etc/init.d/sendmail stop
/etc/init.d/mimedefang stop
sleep 2
/etc/init.d/mimedefang start
sleep 5 # wait until all processes start
/etc/init.d/sendmail start
echo dontcare >/tmp/bad.exe
uuencode /tmp/bad.exe bad.exe | mail -s "umbridge sends bad mail" lippmann@zirndorf.de

Installing Spamassassin

mail2:/etc/mail# apt-get install -t testing spamassassin
mail2:/etc/mail# /etc/init.d/sendmail stop
mail2:/etc/mail# /etc/init.d/mimedefang stop

Create a little special rule for testing to see spamassassin work.

mail:/# vim /etc/mail/spamassassin/local.cf

    # Only to test
    header BAD_TEST             Subject =~ /i am evil/i
    score BAD_TEST              5.00

mail2# /etc/init.d/mimedefang start
mail2# /etc/init.d/sendmail start
mail2# mail -s "i am evil" lippmann@zirndorf.de </dev/null
You should see something like this in /var/spool/mail.log:
 

Mar 19 10:48:38 mail2 sendmail[27376]: i2JAmcjn027376: from=root, size=45, class=0, nrcpts=1, msgid=<200403191048.i2JAmcjn027376@mail2.zdf>, relay=root@localhost

Mar 19 10:48:38 mail2 sm-mta[27378]: i2JAmcVx027378: from=<root@mail2.zdf>, size=309, class=0, nrcpts=1, msgid=<200403191048.i2JAmcjn027376@mail2.zdf>, proto=ESMTP, daemon=MSA, relay=mail2 [10.95.81.71]

Mar 19 10:48:38 mail2 mimedefang.pl[27174]: MDLOG, i2JAmcVx027378, spam,15,10.95.81.71, <root@mail2.zdf>, <lippmann@zirndorf.de>, i am evil

Mar 19 10:48:38 mail2 sm-mta[27378]: i2JAmcVx027378: Milter message: body replaced

Configuring spamassassin: local.cf

/etc/mail/spamassassin/local.cf is the point to create all your local rules. If you are good-skilled in database-programming you can do this with a script from a database (best practise, sorry no link here for that!). This is a small part of my ruleset:

###################################################################
# ruleset whitelist
###################################################################
whitelist_from me@home.de
whitelist_from mywife@home.de

###################################################################
# ruleset blacklist
###################################################################
blacklist_from *@*.cnetchannel.com
blacklist_from *@jeepmania.it

###################################################################
# ruleset rescore
###################################################################
score CHINA_HEADER 3
score FORGED_YAHOO_RCVD 5
score HTML_IMAGE_ONLY_02 5
score SUB_FREE_OFFER 4

###################################################################
# content-check, ruleset bad
###################################################################
header ZDF_BOESE_1             Subject =~ /your account/i
describe ZDF_BOESE_1           your account
score ZDF_BOESE_1              5.00

header ZDF_BOESE_2             From =~ /^admin\@/i
describe ZDF_BOESE_2           Mail from admin
score ZDF_BOESE_2              5.00

body ZDF_BOESE_4               /sent as a binary/i
describe ZDF_BOESE_4           Sent as a binary
score ZDF_BOESE_4              5.00


###################################################################
# these rules are _always_ valid
###################################################################
header ZDF_ZZ_1                From =~ /./i
describe ZDF_ZZ_1              local.cf lives
score ZDF_ZZ_1                 0.01

body ZDF_ZZ_2                  /./i
describe ZDF_ZZ_2              local.cf body lives
score ZDF_ZZ_2                 0.01

mimedefang-filter, a central routine to log to a database

/etc/mail/mimedefang-filter is the perl-script to make your things happen: log mails into a database, log attachments, log spam... I changed it like this.

Single point to get database-handle

sub get_dbh {
        use DBI;
        my ($dbname,$dbuser,$dbpass,$dbhost)= 
	      qw(watchtower wwwrun XXXX mysql.internal.org);
        my $dbh = DBI->connect("dbi:mysql:$dbname:$dbhost",$dbuser,$dbpass);
        return $dbh;
}

 

sub log2db {
        # You must have this table in your MySQL-database:
        #   CREATE TABLE `mailtrouble` (
        #   `lfdnr` int(11) NOT NULL auto_increment,
        #   `intime` datetime NOT NULL default '0000-00-00 00:00:00',
        #   `sender` varchar(50) default NULL,
        #   `recipient` varchar(50) default NULL,
        #   `subject` varchar(50) default NULL,
        #   `reason` varchar(20) NOT NULL default '',
        #   `shortreason` varchar(80) NOT NULL default '',
        #   PRIMARY KEY  (`lfdnr`)
        # ) TYPE=MyISAM;
        my (%args)=@_;
        my $shortreason = $args{shortreason} || "";
        my $reason = $args{reason} || "";
        # Kann man als Argumente angeben, muss man aber nicht
        my $subject = exists $args{subject} ? $args{subject} : $Subject;

        my $dbh = &get_dbh;
        return unless $dbh;

        my $sql = sprintf "insert into mailtrouble (intime, sender, recipient, subject, reason, shortreason) values (now(),%s,%s,%s,%s,%s)",
                $dbh->quote($Sender),
                $dbh->quote(join(",",@Recipients)),
                $dbh->quote($Subject),
                $dbh->quote($reason),
                $dbh->quote($shortreason);
        $dbh->do($sql);
        $dbh->disconnect();
}

mimedefang-filter, check mails larger than 100 KBytes

File: /etc/mail/mimedefang-filter

sub filter_end ($) {
...
    # Spam checks if SpamAssassin is installed
    if ($Features{"SpamAssassin"}) {
        # we have to scan larger mails!
        # if (-s "./INPUTMSG" < 100*1024) {
        if (-s "./INPUTMSG" < 3000*1024) {
            # Only scan messages smaller than 100kB.  Larger messages
            # are extremely unlikely to be spam, and SpamAssassin is
            # dreadfully slow on very large messages.
   
...

mimedefang-filter: throw virus-mails into the dustbin

Usually you would deny accepting virus-mails, but I accept them. Because I get mails from fetchmail or from other own systems from the borderline. So virus-mails

  1. get to sendmail
  2. get checked by the virus-scanner
  3. a log into the database and throw them away.

 

sub filter ($$$$) {
...
    # Virus scan
    if ($FoundVirus) {
    ...
            # Log and throw away, you need a "sub log2db"!
            &log2db( shortreason=>"virus", reason=> $VirusName);
            action_discard();
            # I cannot bounce in my environment
            # action_bounce("Virus $VirusName found in mail - rejected");
           
...

mimedefang-filter: log every attachment

I want to have an overview about attachments

sub filter ($$$$) {
...
    # Log every attachment to a database
    &log_attachments(attach_fn=>$fname)
        if $fname;

    if (filter_bad_filename($entity)) {
    ...        
...

You need a subroutine to log into the database, first the single point to open the database:

sub get_dbh {
        use DBI;
        my ($dbname,$dbuser,$dbpass,$dbhost)= 
	      qw(watchtower wwwrun XXXX mysql.internal.org);
        my $dbh = DBI->connect("dbi:mysql:$dbname:$dbhost",$dbuser,$dbpass);
        return $dbh;
}

Then the log-routine:

sub log_attachments {
        # You must have this table in your MySQL-database:
        #   CREATE TABLE `mailattachments` (
        #   `lfdnr` int(11) NOT NULL auto_increment,
        #   `intime` datetime NOT NULL default '0000-00-00 00:00:00',
        #   `sender` varchar(50) default NULL,
        #   `recipient` varchar(50) default NULL,
        #   `subject` varchar(50) default NULL,
        #   `attachment_fn` varchar(80) NOT NULL default '',
        #   PRIMARY KEY  (`lfdnr`)
        # ) TYPE=MyISAM;
        my (%args)=@_;
        my $attach_fn = $args{attach_fn} || "";

        my $dbh = &get_dbh;
        return unless $dbh;

        # <h@lisa.de> --> h@lisa.de
        my $lsender = $Sender;
        $lsender =~ s/^<(.+)>$/$1/;

        my $sql = sprintf "insert into mailattachments (intime, sender, recipient, subject, attachment_fn) values (now(),%s,%s,%s,%s)",
                $dbh->quote($lsender),
                $dbh->quote(join(", ",@Recipients)),
                $dbh->quote($Subject),
                $dbh->quote($attach_fn);
        $dbh->do($sql);
        $dbh->disconnect();
}

mimedefang-filter: redirect mail to another user

In a company you get a lot of mails for a lot of users. If they shall not get all the spam and viruses, you have to redirect these mails to a special user (bad@we_are_good.org) which can take a view over this stuff to find false positives.

 Create a new subroutine like this:

sub redirect_mail_to_mr_spam {
    # Delete all Recipients from Spammail and send these mails
    # to a special user in our domain
    my $towhom_msg;
    foreach my $rec (@Recipients) {
        $towhom_msg .= "This mail should have been sent to: $rec\n";
        delete_recipient($rec);
    }
    add_recipient("edv\@exchange.zdf");
    # Add a file which shows to whom this mail should have been gone
    action_add_part($entity, "text/plain", "-suggest",
        "$towhom_msg\n",
        "to_whom_this_mail_was_addressed.txt", "inline");
}

Now you can redirect bad mails to this user if catched exe, dll, bat, pif-files:

sub filter ($$$$) {
    ...    
    if (filter_bad_filename($entity)) {
        # Send mails to a special spam/virus-recipient
        &redirect_mail_to_mr_spam;

and it it's spam:

sub filter_end ($) {
    ...  
    if ($hits >= $req) { 

        # Send mails to a special spam/virus-recipient
        &redirect_mail_to_mr_spam;
        # Put a record into a database, if you have a "sub log2db"
        &log2db(shortreason=>"spam", reason=>"X-Spam-Score was $hits");

Include F-Prot virusscanner to mimedefang

 Send an EICAR-test-virus as mail like this:

# echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' >/tmp/eicar.txt
# uuencode /tmp/eicar.txt eicar.txt | mail -s "Test eicar" lippmann@zirndorf.de
You will see this in your /var/log/mail.log:
 
Mar 24 16:53:14 mail2 sendmail[6234]: i2OFrDZd006234: from=root, size=169, 
class=0, nrcpts=1, msgid=<200403241553.i2OFrDZd006234@mail2.zdf>,
relay=root@localhost Mar 24 16:53:14 mail2 sm-mta[6236]: i2OFrEZW006236: from=<root@mail2.zdf>,
size=437, class=0, nrcpts=1, msgid=<200403241553.i2OFrDZd006234@mail2.zdf>,
proto=ESMTP, daemon=MSA, relay=mail2 [10.95.81.71] Mar 24 16:53:14 mail2 mimedefang.pl[5972]: i2OFrEZW006236:
Scan '/var/spool/MIMEDefang/mdefang-i2OFrEZW006236/Work'
via F-Protd @10.95.81.71:10200 Mar 24 16:53:14 mail2 mimedefang.pl[5972]: i2OFrEZW006236:
Scan '/var/spool/MIMEDefang/mdefang-i2OFrEZW006236/Work/msg-5972-3.txt'
via F-Protd @10.95.81.71:10200 Mar 24 16:53:14 mail2 fprotd[6238]: Scanner arguments: -dumb -archive -packed -remote-dtd Mar 24 16:53:14 mail2 fprotd[6238]: Scanning file:
/var/spool/MIMEDefang/mdefang-i2OFrEZW006236/Work/msg-5972-3.txt Mar 24 16:53:14 mail2 fprotd[6238]: Detected: EICAR_Test_File Mar 24 16:53:14 mail2 fprotd[6239]: File was infected. Mar 24 16:53:14 mail2 mimedefang.pl[5972]: MDLOG,i2OFrEZW006236,virus,
EICAR_Test_File,10.95.81.71,<root@mail2.zdf>,<lippmann@zirndorf.de>,
Test eicar2 Mar 24 16:53:14 mail2 mimedefang.pl[5972]: filter: i2OFrEZW006236:
discard=1 quarantine=1 Mar 24 16:53:14 mail2 mimedefang[6237]: i2OFrEZW006236:
Discarding because filter instructed us to Mar 24 16:53:14 mail2 sm-mta[6236]: i2OFrEZW006236: Milter: data, discard Mar 24 16:53:14 mail2 sm-mta[6236]: i2OFrEZW006236: discarded
 
Impressum