Skip to content

Instantly share code, notes, and snippets.

@syci
Created February 19, 2018 21:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syci/193d4d72540285296dedc56ad645034e to your computer and use it in GitHub Desktop.
Save syci/193d4d72540285296dedc56ad645034e to your computer and use it in GitHub Desktop.
Check Server BlackList SMTP
#!/bin/sh
#
# title : blcheck
# description : Test any domain against more then 200 black lists.
# author : Intellex
# contributors : Darko Poljak
# date : 20160117
# version : 0.5.0
# usage : blcheck [options] <domain_or_ip>
#===============================================================================
# Config {
# How many tries and for how long to wait for DNS queries
CONF_DNS_TRIES=2
CONF_DNS_DURATION=3
# Blacklists to check
CONF_BLACKLISTS="
0spam-killlist.fusionzero.com
0spam.fusionzero.com
access.redhawk.org
all.rbl.jp
all.spam-rbl.fr
all.spamrats.com
aspews.ext.sorbs.net
b.barracudacentral.org
backscatter.spameatingmonkey.net
badnets.spameatingmonkey.net
bb.barracudacentral.org
bl.drmx.org
bl.konstant.no
bl.nszones.com
bl.spamcannibal.org
bl.spameatingmonkey.net
bl.spamstinks.com
black.junkemailfilter.com
blackholes.five-ten-sg.com
blacklist.sci.kun.nl
blacklist.woody.ch
bogons.cymru.com
bsb.empty.us
bsb.spamlookup.net
cart00ney.surriel.com
cbl.abuseat.org
cbl.anti-spam.org.cn
cblless.anti-spam.org.cn
cblplus.anti-spam.org.cn
cdl.anti-spam.org.cn
cidr.bl.mcafee.com
combined.rbl.msrbl.net
db.wpbl.info
dev.null.dk
dialups.visi.com
dnsbl-0.uceprotect.net
dnsbl-1.uceprotect.net
dnsbl-2.uceprotect.net
dnsbl-3.uceprotect.net
dnsbl.anticaptcha.net
dnsbl.aspnet.hu
dnsbl.inps.de
dnsbl.justspam.org
dnsbl.kempt.net
dnsbl.madavi.de
dnsbl.rizon.net
dnsbl.rv-soft.info
dnsbl.rymsho.ru
dnsbl.sorbs.net
dnsbl.zapbl.net
dnsrbl.swinog.ch
dul.pacifier.net
dyn.nszones.com
dyna.spamrats.com
fnrbl.fast.net
fresh.spameatingmonkey.net
hostkarma.junkemailfilter.com
images.rbl.msrbl.net
ips.backscatterer.org
ix.dnsbl.manitu.net
korea.services.net
l2.bbfh.ext.sorbs.net
l3.bbfh.ext.sorbs.net
l4.bbfh.ext.sorbs.net
list.bbfh.org
list.blogspambl.com
mail-abuse.blacklist.jippg.org
netbl.spameatingmonkey.net
netscan.rbl.blockedservers.com
no-more-funn.moensted.dk
noptr.spamrats.com
orvedb.aupads.org
pbl.spamhaus.org
phishing.rbl.msrbl.net
pofon.foobar.hu
psbl.surriel.com
rbl.abuse.ro
rbl.blockedservers.com
rbl.dns-servicios.com
rbl.efnet.org
rbl.efnetrbl.org
rbl.iprange.net
rbl.schulte.org
rbl.talkactive.net
rbl2.triumf.ca
rsbl.aupads.org
sbl-xbl.spamhaus.org
sbl.nszones.com
sbl.spamhaus.org
short.rbl.jp
spam.dnsbl.anonmails.de
spam.pedantic.org
spam.rbl.blockedservers.com
spam.rbl.msrbl.net
spam.spamrats.com
spamrbl.imp.ch
spamsources.fabel.dk
st.technovision.dk
tor.dan.me.uk
tor.dnsbl.sectoor.de
tor.efnet.org
torexit.dan.me.uk
truncate.gbudb.net
ubl.unsubscore.com
uribl.spameatingmonkey.net
urired.spameatingmonkey.net
virbl.dnsbl.bit.nl
virus.rbl.jp
virus.rbl.msrbl.net
vote.drbl.caravan.ru
vote.drbl.gremlin.ru
web.rbl.msrbl.net
work.drbl.caravan.ru
work.drbl.gremlin.ru
wormrbl.imp.ch
xbl.spamhaus.org
zen.spamhaus.org"
#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ }
# Definitions {
# Common regular expresions
REGEX_IP='\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)\.\([0-9]\{1,3\}\)'
REGEX_DOMAIN='\([a-zA-Z0-9]\+\(-[a-zA-Z0-9]\+\)*\.\)\+[a-zA-Z]\{2,\}'
REGEX_TDL='\([a-zA-Z0-9]\+\(-[a-zA-Z0-9]\+\)*\.\)[a-zA-Z]\{2,\}$'
# Colors
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
CLEAR=$(tput sgr0)
# Define spinner
SPINNER="-\|/"
#SPINNER=".oO@*"
#SPINNER="▉▊▋▌▍▎▏▎▍▌▋▊▉"
#SPINNER="←↖↑↗→↘↓↙"
#SPINNER="▁▂▃▄▅▆▇█▇▆▅▄▃▁"
#SPINNER="▖▘▝▗"
#SPINNER="┤┘┴└├┌┬┐"
#SPINNER="◢◣◤◥"
#SPINNER="◰◳◲◱"
#SPINNER="◴◷◶◵"
#SPINNER="◐◓◑◒"
#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ }
# Macros {
# Verbose printing
VERBOSE=0
info() {
if [ $VERBOSE -ge "$1" ]; then
echo "$2"
fi
}
# Error handling
error() {
echo "ERROR: $1" >&2
exit 2
}
# Show progres
progress() {
# Bar
x=$(($1 % ${#SPINNER} + 1))
BAR=$(echo $SPINNER | awk "{ print substr(\$0, ${x}, 1) }")
if test -z "$PLAIN"; then
printf "\r ";
fi
# BAR as printf arg so that backslash will be litteraly interpreted
printf "[ %s %3s%% ] checking... %4s / $2 " "$BAR" $(($1 * 100 / $2)) "$1";
}
# Resolve the IP
resolve() {
# IP already?
IP=$(echo "$1" | grep "^$REGEX_IP$")
if [ "$IP" ]; then
echo "$IP"
# Resolve domain
else
# Handle special resolve types
case "$2" in
"ns" ) TYPE="ns"; REGEX="$REGEX_DOMAIN\.$";;
* ) TYPE="a"; REGEX="$REGEX_IP$";;
esac
case "$CMD" in
$CMD_DIG ) "$CMD" +short -t "$TYPE" +time=$CONF_DNS_DURATION +tries=$CONF_DNS_TRIES "$1" | grep -om 1 "$REGEX";;
$CMD_HOST ) "$CMD" -t "$TYPE" -W $CONF_DNS_DURATION -R $CONF_DNS_TRIES "$1" | grep -om 1 "$REGEX";;
esac
fi
}
# Load the blacklist from file
loadBlacklists() {
# Make sure the file is readable
if [ ! "$1" ]; then
error "Option -l requires an additional parameter";
elif [ ! -r $1 ]; then
error "File $1 cannot be opened for reading, make sure it exists and that you have appropriate privileges"
fi
CONF_BLACKLISTS=$(cat "$1")
}
# Show help
help() {
cat <<HELP
blcheck [options] <domain_or_IP>
Supplied domain must be full qualified domain name.
If the IP is supplied, the PTR check cannot be executed and will be skipped.
-l file Load blacklists from file, separated by space or new line
-c Warn if the top level domain of the blacklist has expired
-v Verbose mode, can be used multiple times (up to -vvv)
-q Quiet modem with absolutely no output (useful for scripts)
-p Plain text output (no coloring, no interactive status)
-h The help you are just reading
Result of the script is the number of blacklisted entries. So if the supplied
IP is not blacklisted on any of the servers the result is 0.
HELP
exit;
}
#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ }
# Parse the params
while getopts :vqphcl: arg; do
case "$arg" in
l) loadBlacklists $OPTARG;;
c) VERIFY_BL=TRUE;;
v) VERBOSE=$(( (VERBOSE + 1) % 4));;
q) VERBOSE=-1;;
p) PLAIN=1 RED="" GREEN="" YELLOW="" CLEAR="" ;;
h) help;;
?) error "Unknown option $OPTARG";;
esac
done
shift $((OPTIND - 1))
# Get the domain
if [ $# -eq 0 ]; then
echo "Missing target domain or IP."
help
fi
TARGET=$1
# Get the command we will use: dig or host
CMD_DIG=$(which dig)
CMD_HOST=$(which host)
if [ "$CMD_DIG" ]; then
CMD=$CMD_DIG
elif [ "$CMD_HOST" ]; then
CMD=$CMD_HOST
fi
if [ ! "$CMD" ]; then
error "Either dig or host command is required."
fi
info 3 "Using $CMD to reslove DNS queries"
# Parse IP
IP=$(resolve "$TARGET")
if [ ! "$IP" ]; then
error "No DNS record found for $TARGET"
elif [ "$IP" != "$TARGET" ]; then
DOMAIN=$TARGET
info 2 "Using $TARGET for target, resolved to $IP"
else
info 3 "Using $TARGET for target"
fi
# Reverse the IP
REVERSED=$(echo "$IP" | sed -ne "s~^$REGEX_IP$~\4.\3.\2.\1~p")
info 3 "Using $REVERSED for reversed IP"
# Get the PTR
info 3 "Checking the PTR record"
case "$CMD" in
$CMD_DIG ) PTR=$("$CMD" +short -x "$IP" | sed s/\.$//);;
$CMD_HOST ) PTR=$("$CMD" "$IP" | grep -o '[^ ]\+$' | sed s/\.$//)
esac
# Validate PTR
if [ ! "$PTR" ]; then
info 0 "${YELLOW}Warning: PTR lookup failed${CLEAR}"
else
# Match against supplied domain
info 1 "PTR resolves to $PTR"
if [ "$DOMAIN" ]; then
if [ "$DOMAIN" != "$PTR" ]; then
info 0 "${YELLOW}Warning: PTR record does not match supplied domain: $TARGET != $PTR${CLEAR}"
else
info 1 "${GREEN}PTR record matches supplied domain $PTR${CLEAR}"
fi
fi
fi
# Filter out the blacklists
BLACKLISTS=""
for BL in $CONF_BLACKLISTS; do
if [ "$BL" ]; then
# Make sure the domain is a proper one
DOMAIN=$(echo "$BL" | sed -e 's/^[ \t]*//' | grep ^"$REGEX_DOMAIN"$)
if [ ! "$DOMAIN" ]; then
info 0 "${YELLOW}Warning: blacklist '$BL' is not valid and will be ignored${CLEAR}"
else
# It is a proper blacklist
if [ "$BLACKLISTS" ]; then
BLACKLISTS=$(echo -e "$BLACKLISTS\n$DOMAIN")
else
BLACKLISTS="$BL"
fi
fi
fi
done
# Make sure we have at least one blacklist
COUNT=$(($(echo "$BLACKLISTS" | wc -l)))
if [ ! "$BLACKLISTS" ] || [ "$COUNT" -eq 0 ]; then
error "No blacklists have been specified"
fi
info 1 "Matching against $COUNT blacklists"
# Initialize the counters
INVALID=0
PASSED=0
FAILED=0
# Interate over all blacklists
I=0;
for BL in $BLACKLISTS; do
PREFIX=
I=$((I + 1))
# What should we test
TEST="$REVERSED.$BL."
# Make sure the info is shown if we are cheking the servers
if [ "$VERIFY_BL" ] && [ $VERBOSE -lt 1 ]; then
VERBOSE=1
fi
# For verbose output
if [ $VERBOSE -ge 1 ]; then
# Show percentage
STATUS=$(printf " %3s" $((I * 100 / COUNT)))
STATUS="$STATUS%% "
# Show additional info
if [ $VERBOSE -ge 3 ]; then
PREFIX=$(printf "%-60s" "$TEST")
else
PREFIX=$(printf "%-50s" "$BL")
fi
PREFIX="$STATUS $PREFIX"
if test -z "$PLAIN"; then
printf "%s \b" "$PREFIX"
fi
elif [ $VERBOSE -ge 0 ]; then
if test -z "$PLAIN"; then
progress "$I" "$COUNT"
fi
fi
# Get the status
RESPONSE=$(resolve "$TEST")
START=$(echo "$RESPONSE" | cut -c1-4)
# Not blacklisted
if [ ! "$RESPONSE" ]; then
# Make sure the server is viable
ERROR=""
if [ "$VERIFY_BL" ]; then
TDL=$(echo "$BL" | grep -om 1 '\([a-zA-Z0-9]\+\(-[a-zA-Z0-9]\+\)*\.\)[a-zA-Z]\{2,\}$')
if [ ! "$(resolve "$TDL" ns)" ]; then
if test -z "$PLAIN"; then printf "\r"; fi
printf "%s%sUnreachable server%s\n" "$YELLOW" "$PREFIX" "$CLEAR";
INVALID=$((INVALID + 1))
ERROR=TRUE
fi
fi
if [ ! "$ERROR" ]; then
if [ "$VERIFY_BL" ] || [ $VERBOSE -ge 1 ]; then
if test -z "$PLAIN"; then printf "\r"; fi
printf "%s%s✓%s\n" "$CLEAR" "$PREFIX" "$CLEAR";
fi
PASSED=$((PASSED + 1))
fi;
# Invalid response
elif [ "$START" != "127." ]; then
if [ $VERBOSE -ge 1 ]; then
if test -z "$PLAIN"; then printf "\r"; fi
printf "%s%sinvalid response (%s)%s\n" "$YELLOW" "$PREFIX" "$RESPONSE" "$CLEAR";
fi;
INVALID=$((INVALID + 1))
# Blacklisted
else
if [ $VERBOSE -ge 1 ]; then
if test -z "$PLAIN"; then printf "\r"; fi
printf "%s%sblacklisted (%s)%s\n" "$RED" "$PREFIX" "$RESPONSE" "$CLEAR";
elif [ $VERBOSE -ge 0 ]; then
if test -z "$PLAIN"; then printf "\r "; printf "\r"; fi
printf "%s%s%s : %s\n" "$RED" "$BL" "$CLEAR" "$RESPONSE"
fi
FAILED=$((FAILED + 1))
fi
done
# Print results
if [ $VERBOSE -ge 0 ]; then
if test -z "$PLAIN"; then
printf "\r \n"
else
printf " \n"
fi
echo "----------------------------------------------------------"
echo Results for "$TARGET"
echo
printf "%-15s" "Tested:"; echo "${COUNT}"
printf "%-15s" "Passed:"; echo "${GREEN}${PASSED}${CLEAR}"
printf "%-15s" "Invalid:"; echo "${YELLOW}${INVALID}${CLEAR}"
printf "%-15s" "Blacklisted:"; echo "${RED}${FAILED}${CLEAR}"
echo "----------------------------------------------------------"
fi
exit $FAILED;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment