#!/usr/bin/perl -wT # Add spammers to the badmailfrom list (qmail utility) # Copyright (c) 1999, 2001 by Andrew Pam # v0.1 24 Feb 1999 by Andrew Pam # v0.2 25 Feb 1999 by Andrew Pam # v0.3 26 Feb 1999 by Andrew Pam # v0.9 08 Mar 1999 by Andrew Pam # v1.0 09 Mar 1999 by Andrew Pam # v1.1 31 Aug 1999 by Andrew Pam # v1.2 08 Sep 1999 by Andrew Pam # v1.3 08 Mar 2001 by Andrew Pam # SCRIPT DEPRECATED - PLEASE DO NOT USE # As a system administrator or postmaster, do you get a lot of spam # addressed to invalid email addresses within your domain(s) that # double-bounces because it can't be returned to the spammer? # # Maybe this script can help. If you set up qmail aliases to run this # script for the invalid addresses, email to those addresses will # automatically add the envelope sender to the badmailfrom file, # ensuring that qmail doesn't even accept emails from that sender again. # Since the invalid addresses often seem to come from some sort of # "bulk mail list", this will often help prevent spam addressed to valid # addresses in your domain(s) as well! # # See "man dot-qmail" for information on setting up qmail aliases. # # You can also resend (bounce, not forward!) spam to this script # and it will add the From: sender of the message to the badmailfrom # file, since the envelope sender is in one of your own domain(s). # Because email can easily be forged, this script will never add # addresses within your own domains(s) as listed in the rcpthosts file # and will always notify you when it has added an entry. # # 2003 update: PLEASE DO NOT USE THIS SCRIPT. With changes in the way # spammers send their emails in the last couple of years this script is not # only ineffective now but can also potentially result in blocking email # from legitimate senders whose addresses have been forged by spammers. # # Share and enjoy, # *** Xanni *** exit; use strict; my $FALSE = 0; my $TRUE = not $FALSE; my $CONTROL = "/var/qmail/control"; $ENV{ENV} = ""; $ENV{PATH} = "/bin:/usr/bin:/usr/local/bin"; # Exit with "delivery failed" status sub fatal($) { warn $_[0]; exit 100; } # Helper subroutine to check if an address matches a domain in rcpthosts sub inrcpthosts($) { my $address = shift; if (open(RCPTHOSTS, "$CONTROL/rcpthosts")) { while () { chomp; return $TRUE if ($address =~ /\Q$_\E$/i); } close(RCPTHOSTS); } return $FALSE; } # First, check whether the envelope sender is "one of us" fatal("Must be executed by qmail, sorry.\n") unless defined $ENV{SENDER}; my $sender = $ENV{SENDER} or fatal("No envelope sender.\n"); my $local = inrcpthosts($sender); my $from; if (not $local and ($sender ne "#@[]")) { $from = $sender; } else { # Find the From: header while (<>) { if (/^From: .*\b(\S+\@[\w\.]+)\b/) { $from = $1; last; } } fatal("Sorry, can't find a valid From: header.\n") unless $from; fatal("Hey! <$from> is one of our addresses!\n") if inrcpthosts($from); } # Some addresses are special if ($from =~ /^(MAILER-DAEMON\@)|(postmaster\@)|(root\@)|(owner-)|(bounces-)/i) { fatal("Return to sender, address unknown.\n"); } # Now see if this entry already exists # Note: the badmailfrom file should probably be locked first if (open(BMF, "$CONTROL/badmailfrom")) { while () { chomp; exit 0 if $from =~ /\Q$_\E$/; } close(BMF); } # Guess not - so let's go ahead and append the address # Note: the badmailfrom file should be unlocked afterwards open(BMF, ">>$CONTROL/badmailfrom") or die("Can't append to $CONTROL/badmailfrom: $!\n"); print BMF "$from\n"; close(BMF); # Finally, someone must be notified (important in case of forgery!) $sender = "postmaster" unless $local; open(REPLY, "|qmail-inject") or die("Can't run qmail-inject: $!\n"); print REPLY "From: postmaster\nTo: $sender\nSubject: Anti-spam\n\n"; print REPLY "As a result of an email to <$ENV{RECIPIENT}>,\n"; print REPLY "<$from> was added to the badmailfrom control file.\n"; close(REPLY); exit 0;