#!/bin/bash # # Firewall persistent bozos that sendmail would block anyway via DNSBL or Greet_Pause # (the ones who just don't give up trying to spam us...) # Only block (and tarpit) if they've been rejected by sendmail three times so far. # Also block sites trying to spam mailman administrative addresses if greylisting is in use. # # Since this is based on sendmail logs, a persistent IP will cycle between # this blocklist and being rejected by sendmail. If they are removed from the # DNSBLs that sendmail uses they will eventually be accepted again (in a few days) # by the firewall. # # Intended to be run regularly from /etc/cron.daily or /etc/cron.hourly # # Copyright (C) 2006-2007 John Hardin # $Id: spammer-firewall,v 1.32 2015/01/29 17:21:23 root Exp root $ # Master copy at http://www.impsec.org/~jhardin/antispam/ # Released under the GPL v2 or later # Contact the author for commercial licensing # # If you also install LaBrea, this will tarpit the worst offenders. # LaBrea available at http://sourceforge.net/projects/labrea/ # ** LaBrea patches may be needed! see: # ** http://sourceforge.net/tracker/index.php?func=detail&aid=1612799&group_id=70896&atid=529395 # ** http://sourceforge.net/tracker/index.php?func=detail&aid=1612677&group_id=70896&atid=529393 # ** http://sourceforge.net/tracker/index.php?func=detail&aid=1612818&group_id=70896&atid=529395 # ######## # Assumes the following structure in your base firewall script: # # #----------------------------------------------------------- # # chain to log and discard repetitive spam traffic # /sbin/iptables -N spammer # /sbin/iptables -A spammer -j LOG --log-prefix "Spammer: " # /sbin/iptables -A spammer -j DROP # # #----------------------------------------------------------- # # chain to test inbound email # /sbin/iptables -N flt-smtp # # /sbin/iptables -A INPUT -p tcp --sport 1024:65535 --dport 25 -j flt-smtp # /sbin/iptables -A INPUT -p tcp --sport 1024:65535 --dport 25 -j ACCEPT # ######## /sbin/iptables -F flt-smtp > /var/tmp/spammer_bpf_tmp grep 'AUTH=server, relay=' /var/log/maillog | sed -e 's/^.*relay=[^[]*\[//' -e 's/].*//' | sort | uniq > /var/tmp/authuserips if [ -s /etc/mail/do_not_tarpit_ips ] then cat /etc/mail/do_not_tarpit_ips >> /var/tmp/authuserips fi OR=' and ( src host (' HADDYN=0 # I have observed kernel crashes (!) under joe-job load # if these limits are too large. If your mailserver crashes # unexpectedly, try adjusting these. # Limit size of BPF filter rule for labrea, if desired: # Tarpit up to this many of the worst offenders. # Set to negative to firewall only, no tarpit. BPFCNT=40 # Limit size of firewall list. # add this many more firewall rules after BPF limit is reached. FWCNT=0 ( # My /etc/mail/access explicit rejection rules for spammers include the text "go away" grep 'ruleset=check_rcpt' /var/log/maillog |\ egrep ' (listed at|go away)' |\ sed -e 's/^.* \[//' -e 's/\].*//' # Enable FEATURE(`greet_pause',1000) in sendmail.mc for this grep 'pre-greeting' /var/log/maillog |\ grep -v '\.hotmail\.com ' |\ sed -e 's/^.* \[//' -e 's/\].*//' # Catch mailman admin spammers if you're greylisting. # Adjust the time to match whatever your initial greylist # retry time is set to. # The akst[a-z]{7,25}mnsdgs@ from name format seems to be # pretty consistent with one-shot spams that greylisting # successfully blocks. Let's tarpit them if they keep trying. # Infrequent traffic, look through more logs. zgrep 'delayed for 00:15:00' /var/log/maillog /var/log/maillog.[12].* |\ egrep '(-request|-owner|mailman|akst[a-z]{3,25}mnsdgs)@' |\ grep -v '<>' | uniq |\ awk '{print $8}' # Authentication failures, password brute forcing? # Infrequent traffic, look through more logs, weight double. zgrep 'possible SMTP attack: command=AUTH,' /var/log/maillog /var/log/maillog.[12].* |\ sed -e 's/^.* \[//' -e 's/\].*//' |\ while read IPADDR do echo $IPADDR echo $IPADDR done # Repeated protocol failures - under deliberate attack? #grep 'did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA' /var/log/maillog |\ # sed -e 's/^.* \[//' -e 's/\].*//' # manual host additions - they get ten hits per appearance awk '/^ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1}' /root/smtp_tarpit_ip_list |\ grep -v / |\ while read IPADDR do echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR echo $IPADDR done # Sites rejected by milter (e.g. using malformed HELO (spambots?)) zgrep 'milter-regex' /var/log/messages /var/log/messages.[12].gz |\ grep ' REJECT: ' |\ awk '{print $6}' |\ sed -e 's/://' ) |\ sort |\ uniq -c |\ grep -v ' [123] ' |\ sort -nr |\ while read RANK IPADDR do if grep -q "^${IPADDR}$" /var/tmp/authuserips then continue fi BPFCNT=$((BPFCNT - 1)) if [ "$BPFCNT" -ge 0 ] then /sbin/iptables -A flt-smtp -s "$IPADDR" -j spammer echo -n "$OR" "$IPADDR" >> /var/tmp/spammer_bpf_tmp else FWCNT=$((FWCNT - 1)) if [ "$FWCNT" -ge 0 ] then /sbin/iptables -A flt-smtp -s "$IPADDR" -j spammer fi fi OR=' or' done if grep -q " src host " /var/tmp/spammer_bpf_tmp then HADDYN=1 fi if [ $HADDYN -gt 0 ] then OR=' ) or src net (' else OR=' ) and src net (' fi # manual net additions awk '/^ *[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1}' /root/smtp_tarpit_ip_list |\ grep / |\ sort -u |\ while read IPADDR do /sbin/iptables -A flt-smtp -s "$IPADDR" -j spammer echo -n "$OR" "$IPADDR" >> /var/tmp/spammer_bpf_tmp OR=' or' done rm /var/tmp/authuserips if [ -s "/var/tmp/spammer_bpf_tmp" ] then MYIP=`/sbin/ifconfig eth0 | grep 'inet addr:' | sed -e 's/.*addr://' | awk '{print $1}'` echo -n "dst host ${MYIP}" > /etc/mail/spammer_bpf_new echo -n ' and tcp dst port 25' >> /etc/mail/spammer_bpf_new cat /var/tmp/spammer_bpf_tmp >> /etc/mail/spammer_bpf_new if [ $HADDYN -gt 0 ] then echo -n '))' >> /etc/mail/spammer_bpf_new fi if [ -x /usr/local/bin/labrea ] then if [ -s "/etc/mail/spammer_bpf" ] then if diff /etc/mail/spammer_bpf_new /etc/mail/spammer_bpf > /dev/null then # BPF hasn't changed if ps fax | grep labrea | grep -q /spammer_bpf then # don't restart labrea unnecessarily rm -f /var/tmp/spammer_bpf_tmp exit fi fi fi cp /etc/mail/spammer_bpf_new /etc/mail/spammer_bpf ps fax | grep labrea | grep /spammer_bpf | awk '{print $1}' | xargs --no-run-if-empty kill -15 sleep 1 ps fax | grep labrea | grep /spammer_bpf | awk '{print $1}' | xargs --no-run-if-empty kill -9 ( sleep 10 /bin/nice /usr/local/bin/labrea -z -x -v -P -p 32 -b -F /etc/mail/spammer_bpf ) & fi fi rm -f /var/tmp/spammer_bpf_tmp