A Centreon/Nagios Plugin for the Pi-hole API

This morning i found out that Pi-hole has an small API and can be called from the endpoint: admin/api.php? so i decided to create an small plugin for Centreon/Nagios in order to extract (almost) all the information possible that can be graphed

  • Number of DNS queries in a day.
  • Number and percentage of ads blocked.
  • Number of clients using Pi-hole as their DNS server.
  • Number of queries classified by IPv4, IPv6, PTR, SRV, etc…

The API is quite limited so i could not do too much. The following are some graphs that I am getting now using the plugin.

Query Types
DNS Queries
Number of clients using Pi-hole
ADS blocked

The plugin is the following one, but as I always say, you can find it in my GitHub updated.

#!/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

USAGE

To use this plugin it’s as simple as put in /usr/lib/nagios/plugins or in the default location for your plugins, in my case is the previous one. From here the plugin can be called by Centreon or Nagios.

The usage syntax is the following:

./check_pihole_api -h $PIHOLE_IPADDRESS -s [ clients || queries || ads ] || -i || -q || -t

[i] -s (summary)
	- clients: Number of clients using Pihole as their DNS server
	- queries: Number of DNS queries
	- ads: Number and percentage of ads blocked.

[i] -i (information)
	- show the version of the plugin

[i] -q
	- queries by type AAAA, A, SOA, TXT, PTR, ANY, SRV, IPV4, IPV6

[i] -t
  - Show a TOP number of queries by host

Some examples in my Pi-hole:

Take into account that the values that are being extracted from the API are exactly the same that the values that are show in the Pi-hole Dashboard:

Pi-hole Dashboard

UPDATE 14/04/2020

I have added a new function in order to extract a TOP of number of queries by hosts in the last 24 hours and as you can see it can be graphed:

TOP number of queries by host

To get this the plugin has to be executed with the parameter -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

4 comentarios sobre “A Centreon/Nagios Plugin for the Pi-hole API

  1. Hello,

    Thx for the script, it’s really usefull to centralize this information in centreon, the implementation is working well in command line, but on in centreon web interface. I thought it was about permissions but i tried a lot of stuff which is not working. It’s like centreon is not interpreting the shell script’s variable. Do you know how to fix this ?
    Thx for the help

    1. Hi Yakari,

      Could you tell me a bit more about what is happening when you execute the script on Centreon?

      As you can see in the post, when i tried it was working fine.

      With more information, I’ll help you!

      Kind regards

    2. Yakari,

      Take into account that the user that is executing the plugins on centreon (nagios/centreon/centreon-engine it depends on you configuration) must have execution, read and write permissions on the folder where plugin it’s located.

      Kind regards

      1. Hello,
        In Centreon the variable script is not interpreted, but in command line everything is working fine :
        in centreon :
        Statut détaillé
        THERE ARE HOSTS UP & Total=
        in command line with centreon user
        [centreon@ces ~]$ /usr/lib64/nagios/plugins/check_pihole_api -h 192.168.1.254 -s clients
        THERE ARE 9 HOSTS UP & Total=9
        Ive connected and tried the execution with the possible different user of centreon : centreon, centreon-engine, centreon-gorgoned) nagios not having /bin/sh , so i modified the /etc/passwd to put /bin/sh and try the execution of the check , but not working. The permission on my folder /usr/lib/centreon/plugin is 777 and i tried to put nagios as owner and group owner, but still nothing. I tried also to execute the plugin a with different path : /usr/lib64/nagios/plugins.
        I’m out of solution, the version of my centreon is 20.10.3.

        Kind regard

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s