Monitoring/Pi-Hole/Check-PiHole-Api.sh
2023-07-04 13:06:44 +02:00

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