mirror of https://github.com/tLDP/LDP
281 lines
8.9 KiB
Bash
281 lines
8.9 KiB
Bash
#!/bin/bash
|
|
# whx.sh: "whois" spammer lookup
|
|
# Author: Walter Dnes
|
|
# Slight revisions (first section) by ABS Guide author.
|
|
# Used in ABS Guide with permission.
|
|
|
|
# Needs version 3.x or greater of Bash to run (because of =~ operator).
|
|
# Commented by script author and ABS Guide author.
|
|
|
|
|
|
|
|
E_BADARGS=85 # Missing command-line arg.
|
|
E_NOHOST=86 # Host not found.
|
|
E_TIMEOUT=87 # Host lookup timed out.
|
|
E_UNDEF=88 # Some other (undefined) error.
|
|
|
|
HOSTWAIT=10 # Specify up to 10 seconds for host query reply.
|
|
# The actual wait may be a bit longer.
|
|
OUTFILE=whois.txt # Output file.
|
|
PORT=4321
|
|
|
|
|
|
if [ -z "$1" ] # Check for (required) command-line arg.
|
|
then
|
|
echo "Usage: $0 domain name or IP address"
|
|
exit $E_BADARGS
|
|
fi
|
|
|
|
|
|
if [[ "$1" =~ [a-zA-Z][a-zA-Z]$ ]] # Ends in two alpha chars?
|
|
then # It's a domain name &&
|
|
#+ must do host lookup.
|
|
IPADDR=$(host -W $HOSTWAIT $1 | awk '{print $4}')
|
|
# Doing host lookup
|
|
#+ to get IP address.
|
|
# Extract final field.
|
|
else
|
|
IPADDR="$1" # Command-line arg was IP address.
|
|
fi
|
|
|
|
echo; echo "IP Address is: "$IPADDR""; echo
|
|
|
|
if [ -e "$OUTFILE" ]
|
|
then
|
|
rm -f "$OUTFILE"
|
|
echo "Stale output file \"$OUTFILE\" removed."; echo
|
|
fi
|
|
|
|
|
|
# Sanity checks.
|
|
# (This section needs more work.)
|
|
# ===============================
|
|
if [ -z "$IPADDR" ]
|
|
# No response.
|
|
then
|
|
echo "Host not found!"
|
|
exit $E_NOHOST # Bail out.
|
|
fi
|
|
|
|
if [[ "$IPADDR" =~ ^[;;] ]]
|
|
# ;; Connection timed out; no servers could be reached.
|
|
then
|
|
echo "Host lookup timed out!"
|
|
exit $E_TIMEOUT # Bail out.
|
|
fi
|
|
|
|
if [[ "$IPADDR" =~ [(NXDOMAIN)]$ ]]
|
|
# Host xxxxxxxxx.xxx not found: 3(NXDOMAIN)
|
|
then
|
|
echo "Host not found!"
|
|
exit $E_NOHOST # Bail out.
|
|
fi
|
|
|
|
if [[ "$IPADDR" =~ [(SERVFAIL)]$ ]]
|
|
# Host xxxxxxxxx.xxx not found: 2(SERVFAIL)
|
|
then
|
|
echo "Host not found!"
|
|
exit $E_NOHOST # Bail out.
|
|
fi
|
|
|
|
|
|
|
|
|
|
# ======================== Main body of script ========================
|
|
|
|
AFRINICquery() {
|
|
# Define the function that queries AFRINIC. Echo a notification to the
|
|
#+ screen, and then run the actual query, redirecting output to $OUTFILE.
|
|
|
|
echo "Searching for $IPADDR in whois.afrinic.net"
|
|
whois -h whois.afrinic.net "$IPADDR" > $OUTFILE
|
|
|
|
# Check for presence of reference to an rwhois.
|
|
# Warn about non-functional rwhois.infosat.net server
|
|
#+ and attempt rwhois query.
|
|
if grep -e "^remarks: .*rwhois\.[^ ]\+" "$OUTFILE"
|
|
then
|
|
echo " " >> $OUTFILE
|
|
echo "***" >> $OUTFILE
|
|
echo "***" >> $OUTFILE
|
|
echo "Warning: rwhois.infosat.net was not working \
|
|
as of 2005/02/02" >> $OUTFILE
|
|
echo " when this script was written." >> $OUTFILE
|
|
echo "***" >> $OUTFILE
|
|
echo "***" >> $OUTFILE
|
|
echo " " >> $OUTFILE
|
|
RWHOIS=`grep "^remarks: .*rwhois\.[^ ]\+" "$OUTFILE" | tail -n 1 |\
|
|
sed "s/\(^.*\)\(rwhois\..*\)\(:4.*\)/\2/"`
|
|
whois -h ${RWHOIS}:${PORT} "$IPADDR" >> $OUTFILE
|
|
fi
|
|
}
|
|
|
|
APNICquery() {
|
|
echo "Searching for $IPADDR in whois.apnic.net"
|
|
whois -h whois.apnic.net "$IPADDR" > $OUTFILE
|
|
|
|
# Just about every country has its own internet registrar.
|
|
# I don't normally bother consulting them, because the regional registry
|
|
#+ usually supplies sufficient information.
|
|
# There are a few exceptions, where the regional registry simply
|
|
#+ refers to the national registry for direct data.
|
|
# These are Japan and South Korea in APNIC, and Brasil in LACNIC.
|
|
# The following if statement checks $OUTFILE (whois.txt) for the presence
|
|
#+ of "KR" (South Korea) or "JP" (Japan) in the country field.
|
|
# If either is found, the query is re-run against the appropriate
|
|
#+ national registry.
|
|
|
|
if grep -E "^country:[ ]+KR$" "$OUTFILE"
|
|
then
|
|
echo "Searching for $IPADDR in whois.krnic.net"
|
|
whois -h whois.krnic.net "$IPADDR" >> $OUTFILE
|
|
elif grep -E "^country:[ ]+JP$" "$OUTFILE"
|
|
then
|
|
echo "Searching for $IPADDR in whois.nic.ad.jp"
|
|
whois -h whois.nic.ad.jp "$IPADDR"/e >> $OUTFILE
|
|
fi
|
|
}
|
|
|
|
ARINquery() {
|
|
echo "Searching for $IPADDR in whois.arin.net"
|
|
whois -h whois.arin.net "$IPADDR" > $OUTFILE
|
|
|
|
# Several large internet providers listed by ARIN have their own
|
|
#+ internal whois service, referred to as "rwhois".
|
|
# A large block of IP addresses is listed with the provider
|
|
#+ under the ARIN registry.
|
|
# To get the IP addresses of 2nd-level ISPs or other large customers,
|
|
#+ one has to refer to the rwhois server on port 4321.
|
|
# I originally started with a bunch of "if" statements checking for
|
|
#+ the larger providers.
|
|
# This approach is unwieldy, and there's always another rwhois server
|
|
#+ that I didn't know about.
|
|
# A more elegant approach is to check $OUTFILE for a reference
|
|
#+ to a whois server, parse that server name out of the comment section,
|
|
#+ and re-run the query against the appropriate rwhois server.
|
|
# The parsing looks a bit ugly, with a long continued line inside
|
|
#+ backticks.
|
|
# But it only has to be done once, and will work as new servers are added.
|
|
#@ ABS Guide author comment: it isn't all that ugly, and is, in fact,
|
|
#@+ an instructive use of Regular Expressions.
|
|
|
|
if grep -E "^Comment: .*rwhois.[^ ]+" "$OUTFILE"
|
|
then
|
|
RWHOIS=`grep -e "^Comment:.*rwhois\.[^ ]\+" "$OUTFILE" | tail -n 1 |\
|
|
sed "s/^\(.*\)\(rwhois\.[^ ]\+\)\(.*$\)/\2/"`
|
|
echo "Searching for $IPADDR in ${RWHOIS}"
|
|
whois -h ${RWHOIS}:${PORT} "$IPADDR" >> $OUTFILE
|
|
fi
|
|
}
|
|
|
|
LACNICquery() {
|
|
echo "Searching for $IPADDR in whois.lacnic.net"
|
|
whois -h whois.lacnic.net "$IPADDR" > $OUTFILE
|
|
|
|
# The following if statement checks $OUTFILE (whois.txt) for
|
|
#+ the presence of "BR" (Brasil) in the country field.
|
|
# If it is found, the query is re-run against whois.registro.br.
|
|
|
|
if grep -E "^country:[ ]+BR$" "$OUTFILE"
|
|
then
|
|
echo "Searching for $IPADDR in whois.registro.br"
|
|
whois -h whois.registro.br "$IPADDR" >> $OUTFILE
|
|
fi
|
|
}
|
|
|
|
RIPEquery() {
|
|
echo "Searching for $IPADDR in whois.ripe.net"
|
|
whois -h whois.ripe.net "$IPADDR" > $OUTFILE
|
|
}
|
|
|
|
# Initialize a few variables.
|
|
# * slash8 is the most significant octet
|
|
# * slash16 consists of the two most significant octets
|
|
# * octet2 is the second most significant octet
|
|
|
|
|
|
|
|
|
|
slash8=`echo $IPADDR | cut -d. -f 1`
|
|
if [ -z "$slash8" ] # Yet another sanity check.
|
|
then
|
|
echo "Undefined error!"
|
|
exit $E_UNDEF
|
|
fi
|
|
slash16=`echo $IPADDR | cut -d. -f 1-2`
|
|
# ^ Period specified as 'cut" delimiter.
|
|
if [ -z "$slash16" ]
|
|
then
|
|
echo "Undefined error!"
|
|
exit $E_UNDEF
|
|
fi
|
|
octet2=`echo $slash16 | cut -d. -f 2`
|
|
if [ -z "$octet2" ]
|
|
then
|
|
echo "Undefined error!"
|
|
exit $E_UNDEF
|
|
fi
|
|
|
|
|
|
# Check for various odds and ends of reserved space.
|
|
# There is no point in querying for those addresses.
|
|
|
|
if [ $slash8 == 0 ]; then
|
|
echo $IPADDR is '"This Network"' space\; Not querying
|
|
elif [ $slash8 == 10 ]; then
|
|
echo $IPADDR is RFC1918 space\; Not querying
|
|
elif [ $slash8 == 14 ]; then
|
|
echo $IPADDR is '"Public Data Network"' space\; Not querying
|
|
elif [ $slash8 == 127 ]; then
|
|
echo $IPADDR is loopback space\; Not querying
|
|
elif [ $slash16 == 169.254 ]; then
|
|
echo $IPADDR is link-local space\; Not querying
|
|
elif [ $slash8 == 172 ] && [ $octet2 -ge 16 ] && [ $octet2 -le 31 ];then
|
|
echo $IPADDR is RFC1918 space\; Not querying
|
|
elif [ $slash16 == 192.168 ]; then
|
|
echo $IPADDR is RFC1918 space\; Not querying
|
|
elif [ $slash8 -ge 224 ]; then
|
|
echo $IPADDR is either Multicast or reserved space\; Not querying
|
|
elif [ $slash8 -ge 200 ] && [ $slash8 -le 201 ]; then LACNICquery "$IPADDR"
|
|
elif [ $slash8 -ge 202 ] && [ $slash8 -le 203 ]; then APNICquery "$IPADDR"
|
|
elif [ $slash8 -ge 210 ] && [ $slash8 -le 211 ]; then APNICquery "$IPADDR"
|
|
elif [ $slash8 -ge 218 ] && [ $slash8 -le 223 ]; then APNICquery "$IPADDR"
|
|
|
|
# If we got this far without making a decision, query ARIN.
|
|
# If a reference is found in $OUTFILE to APNIC, AFRINIC, LACNIC, or RIPE,
|
|
#+ query the appropriate whois server.
|
|
|
|
else
|
|
ARINquery "$IPADDR"
|
|
if grep "whois.afrinic.net" "$OUTFILE"; then
|
|
AFRINICquery "$IPADDR"
|
|
elif grep -E "^OrgID:[ ]+RIPE$" "$OUTFILE"; then
|
|
RIPEquery "$IPADDR"
|
|
elif grep -E "^OrgID:[ ]+APNIC$" "$OUTFILE"; then
|
|
APNICquery "$IPADDR"
|
|
elif grep -E "^OrgID:[ ]+LACNIC$" "$OUTFILE"; then
|
|
LACNICquery "$IPADDR"
|
|
fi
|
|
fi
|
|
|
|
#@ ---------------------------------------------------------------
|
|
# Try also:
|
|
# wget http://logi.cc/nw/whois.php3?ACTION=doQuery&DOMAIN=$IPADDR
|
|
#@ ---------------------------------------------------------------
|
|
|
|
# We've now finished the querying.
|
|
# Echo a copy of the final result to the screen.
|
|
|
|
cat $OUTFILE
|
|
# Or "less $OUTFILE" . . .
|
|
|
|
|
|
exit 0
|
|
|
|
#@ ABS Guide author comments:
|
|
#@ Nothing fancy here, but still a very useful tool for hunting spammers.
|
|
#@ Sure, the script can be cleaned up some, and it's still a bit buggy,
|
|
#@+ (exercise for reader), but all the same, it's a nice piece of coding
|
|
#@+ by Walter Dnes.
|
|
#@ Thank you!
|