
Este mañana he descubierto que Pihole tiene una pequeña API que se puede llamar desde el endpoint: admin/api.php? así que he decido crear un pequeño plugin que se pueda usar tanto en Centreon como en Nagios . Lo que conseguiremos con este plugin es mantener un histórico y graficar datos en nuestro Centreon como:
- Numero consultas DNS al dia
- Numero y porcentaje de anuncios bloqueados
- Numero de clientes usando Pihole como DNS
- Numero consultas clasificadas por IPv4, IPv6, PTR, SRV, etc…
La API es bastante limitada así que no he podido sacarle mucho mas. A continuación os dejo unos gráficos extraídos de mi Dashboard en el Centreon que tengo en mi Raspberry corriendo sobre un contenedor de Docker.




El plugin es el que dejo aquí a continuación, pero como siempre digo, lo mas probable es que lo vaya actualizando, así que si lo queréis lo tendréis en mi GitHub actualizado.
#!/bin/bash
# Nagios plugin to work with Pihole API
########### By @deividgdt ###########
plugin_version="1.3"
#####################################
function info() {
case "$1" in
token)
echo "[i] The file ${api_token_file} does not exist or it's empty."
echo "[i] You can get your token from the value WEBPASSWORD in the file /etc/pihole/setupVars.conf"
echo "[i] Just put in the file ${api_token_file} and that's it."
echo ""
echo "[i] Example:"
echo " centreon-engine@centreon # touch ${api_token_file}"
echo " centreon-engine@centreon # echo 'PASTE_YOUR_TOKEN_HERE' >> ${api_token_file}"
exit 1;
;;
usage)
echo "[i] Usage $0 -h pihole_ipaddress -s [ clients || queries || ads ] || -i || -q"
echo ""
echo "[i] -s (summary)"
echo " - clients: Number of clients using Pihole as their DNS server"
echo " - queries: Number of DNS queries"
echo " - ads: Number and percentage of ads blocked."
echo ""
echo "[i] -i (information)"
echo " - show the version of the plugin"
echo "[i] -q"
echo " - queries by type AAAA, A, SOA, TXT, PTR, ANY, SRV, IPV4, IPV6"
;;
version)
echo "[v] plugin by @deividgdt https://github.com/deividgdt - version: ${plugin_version}"
;;
esac
}
function apiCall() {
local obj=$1
local token=$2
pihole_api_tempfile="/usr/lib/nagios/plugins/pihole_api.tmp"
case $obj in
"summary")
pihole_api_output=$(curl http://${pihole_ipadd}/admin/api.php?${obj} 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})
;;
esac
}
function getApiToken() {
# Default token file location
api_token_file="/usr/lib/nagios/plugins/apihole.token"
# If the file does not exist
if [ ! -f ${api_token_file} ]; then
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 "[e] Token is NULL";
info token
fi
fi
}
function functSummary() {
apiCall "summary"
# The summary option passed
case "${summary_opt}" in
clients)
unique_clients=$(cat ${pihole_api_tempfile} | grep unique_clients | cut -f2 -d":")
echo "THERE ARE ${unique_clients} HOSTS UP|Total=${unique_clients}"
;;
queries)
dns_queries_today=$(cat ${pihole_api_tempfile} | grep dns_queries_today | cut -f2 -d":")
echo "DNS QUERIES TODAY ${dns_queries_today}|Total=${dns_queries_today}"
;;
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} %|Total=${ads_blocked_today} Percentage=${ads_percentage_today}%"
;;
*)
echo "Incorrect arugment > ${summary_opt} < for the option -s";
info "usage"
exit 1;
;;
esac
}
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 -io "ptr:.*" | cut -f2 -d":")
local txt=$(cat ${pihole_api_tempfile} | grep -io "txt:.*" | sed 's,},,g' | cut -f2 -d":")
echo "NUMBER OF QUERIES BY TYPE IPV4=${ipv4} , IPV6=${ipv6} , ANY=${any} , SRV=${srv} , SOA=${soa} , PTR=${ptr} , TXT=${txt}|IPV4=${ipv4} IPV6=${ipv6} ANY=${any} SRV=${srv} SOA=${soa} PTR=${ptr} TXT=${txt}"
}
if [ $# -eq 0 ]; then
info "usage"
exit 1;
fi
# The options passed by the user
while getopts "h:s:iq" opt; do
case "$opt" in
h )
pihole_ipadd=$OPTARG ;;
s )
summary_selected="y"
summary_opt=$OPTARG ;;
q )
query_type_selected="y" ;;
i )
info "version"
exit 0 ;;
\?)
echo "[e] Invalid option. -$OPTARG"
exit 1 ;;
esac
done
# The values passed by the user
if [ -z ${pihole_ipadd} ]; then
echo "[i] Please enter the Pihole IP address as follow: -h pihole_ipaddress";
exit 1;
else
if [[ "${summary_selected}" == "y" ]]; then
# Calling the summary function
functSummary
exit 1;
elif [[ "${query_type_selected}" == "y" ]]; then
# Calling the Query Types funct
functGetQueryTypes
else
info "usage"
fi
# Just delete the temp file
rm -f ${pihole_api_tempfile}
fi
USO
Para usar el plugin es tan simple como ubicarlo en /usr/lib/nagios/plugins o en la ruta que tengáis todos vuestros plugins, en mi caso es esta. Desde aquí lo podremos llamar con Centreon o Nagios.
La sintaxis de uso es la siguiente:
./check_pihole_api -h pihole_ipaddress ( -s [ clients || queries || ads ] || -i || -q )
-h (hosts)
- La dirección IP del hosts donde este instalado Pi-hole
-s (summary)
- clients: Numero de clientes usando Pihole como DNS
- queries: Numero de consultas DNS
- ads: Numero y porcentaje de anuncios bloqueados
-i (information)
- Muestra la version del plugin
-q
- consulta por tipo AAAA, A, SOA, TXT, PTR, ANY, SRV, IPV4, IPV6
A continuación algunos ejemplos de uso en mi Pihole

Tened en cuenta que los valores que se extraen de la API son los mismo que se pueden observar en el Dashboard de Pi-hole:

UPDATE 14/04/2020
He añadido una nueva función al script que extrae los hosts en la red que más consultas DNS han realizado en las ultimas 24 h y que como veis a continuación podéis graficarlo:

Para obtener estos datos con el plugin hay que ejecutarlo con el parámetro: -t
./check_pihole_api -h $PIHOLE_IPADDRESS -t
TOP NUMBER OF QUERIES BY HOST portatil1.pihome=5678 movil1.pihome=4442 movil2.pihome=3556 portatil2.pihome=2280 samsungtv.pihome=1942| portatil1.pihome=5678 movil1.pihome=4442 movil2.pihome=3556 portatil2.pihome=2280 samsungtv.pihome=1942