433 lines
14 KiB
Bash
433 lines
14 KiB
Bash
#!/bin/bash
|
|
|
|
# Centreon plugin to work with Pihole API
|
|
|
|
############ By @tips-of-mine ############
|
|
plugin_version="1.0"
|
|
|
|
##########################################
|
|
|
|
red=$'\033[1;31m'
|
|
yellow=$'\033[0;33m'
|
|
nc=$'\033[0m'
|
|
|
|
current_dira="$(pwd)"
|
|
current_dir="/usr/lib/centreon/plugins"
|
|
|
|
function info() {
|
|
case "$1" in
|
|
token)
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * The file ${yellow}${api_token_file}${nc} does not exist or it's empty."
|
|
echo " * You can get your token from the value ${yellow}WEBPASSWORD${nc} in the file ${yellow}/etc/pihole/setupVars.conf${nc}"
|
|
echo " * Just put in the file ${yellow}${api_token_file}${nc} and that's it."
|
|
echo " *"
|
|
echo " * Example:"
|
|
echo " * centreon-engine@centreon # ${yellow}touch ${api_token_file}${nc}"
|
|
echo " * centreon-engine@centreon # ${yellow}echo 'PASTE_YOUR_TOKEN_HERE' >> ${api_token_file}${nc}"
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " "
|
|
|
|
exit 1 ;
|
|
;;
|
|
usage)
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * Instructions for use"
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * Usage $0 -h pihole_ipaddress -e [ ads || being || clients || queries || unique] || -s || -i || -q || -t "
|
|
echo " *"
|
|
echo " * -h (host) "
|
|
echo " * - ip address or fqdn name of the machine running Pi-Hole "
|
|
echo " *"
|
|
echo " * -c (cache) "
|
|
echo " * - show cache "
|
|
echo " *"
|
|
echo " * -e (summary) "
|
|
echo " * - ads : Number and percentage of ads blocked. "
|
|
echo " * - being : Amount of blocked domain."
|
|
echo " * - clients : Number of clients using Pihole as their DNS server "
|
|
echo " * - domain : Number of domain queries "
|
|
echo " * - queries : Number of DNS queries "
|
|
echo " *"
|
|
echo " * -f (forwarded) "
|
|
echo " * - show forwarded "
|
|
echo " *"
|
|
echo " * -r (reply) "
|
|
echo " * - show the status reply UNKNOWN, CNAME, IP, NODATA, NXDOMAIN "
|
|
echo " *"
|
|
echo " * -s (status) "
|
|
echo " * - show the status service (enable/disable) "
|
|
echo " *"
|
|
echo " * -q (querie) "
|
|
echo " * - queries by type AAAA, A, SOA, TXT, PTR, ANY, SRV, IPV4, IPV6 "
|
|
echo " *"
|
|
echo " * -t (top 10) "
|
|
echo " * - Show a TOP number of queries by host "
|
|
echo " *"
|
|
echo " * -v (information) "
|
|
echo " * - show the version of the plugin "
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " "
|
|
|
|
exit 0 ;
|
|
;;
|
|
version)
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * Plugin by @tips-of-mine https://git.tips-of-mine.fr/ - Version: ${plugin_version} "
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " "
|
|
|
|
exit 0 ;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function ApiCall() {
|
|
local obj=$1
|
|
local token=$2
|
|
|
|
pihole_api_tempfile="/tmp/pihole_api_${obj}.tmp"
|
|
|
|
case $obj in
|
|
"summary")
|
|
pihole_api_output=$(curl "http://${pihole_ipadd}/admin/api.php?${obj}&auth=${token}" 2> /dev/null | sed 's/{/\n/g ; s/","/\n/g ; s/"//g' > ${pihole_api_tempfile})
|
|
;;
|
|
"status")
|
|
pihole_api_output=$(curl "http://${pihole_ipadd}/admin/api.php?${obj}&auth=${token}" 2> /dev/null | sed 's/","/\n/g ; s/"//g' > ${pihole_api_tempfile})
|
|
;;
|
|
"getQueryTypes")
|
|
pihole_api_output=$(curl "http://${pihole_ipadd}/admin/api.php?${obj}&auth=${token}" 2> /dev/null | sed "s,),,g ; s,(,,g ; s/,\"/\n/g ; s/\"//g" > ${pihole_api_tempfile})
|
|
;;
|
|
"getQuerySources")
|
|
pihole_api_output=$(curl "http://${pihole_ipadd}/admin/api.php?${obj}&auth=${token}" 2> /dev/null | sed 's,{"top_sources":{",,g ; s/,"/\n/g ; s/"//g ; s/}//g ; s/|/:/g' > ${pihole_api_tempfile})
|
|
esac
|
|
}
|
|
|
|
function GetApiToken() {
|
|
# Default token file location
|
|
api_token_file="${current_dir}/pihole-api.token"
|
|
|
|
# If the file does not exist
|
|
if [ ! -f ${api_token_file} ]; then
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * ${red}The file ${api_token_file} does not exist ${nc}"
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " ";
|
|
|
|
info token
|
|
else
|
|
export api_token=$(cat ${api_token_file})
|
|
# If the the api_token var is NULL because the file is empty (?)
|
|
if [ -z ${api_token} ]; then
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * ${red}The file ${api_token_file} exists, but it is empty ${nc}"
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " ";
|
|
|
|
info token
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function functSummary() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# The summary option passed
|
|
ApiCall "summary" "${api_token}"
|
|
|
|
case "${summary_opt}" in
|
|
ads)
|
|
ads_percentage_today=$(cat ${pihole_api_tempfile} | grep ads_percentage_today | cut -f2 -d":")
|
|
ads_blocked_today=$(cat ${pihole_api_tempfile} | grep ads_blocked_today | cut -f2 -d":")
|
|
echo "ADS blocked today : ${ads_blocked_today}, Percentage = ${ads_percentage_today} % | 'TotalADS'=${ads_blocked_today} 'Percentage'=${ads_percentage_today}%"
|
|
;;
|
|
being)
|
|
domains_being_blocked=$(cat ${pihole_api_tempfile} | grep domains_being_blocked | cut -f2 -d":")
|
|
echo "Domains blocked : ${domains_being_blocked} | 'Blocked'=${domains_being_blocked}"
|
|
;;
|
|
clients)
|
|
unique_clients=$(cat ${pihole_api_tempfile} | grep unique_clients | cut -f2 -d":")
|
|
clients_ever_seen=$(cat ${pihole_api_tempfile} | grep clients_ever_seen | cut -f2 -d":")
|
|
echo "${unique_clients} Hosts up, Total ${clients_ever_seen} | 'Hosts'=${unique_clients} 'TotalHosts'=${clients_ever_seen}"
|
|
;;
|
|
domain)
|
|
unique_domains=$(cat ${pihole_api_tempfile} | grep unique_domains | cut -f2 -d":")
|
|
echo "Queries domain : ${unique_domains} | 'QueryDomain'=${unique_domains}"
|
|
;;
|
|
queries)
|
|
dns_queries_today=$(cat ${pihole_api_tempfile} | grep dns_queries_today | cut -f2 -d":")
|
|
dns_queries_all_types=$(cat ${pihole_api_tempfile} | grep dns_queries_all_types | cut -f2 -d":")
|
|
echo "DNS queries today : ${dns_queries_today}, queries all type : ${dns_queries_all_types} | 'DnsTotalToday'=${dns_queries_today} 'DnsAllType'=${dns_queries_all_types}"
|
|
;;
|
|
*)
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * ${red}Incorrect arugment > ${summary_opt} < for the option -s ${nc}"
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " ";
|
|
|
|
info "usage"
|
|
|
|
exit 1 ;
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function functCache() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# Calling the api
|
|
ApiCall "summary" "${api_token}"
|
|
|
|
#
|
|
queries_cached=$(cat ${pihole_api_tempfile} | grep -io "queries_cached:.*" | cut -f2 -d":" | sed 's/}//g')
|
|
|
|
#
|
|
echo "Use cache ${queries_cached} | 'cache'=${queries_cached} "
|
|
}
|
|
|
|
function functforwarded() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# Calling the api
|
|
ApiCall "summary" "${api_token}"
|
|
|
|
#
|
|
queries_forwarded=$(cat ${pihole_api_tempfile} | grep -io "queries_forwarded:.*" | cut -f2 -d":" | sed 's/}//g')
|
|
|
|
#
|
|
echo "Use forwarded ${queries_forwarded} | 'forwarded'=${queries_forwarded} "
|
|
}
|
|
|
|
function functStatus() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# Calling the api
|
|
ApiCall "status" "${api_token}"
|
|
|
|
#
|
|
status=$(cat ${pihole_api_tempfile} | grep -io "status:.*" | cut -f2 -d":" | sed 's/}//g')
|
|
|
|
#
|
|
if [[ ${status} == "enabled" ]]; then
|
|
echo "OK - Status Pi-Hole is ${status} | 'enabled'=1, 'disabled'=0 "
|
|
|
|
exit 0;
|
|
elif [[ ${status} == "disabled" ]]; then
|
|
echo "WARNING - Status Pi-Hole is ${status} | 'enabled'=0, 'disabled'=1 "
|
|
|
|
exit 1;
|
|
else
|
|
echo "UNKNOWN - Status Pi-Hole is ${status} | 'enabled'=0, 'disabled'=0 "
|
|
|
|
exit 3;
|
|
fi
|
|
}
|
|
|
|
function functGetReply() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# Calling the api
|
|
ApiCall "summary" "${api_token}"
|
|
|
|
# Local vars for query types
|
|
local reply_UNKNOWN=$(cat ${pihole_api_tempfile} | grep reply_UNKNOWN | cut -f2 -d":")
|
|
local reply_NODATA=$(cat ${pihole_api_tempfile} | grep reply_NODATA | cut -f2 -d":")
|
|
local reply_NXDOMAIN=$(cat ${pihole_api_tempfile} | grep reply_NXDOMAIN | cut -f2 -d":")
|
|
local reply_CNAME=$(cat ${pihole_api_tempfile} | grep reply_CNAME | cut -f2 -d":")
|
|
local reply_IP=$(cat ${pihole_api_tempfile} | grep reply_IP | cut -f2 -d":")
|
|
local reply_DOMAIN=$(cat ${pihole_api_tempfile} | grep reply_DOMAIN | cut -f2 -d":")
|
|
|
|
texte="'UNKNOWN'=${reply_UNKNOWN}, 'NODATA'=${reply_NODATA}, 'NXDOMAIN'=${reply_NXDOMAIN}, 'CNAME'=${reply_CNAME}, 'IP'=${reply_IP}, 'DOMAIN'=${reply_DOMAIN}"
|
|
datatexte="'UNKNOWN'=${reply_UNKNOWN}, 'NODATA'=${reply_NODATA}, 'NXDOMAIN'=${reply_NXDOMAIN}, 'CNAME'=${reply_CNAME}, 'IP'=${reply_IP}, 'DOMAIN'=${reply_DOMAIN}"
|
|
|
|
echo "Reply type ${texte} | ${datatexte}"
|
|
}
|
|
|
|
function functGetQueryTypes() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# Calling the api
|
|
ApiCall "getQueryTypes" "${api_token}"
|
|
|
|
# Local vars for query types
|
|
local ipv4=$(cat ${pihole_api_tempfile} | grep -io "ipv4:.*" | cut -f2 -d":")
|
|
local ipv6=$(cat ${pihole_api_tempfile} | grep -io "ipv6:.*" | cut -f2 -d":")
|
|
local any=$(cat ${pihole_api_tempfile} | grep -io "any:.*" | cut -f2 -d":")
|
|
local srv=$(cat ${pihole_api_tempfile} | grep -io "srv:.*" | cut -f2 -d":")
|
|
local soa=$(cat ${pihole_api_tempfile} | grep -io "soa:.*" | cut -f2 -d":")
|
|
local ptr=$(cat ${pihole_api_tempfile} | grep -xi "ptr:.*" | cut -f2 -d":")
|
|
local naptr=$(cat ${pihole_api_tempfile} | grep -io "naptr:.*" | cut -f2 -d":")
|
|
local txt=$(cat ${pihole_api_tempfile} | grep -io "txt:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local mx=$(cat ${pihole_api_tempfile} | grep -io "mx:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local ds=$(cat ${pihole_api_tempfile} | grep -io "ds:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local rrsig=$(cat ${pihole_api_tempfile} | grep -io "rrsig:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local dnskey=$(cat ${pihole_api_tempfile} | grep -io "ns:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local ns=$(cat ${pihole_api_tempfile} | grep -io "ns:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local other=$(cat ${pihole_api_tempfile} | grep -io "other:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
local svcb=$(cat ${pihole_api_tempfile} | grep -io "svcb:.*" | sed 's,},,g' | cut -f2 -d":")
|
|
|
|
texte="'IPV4'=${ipv4}, 'IPV6'=${ipv6}, 'ANY'=${any}, 'SRV'=${srv}, 'SOA'=${soa}, 'PTR'=${ptr}, 'NAPTR'=${naptr}, 'TXT'=${txt}, 'MX'=${mx}, 'DS'=${ds}, 'RRSIG'=${rrsig}, 'DNSKEY'=${dnskey}, 'NS'=${ns}, 'OTHER'=${other}, 'SVCB'=${svcb}"
|
|
datatexte="'IPV4'=${ipv4}, 'IPV6'=${ipv6}, 'ANY'=${any}, 'SRV'=${srv}, 'SOA'=${soa}, 'PTR'=${ptr}, 'NAPTR'=${naptr}, 'TXT'=${txt}, 'MX'=${mx}, 'DS'=${ds}, 'RRSIG'=${rrsig}, 'DNSKEY'=${dnskey}, 'NS'=${ns}, 'OTHER'=${other}, 'SVCB'=${svcb}"
|
|
|
|
echo "Number of queries by type ${texte} | ${datatexte}"
|
|
}
|
|
|
|
function functGetQuerySources() {
|
|
# This function requires a token
|
|
GetApiToken
|
|
|
|
# Calling the api
|
|
ApiCall "getQuerySources" "${api_token}"
|
|
|
|
while read line; do
|
|
check_columns=$(echo $line | sed 's,:, ,g' | wc -w)
|
|
host_name=$(echo $line | cut -f1 -d":")
|
|
|
|
if [[ "${check_columns}" == "3" ]]; then
|
|
columns="3"
|
|
elif [[ "${check_columns}" == "2" ]]; then
|
|
columns="2"
|
|
else
|
|
echo "Error formatting the list"
|
|
echo " "
|
|
|
|
exit 1;
|
|
fi
|
|
|
|
host_queries=$(echo ${line} | cut -f${columns} -d":")
|
|
|
|
if [ -z "${host_queries}" ]; then host_queries="0"; fi
|
|
|
|
texte="${texte} ${host_name}=${host_queries}\n"
|
|
datatexte="${datatexte} ${host_name}=${host_queries}"
|
|
done < ${pihole_api_tempfile}
|
|
|
|
echo -e "Top hosts by queries :\n${texte}|${datatexte}"
|
|
}
|
|
|
|
# Display if there is no argument
|
|
if [ $# -eq 0 ]; then
|
|
info "usage"
|
|
|
|
exit 1;
|
|
fi
|
|
|
|
# The options passed by the user
|
|
while getopts "h:e:cfqrstv" opt; do
|
|
case "$opt" in
|
|
h )
|
|
pihole_ipadd=${OPTARG} ;;
|
|
c )
|
|
e )
|
|
summary_selected="y"
|
|
summary_opt=${OPTARG} ;;
|
|
f )
|
|
query_forwarded="y" ;;
|
|
q )
|
|
query_type_selected="y" ;;
|
|
r )
|
|
query_type_reply="y" ;;
|
|
s )
|
|
status="y" ;;
|
|
t )
|
|
query_sources_selected="y" ;;
|
|
v )
|
|
info "version"
|
|
exit 0 ;;
|
|
\?)
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * ${red}Invalid option. -${OPTARG} ${nc}"
|
|
echo " *"
|
|
echo " * use -h to get help "
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " "
|
|
|
|
exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
# The values passed by the user
|
|
if [ -z ${pihole_ipadd} ]; then
|
|
echo " "
|
|
echo " ************************************************************************************************"
|
|
echo " *"
|
|
echo " * ${red}Please enter the Pihole IP address as follow: -h pihole_ipaddress ${nc}"
|
|
echo " *"
|
|
echo " ************************************************************************************************"
|
|
echo " ";
|
|
|
|
exit 1;
|
|
else
|
|
if [[ "${summary_selected}" == "y" ]]; then
|
|
# Calling the summary function
|
|
functSummary
|
|
|
|
exit 0;
|
|
elif [[ "${query_cached}" == "y" ]]; then
|
|
# Calling the status Cache
|
|
functCache
|
|
|
|
exit 0;
|
|
elif [[ "${status}" == "y" ]]; then
|
|
# Calling the status service
|
|
functStatus
|
|
|
|
exit 0;
|
|
elif [[ "${query_forwarded}" == "y" ]]; then
|
|
# Calling the status forwarded
|
|
functforwarded
|
|
|
|
exit 0;
|
|
elif [[ "${query_type_selected}" == "y" ]]; then
|
|
# Calling the Query Types funct
|
|
functGetQueryTypes
|
|
|
|
exit 0;
|
|
elif [[ "${query_sources_selected}" == "y" ]]; then
|
|
# Calling the Query Source funct
|
|
functGetQuerySources
|
|
|
|
exit 0;
|
|
elif [[ "${query_type_reply}" == "y" ]]; then
|
|
# Calling the Query Reply funct
|
|
functGetReply
|
|
|
|
exit 0;
|
|
else
|
|
info "usage"
|
|
fi
|
|
|
|
# Just delete the temp file
|
|
#rm -f ${pihole_api_tempfile}
|
|
fi
|
|
|