97 lines
3.5 KiB
Bash
97 lines
3.5 KiB
Bash
#!/bin/bash
|
|
#################################################################################
|
|
## checkdnsbl.sh by rojo (rojo @ headcandy.org) and
|
|
## outsider (outsider @ scarynet.org) and
|
|
## remco (remco @ webconquest.com)
|
|
##
|
|
## LICENSE AGREEMENT
|
|
## By using this script, you are implying acceptance of the idea that this script
|
|
## is a stimulating piece of prose. As such, PLEASE DO NOT PLAGIARIZE IT. As
|
|
## long as you give me credit for my work, feel free to redistribute / make a
|
|
## profit / rewrite / whatever you wish to the script. Just don't mess it up
|
|
## and pretend that the bug was my fault. My code is bug-free, dammit!
|
|
##
|
|
## syntax: /usr/local/sbin/checkdnsbl.sh ip_addr
|
|
## where ip_addr is a valid four-octet IPv4 address
|
|
## * exits 0 if a match is found; exits 1 for no match
|
|
## * intended to be called from /etc/hosts.deny via aclexec
|
|
##
|
|
## example hosts.deny:
|
|
#
|
|
# sshd : 10.0.0.0/24, 127.0.0.1 : allow
|
|
# ALL : 192.168.0.0/32 : deny
|
|
# ALL EXCEPT httpd : ALL : aclexec /usr/local/sbin/checkdnsbl %a
|
|
#
|
|
## This will deny connections from DNSBL-flagged hosts, and assume the rest are
|
|
## safe. MAKE SURE THAT THIS SCRIPT IS RUN AFTER ALL EXPLICITLY DEFINED
|
|
## ADDRESSES! After tcpwrappers spawns this script, the connection is either
|
|
## passed or failed, with no further rule matching.
|
|
##
|
|
## As of the writing of this script, aclexec in hosts.allow allows every client
|
|
## to connect, regardless of returned exit code. This script will NOT work if
|
|
## called from hosts.allow. It should only be called from hosts.deny.
|
|
##
|
|
## To test whether this script works, try binding to a banned address. Both
|
|
## dronebl.org and spamhaus.org, for example, include 127.0.0.2 in their
|
|
## databases for testing. So, if this script monitors ssh connections, and such
|
|
## a service exists in your array of DNSBL hosts, try the following command:
|
|
# ssh -o BindAddress=127.0.0.2 localhost
|
|
## If all works as intended, you should see "ssh_exchange_identification:
|
|
## Connection closed by remote host." And so will other blacklisted clients.
|
|
#################################################################################
|
|
|
|
# DNSBL[x] -- array of DNSBL hosts to query
|
|
DNSBL[0]="dnsbl.dronebl.org"
|
|
DNSBL[1]="rbl.efnetrbl.org"
|
|
DNSBL[2]="dnsbl.swiftbl.net"
|
|
DNSBL[3]="combined.abuse.ch"
|
|
DNSBL[4]="bogons.cymru.com"
|
|
|
|
|
|
# Number of minutes to cache queries
|
|
QUERY_EXPIRE=5
|
|
|
|
# Location for cache
|
|
CACHE_FOLDER="/tmp/checkdnsbl"
|
|
|
|
# UMASK value for created files and directory
|
|
UMASK="077"
|
|
|
|
################################# stop editing ##################################
|
|
|
|
IPADDR=`echo $1 | sed -r -e 's/^::ffff://'`
|
|
IP_BACKWARD=`host $IPADDR|grep -E -o -e '[0-9a-f\.]+\.(in-addr|ip6)\.arpa'|sed -r -e 's/\.i.+$//'`
|
|
|
|
umask $UMASK
|
|
|
|
if [ ! -d "$CACHE_FOLDER" ]; then mkdir $CACHE_FOLDER;
|
|
elif [ -f "$CACHE_FOLDER/$IPADDR-0" ]; then {
|
|
echo CACHED: $IPADDR found in `cat $CACHE_FOLDER/$IPADDR-0`
|
|
exit 0
|
|
};
|
|
elif [ -f "$CACHE_FOLDER/$IPADDR-1" ]; then {
|
|
echo CACHED: $IPADDR not found in any DNSBLs.
|
|
exit 1
|
|
}; fi
|
|
|
|
for (( x=0; x<${#DNSBL[@]}; x++ )); do {
|
|
DNSBLQUERY=$IP_BACKWARD.${DNSBL[$x]}
|
|
echo -n "checking $DNSBLQUERY... "
|
|
DNSBLOUT=`host $DNSBLQUERY | grep -E -o -e '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$'`
|
|
if [ "$DNSBLOUT" != "" ]; then
|
|
echo "MATCH: $DNSBLOUT"
|
|
echo "${DNSBL[$x]} : $DNSBLOUT" >>$CACHE_FOLDER/$IPADDR-0
|
|
sleep $(( $QUERY_EXPIRE * 60 )) && {
|
|
rm -f $CACHE_FOLDER/$IPADDR-0
|
|
} &
|
|
exit 0
|
|
else
|
|
echo "no match."
|
|
fi
|
|
}; done
|
|
touch $CACHE_FOLDER/$IPADDR-1
|
|
sleep $(( $QUERY_EXPIRE * 60 )) && {
|
|
rm -f $CACHE_FOLDER/$IPADDR-1
|
|
} &
|
|
exit 1
|