#!/bin/sh
# Editado por hellnux (Danillo Costa)
# Fonte: http://daemonforums.org/showthread.php?t=302
version="15.0508"

# Checa um determinado IP se passado como parametro, caso contrario eh
# analisado um faixa de IPs pre determinados.

#####################################################################################
#                               Functions
#####################################################################################

function dateNow () {
        date +%d/%m/%Y" "%k:%M:%S
}

function getIps() {
        # Cria lista de ips
        ips=""
        notes_mail="Faixa de IPs analisadas:\n"
        prefix="162.144.34"
        notes_mail="$notes_mail de 162.144.34.1 até 162.144.34.126 \n"
        for i in `seq 1 126`; do
                ips="$ips $prefix.$i"
        done        
        # Adiciona a lista de ips, os ips de 37.49.226.1 até 37.49.226.62
        prefix="37.49.226"
        notes_mail="$notes_mail de 37.49.226.1 até 37.49.226.62 \n"
        for i in `seq 1 62`; do
                ips="$ips $prefix.$i"
        done 
}

function printResultBase () {
        printf "%-22s %-18s %-30s %-24s %s \n" "$date_now" "$ip" "$reverse_dns" "${BL}" "$result"
}

function printResultSenderbase() {
        date_now=`dateNow`
        BL="senderbase.org"
        # Evita consulta desnecessaria quando o SenderBase tiver bloqueado IP da maquina que executa este script
        if [ "$block_printResultSenderbase" == "1" ]; then
                result="Fail"
                printResultBase
        else
                # Passa pelos Termos de Servicos do SenderBase, method post e pega a saida do lynx
                out=$(echo "tos_accepted=Yes, I Agree" | lynx -dump -post_data "$link_sederbase$ip" | nl -ba)
                if [ $? -eq 0 ]; then
                        if [ "`echo "$out" | grep -F "You don't have permission to access"`" != "" ]; then
                                block_printResultSenderbase="1"
                                result="Fail"
                                printResultBase
                        else
                                # O status do email_reputation costuma estar uma linha antes de "Web Reputation Help" na saida do lynx
                                n_web_reputation=$(echo "$out" | grep -F "Web Reputation Help" | awk '{print $1}')
                                n_email_reputation=$(( $n_web_reputation - 1 ))
                                email_reputation=$(echo "$out" | sed -n "$n_email_reputation"p | awk '{print $2}')
                                if [ "$email_reputation" == "Poor" ]; then
                                        result="<a href=$link_sederbase$ip>Listed</a>"
                                        printResultBase | tee -a "$log_file"
                                else
                                        result="---"
                                        printResultBase
                                fi
                        fi
                else # Metodo antigo. Nao eh tao preciso, pois informa apenas o score. Raramente entre neste trecho
                        BL="rf.senderbase.org"
                        result=$(dig +short txt ${reverse[$i]}.${BL}.)
                        date_now=`dateNow`
                        if [ "`echo "$result" | grep -F "-"`" != "" ]; then
                                score=$(echo "$result" | tr -d '"') 
                                result="<a href=$link_sederbase$ip>NeedCheck</a>:$score" 
                                printResultBase | tee -a "$log_file"
                        else
                                result="---"
                                printResultBase
                        fi
                fi
        fi
}

function printResult() {
        date_now=`dateNow`
        if [ "$result" != "" ]; then
                result="Listed"
                printResultBase | tee -a "$log_file"
        else
                result="---" # Nao listado
                printResultBase
        fi
}

#####################################################################################
#                                       Main
#####################################################################################

# Lista de blacklists. SenderBase eh analisado separadamente
BLISTS="
b.barracudacentral.org
zen.spamhaus.org
xbl.spamhaus.org
pbl.spamhaus.org
bl.spamcop.net
dnsbl.sorbs.net
http.dnsbl.sorbs.net
web.dnsbl.sorbs.net
"

script_name=$(basename $0 .sh)
emails="seu@email.com"
msmtp="/usr/sbin/msmtp"
log_file="/tmp/$script_name.log"
sign_mail="------------------\n$script_name $version" #Assinatura da notificacao via email
link_sederbase="http://www.senderbase.org/lookup/?search_string="
block_printResultSenderbase="0" # disable
msg_printResultSenderbase=""

# Define se usa IP passado via argumento ou "lista de IPs" informadas neste codigo.
if [ "$2" != "" ]; then
        echo "Error: Informe apenas 1 IP ou nenhum para usar a lista pre-determinada."
        exit 1
elif [ "$1" != "" ]; then
        ips="$1"
else
        getIps
fi

# limpa log
> "$log_file"

# Cria IP reverso
i=0
for ip in $ips; do
        reverse[$i]=$(echo "$ip" | sed -ne "s~^\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)$~\4.\3.\2.\1~p")
        if [ "x${reverse[$i]}" = "x" ]; then
                echo "Error: '$ip' nao parece ser um IP valido."
                exit 1
        fi
        (( i++ ))
done

# Faz checagem nas blacklists
i=0
for ip in $ips; do
        #echo "[$ip]" #debug
        reverse_dns=$(dig +short -x "$ip")
        if [ "$reverse_dns" == "" ]; then
                reverse_dns="reverseNull"
        fi
        # Chama funcao printResultSenderbase
        printResultSenderbase
        # Demais blacklists
        for BL in ${BLISTS} ; do
                result="$(dig +short -t a ${reverse[$i]}.${BL}.)"
                printResult
        done
        sleep "$(( ( RANDOM % 10 )  + 5 ))" # Random de ~5s a ~20s
        (( i++ ))
done

# Print in body mail if this script blocked in SenderBase
if [ "$block_printResultSenderbase" == "1" ]; then
        msg_printResultSenderbase="SenderBase blocked the `hostname -i` to queries.\n"
fi

# Send mail - Se identar o echo, pode bugar
if [ "`wc -l "$log_file" | awk '{print $1}'`" != "0" ]; then
echo "To: $emails
From: seu@email.com
Subject: [$script_name]
Content-Type: text/html; charset=\"utf-8\"

<pre>`cat \"$log_file\"`</pre>
<pre>`echo -e \"$msg_printResultSenderbase\"`</pre>
<pre>`echo -e \"$notes_mail\"`</pre>
<pre>`echo -e \"\n\n$sign_mail\"`</pre>" | "$msmtp" --read-recipients
fi

# senderbase
# dig +short txt 55.145.202.186.rf.senderbase.org

# Outras RBL
# combined.njabl.org
# spam.rbl.msrbl.net
# bl.spamcannibal.org
# bl.deadbeef.com
# bl.emailbasura.org
# blackholes.five-ten-sg.com
# bogons.cymru.com
# blacklist.woody.ch
# cbl.abuseat.org
# cdl.anti-spam.org.cn
# combined.abuse.ch
# combined.rbl.msrbl.net
# db.wpbl.info
# dnsbl-1.uceprotect.net
# dnsbl-2.uceprotect.net
# dnsbl-3.uceprotect.net
# dnsbl.ahbl.org
# dnsbl.cyberlogic.net
# dnsbl.inps.de
# dnsbl.njabl.org
# drone.abuse.ch
# drone.abuse.ch
# duinv.aupads.org
# dul.dnsbl.sorbs.net
# dul.ru
# dyna.spamrats.com
# dynip.rothen.com
# images.rbl.msrbl.net
# ips.backscatterer.org
# ix.dnsbl.manitu.net
# korea.services.net
# misc.dnsbl.sorbs.net
# noptr.spamrats.com
# ohps.dnsbl.net.au
# omrs.dnsbl.net.au
# orvedb.aupads.org
# osps.dnsbl.net.au
# osrs.dnsbl.net.au
# owfs.dnsbl.net.au
# owps.dnsbl.net.au
# probes.dnsbl.net.au
# proxy.bl.gweep.ca
# proxy.block.transip.nl
# psbl.surriel.com
# rbl.interserver.net
# rdts.dnsbl.net.au
# relays.bl.gweep.ca
# relays.bl.kundenserver.de
# relays.nether.net
# residential.block.transip.nl
# ricn.dnsbl.net.au
# rmst.dnsbl.net.au
# sbl.spamhaus.org
# short.rbl.jp
# smtp.dnsbl.sorbs.net
# socks.dnsbl.sorbs.net
# spam.abuse.ch
# spam.dnsbl.sorbs.net
# spam.spamrats.com
# spamlist.or.kr
# spamrbl.imp.ch
# t3direct.dnsbl.net.au
# tor.ahbl.org
# tor.dnsbl.sectoor.de
# torserver.tor.dnsbl.sectoor.de
# ubl.lashback.com
# ubl.unsubscore.com
# virbl.bit.nl
# virus.rbl.jp
# virus.rbl.msrbl.net
# wormrbl.imp.ch
# zombie.dnsbl.sorbs.net
# phishing.rbl.msrbl.net

# Fontes de pesquisas
# http://www.redhat.com/archives/rhl-list/2003-December/msg01341.html
# http://h3manth.com/content/methods-submit-form-post-using-curl-perl-python-ruby-lynx
# Numero random em um determinado range pelo shuf
# http://stackoverflow.com/questions/2556190/random-number-from-a-range-in-a-bash-script