#!/usr/bin/env bash # Script to check if specified IP is on common known dns blacklists # Copyright (C) 2018 Aaron Ball # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Default to opendns main nameserver if the NS variable isn't set export NS=${NS:-208.67.220.220} # Pertinent color escape sequences export CGREEN=$'\e[32m' export CRED=$'\e[31m' export CRESET=$'\e[0m' # is_ipv4: # Checks if the provided string is a valid IPv4 address. # # @str String to check # @return (stdout) 1 == valid ip, 0 == invalid ip is_ipv4() { local str="${1}" local match match=$(printf "${str}" | grep -E '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$') if [ "${match}" = "${str}" ]; then printf 1 return 0; fi printf 0; return 1; } usage() { printf "Usage:\n %s [options] \n\n" "$(basename ${0})" printf "Options:\n" printf " -h,--help Print this help text\n" printf " -m,--manifest Path to file containing DNSBL manifest\n" printf " -s,--summary Print only number of lists IP was found on\n" } parseargs() { local args=("${@}") for (( i = 0; i < ${#args[@]}; i++ )); do if [ "${args[$i]}" = '-h' ] || [ "${args[$i]}" = '-h' ]; then usage exit 0 elif [ "${args[$i]}" = '-s' ] || [ "${args[$i]}" = '--summary' ]; then _SUMMARY=1 elif [ "${args[$i]}" = '-m' ] || [ "${args[$i]}" = '--manifest' ]; then i=$(( i + 1 )) _MANIFEST="${args[$i]}" else _IP="${args[$i]}" fi done if [ -z "${_IP}" ]; then printf "IP address required\n" return 1 fi if [ $(is_ipv4 "${_IP}") = 0 ]; then printf "Provided IP '%s' is not a valid IPv4 address\n" "${_IP}" return 1 fi } # main: # Ye olde' main. # # @ip IP address to check for blacklist main() { local rev # IP address, reversed for dns lookup (dig) local resp # Response from dns query local dnsbls # Array of dns blacklist endpoints local found # Number of times the ip was found in blacklists local _IP='' # IP to query DNSBLs for local _SUMMARY=0 # Print only DNSBL count summary (number of lists # blacklisting the ip) local _MANIFEST='' # Manifest of DNSBLs to check # Set defaults _MANIFEST="dnsbls.txt" # Parse cli args into arg variables parseargs ${@} || return $? # If the terminal is not a char terminal (eg: someone is using less, more, # cat, etc), we don't want to print escape codes because they will get # mangled by the tool most likely. if [ ! -t 1 ]; then unset CGREEN unset CRED unset CRESET fi # Reverse the ip address rev=$(printf '%s.' "${_IP}" | tac -s.) # Some basic information if [ "${_SUMMARY}" -eq 0 ]; then printf "Checking %s\n" "${_IP}" printf "Reverse DNS: %s\n\n" "$(dig @${NS} +short -x ${_IP})" fi if [ ! -f "${_MANIFEST}" ]; then printf "ERROR: DNSBL manifest '%s' not accessible.\n" "${_MANIFEST}" printf "Please set LIST environment variable to file that exists\n" return 1 else dnsbls=($(grep -v '^#' "${_MANIFEST}")) fi found=0 for bl in ${dnsbls[@]}; do # I can dig it resp="$(dig @${NS} +short -t a ${rev}${bl})" [ "${_SUMMARY}" -eq 0 ] && printf "%-25s: " "${bl}" if [ -z "${resp}" ]; then [ "${_SUMMARY}" -eq 0 ] && printf "%bNot found%b\n" "${CGREEN}" "${CRESET}" else [ "${_SUMMARY}" -eq 0 ] && printf "%bFound%b\n" "${CRED}" "${CRESET}" found=$((found + 1)) fi done if [ ${_SUMMARY} -eq 0 ]; then printf "\nFound %s on %d lists\n" "${_IP}" "${found}" else printf "%d\n" "${found}" fi } main ${@}