# Blocking spam with an accept list, version 030131 # Info at http://angel.net/~nic/spam-x.html # Modified by fangor @ http://fangor.freeshell.org MY_EMAIL=(email1\@|email2\@) MY_MAIN=user@sdf.lonestar.org MY_NAME="Fangor" # Default values if not taken from message and assigned TO=email1@domain SPAMTO=email1@domain SPAMU=email1 SPAMH=domain SPAMD=gf03.domain # This should be either blank, or a regex that matches the To: headers of any # mailing lists you're on, or ok addresses in To: headers: LISTS=(list1|list2|address1|address2) # This should be a regex that matches all domains from which you know you # won't get spammed but don't want autoreplies: KNOWN_DOMAINS1=(domain1|domain2) # This should be a regex that matches all domains from which you know you # won't get spammed and do want autoreplies: KNOWN_DOMAINS2=(domain3|domain4) # This should be a regex that matches all domains to be trashed TRASH=(domain5|domain6|hotmail\.com) # This should be either blank, or a regex that matches all Subjects that should # be saved before inspection of From SUBJ=(subject1|subject2) # Customize this to change the autoreply sent to messages from addresses # that are not in the accept list AUTOR="Hi, Your message has been received, but it hasn't been delivered to me yet. Since I don't have any record of your sending me mail from this address before, I need to verify that you're not a spammer. Please just hit 'Reply' and send this message back to me without changing the subject line, and your previous message will be delivered, as will all your future messages." AUTORSAL="Thanks, and sorry for the bother," AUTORADD="You may not recognize the email address from which this message is coming. That is because you did not put my email address in the To: or Cc: fields of the message to which this reply is in response. So, I don't know which address you sent it to, and don't want to verify to a spammer that that address is active. If your message was genuine, please just respond to this one and there will be no more delay." # Customize these if they're not right on your system: FORMAIL=/usr/pkg/bin/formail GREP=/usr/bin/grep HEAD=/usr/bin/head SENDMAIL=/usr/sbin/sendmail LS=/bin/ls TR=/usr/bin/tr PROCMAIL=/usr/pkg/bin/procmail # Customize these if you want to put addresses and pending messages elsewhere - # make sure PENDING_DIR exists! DEFAULT=/mail/fangor MAILDIR=$HOME/mail ADDBOOK=$HOME/.addressbook DB=$MAILDIR/.accept-list DENY_DB=$MAILDIR/.deny-list BOUNCE_DB=$MAILDIR/.bounce-list VAC_DB=$MAILDIR/.vac-list JUNK_DB=$MAILDIR/.junk-list FRIEND_DB=$MAILDIR/.friend-list PENDING_DIR=zp ############################## # Be extra careful changing info below here SHELL=/bin/sh PATH COMSAT VERBOSE=off LOGABSTRACT=yes LOGFILE=$MAILDIR/.log/log.`date +%y-%m-%d` # Extract From line from each message and save :0 ch | egrep ^'From ' >> ~/mail/.from # Backup all messages under 25K before processing :0 c * < 25600 .backup :0 ica | cd .backup && rm -f dummy `ls -t msg.* | sed -e 1,64d` # You can mail yourself a request for the list of pending senders :0 * ^Subject: listmessage * $ ^From $MY_MAIN { :0 fbw | $LS -t $PENDING_DIR :0: $DEFAULT } # You can mail yourself to approve an address from the To: line :0 * $ ^From $MY_MAIN * $ ! ^(To|Cc):.*${MY_EMAIL} * ^To: \/[^, ]+ * ? echo $MATCH >> $DB { :0 fw * ? test -e $PENDING_DIR/$MATCH | ( cat $PENDING_DIR/$MATCH || true ) :0 /dev/null } # If message is to a list we're on, or sent to an ok address, then deliver it :0: * LISTS ?? (.) * $ ^TO_$LISTS $DEFAULT # If message is an NDN and a Chicken reply, delete NDN and pending message; # otherwise deliver :0 * MAILER-DAEMON { :0 B * ^Subject: Verify \/[^ ]+ * ? test -e $PENDING_DIR/$MATCH | echo $MATCH >> $JUNK_DB && rm $PENDING_DIR/$MATCH :0: $DEFAULT } # Capture and assign the From address :0 * ^^From \/[^ ]+ { FROM=$MATCH } # Handles mail from known friends, pipe through .procmailrc.friend :0 * ? $GREP -i ^$FROM $FRIEND_DB | $PROCMAIL $MAILDIR/.procmailrc.friend # If Subject matches list then deliver :0: * SUBJ ?? (.) * $ ^Subject:.*$SUBJ $DEFAULT # If message is from a known domain (no autoreplies) then deliver it :0: * KNOWN_DOMAINS1 ?? (.) * $ FROM ?? $KNOWN_DOMAINS1 $DEFAULT # If message is from a known domain (autoreplies) then deliver it :0: * KNOWN_DOMAINS2 ?? (.) * $ FROM ?? $KNOWN_DOMAINS2 $DEFAULT # If message is from a domain we want to ignore then drop it :0 * TRASH ?? (.) * $ FROM ?? $TRASH /dev/null # If message is from someone we want to ignore then drop it :0 h * ? $GREP -i ^$FROM $DENY_DB /dev/null # If message is from a known non-spammer then pipe it through .procmailrc.bc :0 h * ? $GREP -i ^$FROM $BOUNCE_DB | $PROCMAIL $MAILDIR/.procmailrc.bc # Else if message has chicken then register sender and deliver stored messages # Need to fix so multiple messages aren't lost when moved :0 Efw * $ ^Subject:.*Verify.*for.*(${MY_EMAIL}|\"Re: ) * ? echo $FROM >> $DB * ? test -e $PENDING_DIR/$FROM | ( ( cat $PENDING_DIR/$FROM && rm $PENDING_DIR/$FROM ) || true ) # Else if sender isn't in DB then send request for chicken and store message :0 E * $ ! ^X-Loop: ${MY_EMAIL} * $ ! ^FROM_DAEMON * ! ? $GREP -i ^$FROM $DB { :0 c * $ ^(To|Cc):.*\/${MY_EMAIL}[^,> ]+ { TO=$MATCH NAME=$MATCH :0 * ? test ! -e $PENDING_DIR/$FROM | ( $FORMAIL -rt -I"To: $FROM" -I"From: $TO" -A"X-Loop: $TO" -I"Subject: Verify $FROM for $NAME"; echo "$AUTOR"; echo; echo "$AUTORSAL"; echo; echo "$MY_NAME" ) | $SENDMAIL -t } :0 Ec * ? test ! -e $PENDING_DIR/$FROM * $ ^Subject: .*\/.+ | ( $FORMAIL -rt -I"To: $FROM" -I"From: $TO" -A"X-Loop: $TO" -I"Subject: Verify $FROM for \"Re: $MATCH\""; echo "$AUTOR"; echo; echo "$AUTORADD"; echo; echo "$AUTORSAL"; echo; echo "Yours Truly" ) | $SENDMAIL -t :0: $PENDING_DIR/$FROM } #Else deliver normally #Vacation Auto-replier through .procmailrc.vac #:0 #* $ ! ^FROM_DAEMON #* ! ? $GREP -i ^$FROM $VAC_DB #| $PROCMAIL $MAILDIR/.procmailrc.vac # Append in KNOWN_DOMAINS2 and SUBJ for vacation autoreplier #{ # :0 # * ! ^FROM_DAEMON # * ! ? $GREP -i ^$FROM $VAC_DB # | $PROCMAIL $MAILDIR/.procmailrc.vac # # :0: # $DEFAULT #}