Wireless Group Policy WLAN Radius Part 3 WLAN Radius Config WLAN Client Config Linksys BEFSR41 Firmware Linksys BEFSR41 101 Linksys WAP54G config More Linksys BEFSR config Security how-to Writing DNS Zonefiles Is ZoneAlarm Spyware? Linksys Wishlist Sendmail spamblock Bind

[netmenu.html]

Privacy Feedback

Using Logwatch with Sendmail

Logwatch is a handy logfile analyzer that comes with RedHat 7.x and 8.x, and it's installed by default. If, for some reason, it isn't installed on your system, it comes in its own rpm (logwatch-2.6-8 comes with RedHat 8.0). 

It's a collection of perl scripts that analyses the log files for a number of services, and creates reports that are easier to read. For Sendmail, it'll tell you how many messages have been transmitted over the report period, list the unknown users, relay attempts, authentication warnings, forward errors and how many messages could not be sent within 4 hours. 

This is all very handy, but with the addition of spam filtering and access databases in Sendmail, it would be nice if it would report on who the bad guys are as well. 

The perl script that analyzes the /var/log/maillog file is located in the /etc/log.d/scripts/services directory. The script itself is called "sendmail" ... The script has two parts, one which reads the log file and collects the necessary information, and one that prints it out. I mention this, as each modification listed below has two parts as well, one for each in the script. 

First, here's the two parts for the unknown users section (included by default), here only for reference:

Part 1:

elsif ( ($User) = ($ThisLine =~ /^[a-zA-Z0-9]+: <([^ ]*)>... User unknown$/) ) {
    $UnknownUsers{$User}++;
}

Part 2:

if (keys %UnknownUsers) {
    print "\n\nUnknown users:\n";
    foreach $ThisOne (keys %UnknownUsers) {
        print " " . $ThisOne . ": " . $UnknownUsers{$ThisOne} . " Times(s)\n";
    }
}

Part 2, with modification to sort list by count

if (keys %UnknownUsers) {
    print "\n\nUnknown users:\n";
    foreach $ThisOne (sort {$UnknownUsers{$b} <=> $UnknownUsers{$a} } keys %UnknownUsers) {
        printf " %-60s %3d Time(s)\n", $ThisOne, $UnknownUsers{$ThisOne};
    }
}

Report on Blackhole list entries.

If you've enabled the blackhole checking in Sendmail (see Using Sendmail to combat spam), then the following addition to the Logwatch sendmail script will list which sites that are blocked because they're on one list or another. The list is sorted, listing the biggest offenders on top.

Part 1

elsif ( ($Domain,$IPAddr) = ($ThisLine =~ /^ruleset=check_relay, arg1=([^ ]*), arg2=([^ ]*), relay=([^,]*), reject=550 5.7.1 Mail from ([^ ]*) rejected*/) ) {
    $Temp = $IPAddr . " (" . $Domain . ")";
    $Blackholed{$Temp}++;
}

Part 2

if (keys %Blackholed) {
    print "\n\nBlackholed servers:\n";
    foreach $ThisOne (sort { $Blackholed{$b} <=> $Blackholed{$a} } keys %Blackholed) {
        printf " %-60s %3d Time(s)\n", $ThisOne, $Blackholed{$ThisOne};
    }
}

Report on Access Denies entries (from use of access database).

If you're using the Access database feature with Sendmail, then the following addition to the script will report which servers in your Access database are attempting to send you mail.

Part 1

elsif ( ($Dest,$Relay) = ($ThisLine =~ /^ruleset=check_mail, arg1=<([^ ]*)>, relay=([^,]*), reject=550 5.7.1 <([^ ]*)>... Access denied/) ) {
    $Temp = $Relay . " (" . $Dest . ")";
    $AccessDenied{$Temp}++;
}

Part 2

if (keys %AccessDenied) {
    print "\n\nAccess denied from:\n";
    foreach $ThisOne (sort { $AccessDenied{$b} <=> $AccessDenied{$a} } keys %AccessDenied) {
        printf " %-60s %3d Time(s)\n", $ThisOne, $AccessDenied{$ThisOne};
    }
}

Report on bad domain names.

Assuming you've taken everyone's advice, you are blocking e-mail from sites that doesn't exist. By adding the following to the sendmail script, you'll get a list of who's attempting to fake it. Since there's two error messages in the sendmail logs to indicate this type of error, there's to if-statements for this one. This is also sorted with the biggest offender on top.

Part 1

elsif ( ($Dest,$Relay) = ($ThisLine =~ /^[a-zA-Z0-9]+: ruleset=check_mail, arg1=<([^ ]*)>, relay=([^,]*), reject=451 4.1.8 Domain of sender*/) ) {
    $Temp = $Dest . " From: " . $Relay;
    $BadDomain{$Temp}++;
}
elsif ( ($Dest,$Relay) = ($ThisLine =~ /^[a-zA-Z0-9]+: ruleset=check_mail, arg1=<([^ ]*)>, relay=([^,]*), reject=553 5.1.8*/) ) {
    $Temp = $Dest . " From: " . $Relay;
    $BadDomain{$Temp}++;
}

Part 2

if (keys %BadDomain) {
    print "\n\nNon-existing or non-resolving domains:\n";
    foreach $ThisOne (sort { $BadDomain{$b} <=> $BadDomain{$a}} keys %BadDomain) {
        printf " %-60s %3d Time(s)\n", $ThisOne, $BadDomain{$ThisOne};
    }
}

Timeouts.

A number of connections simply seems to time out. These shows up with a "did not issues MAIL/EXPN..." error messages. Since it's rather annoying to get all these in the "unmatched" section of the report, you can add the following to the script to get these entries neatly sorted in the report as well.

Part 1

elsif ( ($TimeOut) = ($ThisLine =~ /^[a-zA-Z0-9]+: ([^ ]+) did not issue*/) ) {
    $NoMail{$TimeOut}++;
}

Part 2

if (keys %NoMail) {
    print "\n\nNo Mail connection from:\n";
    foreach $ThisOne (sort { $NoMail{$b} <=> $NoMail{$a}} keys %NoMail) {
        printf " %-60s %3d Time(s)\n", $ThisOne, $NoMail{$ThisOne};
    }
}

There's two other sections of the sendmail script. The first is the "ignore list", which is all the way at the top. Here you can add other entries that shows up in the "unmatched" area of the report that you don't really want to see. The other is the test to see if there is a report. It's a list of "(keys %variable) or" entries just above where the report section is. You should consider adding an entry like that for the variables used in the additions above that you are using (i.e. "(keys %NoMail) or").

Now, to see the fruits of your labor, type this in a console window:

logwatch --service sendmail --range today --print | more

That'll print the report to the console.

I use these reports to add sites to the access database. Sites that repeatedly attempts to relay of my server and servers that continues to connect with fake domain names are prime candidates to end up on the reject list ...

If you're not getting the desired result when using these, it might be because your logfiles are slightly different from mine. What you need to do is check the "unmatched entries" section of the report, and match the pattern matched statements to that. You should be able to figure out how the pattern matching is done by reviewing the ones that are already in the script...

1999, 2000, 2001 Lars M. Hansen