#!/bin/bash # /usr/lib/check_mk_agent/local/300/check_adguard set -u CONFIG="/etc/check_mk/adguard.conf" OK=0 WARN=1 CRIT=2 UNKNOWN=3 # # --------------------------------------------------------------------------- # Configuration # --------------------------------------------------------------------------- # if [[ ! -r "$CONFIG" ]]; then printf '%s\n' \ "${UNKNOWN} \"AdGuard Home\" - Configuration file ${CONFIG} missing or unreadable" exit 0 fi # shellcheck disable=SC1090 source "$CONFIG" ADGUARD_URL="${ADGUARD_URL:-http://127.0.0.1:3000}" ADGUARD_USER="${ADGUARD_USER:-}" ADGUARD_PASSWORD="${ADGUARD_PASSWORD:-}" CHECK_UPDATES="${CHECK_UPDATES:-yes}" ALERT_PROTECTION_DISABLED="${ALERT_PROTECTION_DISABLED:-yes}" # # --------------------------------------------------------------------------- # Requirements # --------------------------------------------------------------------------- # if ! command -v curl >/dev/null 2>&1; then printf '%s\n' \ "${UNKNOWN} \"AdGuard Home\" - curl is not installed" exit 0 fi if ! command -v jq >/dev/null 2>&1; then printf '%s\n' \ "${UNKNOWN} \"AdGuard Home\" - jq is not installed" exit 0 fi # # --------------------------------------------------------------------------- # curl configuration # --------------------------------------------------------------------------- # CURL_OPTS=( --silent --show-error --fail --connect-timeout 3 --max-time 10 ) AUTH_OPTS=() if [[ -n "$ADGUARD_USER" ]]; then AUTH_OPTS=( --user "${ADGUARD_USER}:${ADGUARD_PASSWORD}" ) fi # # --------------------------------------------------------------------------- # AdGuard status / version # --------------------------------------------------------------------------- # STATUS_RESPONSE="$( curl \ "${CURL_OPTS[@]}" \ "${AUTH_OPTS[@]}" \ "${ADGUARD_URL%/}/control/status" \ 2>/dev/null )" STATUS_RC=$? if [[ $STATUS_RC -ne 0 || -z "$STATUS_RESPONSE" ]]; then printf '%s\n' \ "${CRIT} \"AdGuard Home\" - API unavailable or authentication failed at ${ADGUARD_URL}" exit 0 fi if ! printf '%s' "$STATUS_RESPONSE" | jq -e 'type == "object"' >/dev/null 2>&1 then printf '%s\n' \ "${UNKNOWN} \"AdGuard Home\" - Status API returned unexpected data" exit 0 fi VERSION="$( printf '%s' "$STATUS_RESPONSE" | jq -r '.version // empty' )" RUNNING="$( printf '%s' "$STATUS_RESPONSE" | jq -r '.running // false' )" PROTECTION_ENABLED="$( printf '%s' "$STATUS_RESPONSE" | jq -r '.protection_enabled // false' )" DNS_PORT="$( printf '%s' "$STATUS_RESPONSE" | jq -r '.dns_port // 53' )" DNS_ADDRESSES="$( printf '%s' "$STATUS_RESPONSE" | jq -r ' (.dns_addresses // []) | join(", ") ' )" if [[ "$RUNNING" != "true" ]]; then printf '%s\n' \ "${CRIT} \"AdGuard Home\" - API reachable but DNS service reports not running" else if [[ -n "$VERSION" ]]; then printf '%s\n' \ "${OK} \"AdGuard Home\" - API reachable, DNS running, version ${VERSION}, port ${DNS_PORT}" else printf '%s\n' \ "${OK} \"AdGuard Home\" - API reachable, DNS running, port ${DNS_PORT}" fi fi # # --------------------------------------------------------------------------- # Protection state # --------------------------------------------------------------------------- # if [[ "$PROTECTION_ENABLED" == "true" ]]; then printf '%s\n' \ "${OK} \"AdGuard Protection\" - Protection enabled" else if [[ "$ALERT_PROTECTION_DISABLED" == "yes" ]]; then printf '%s\n' \ "${WARN} \"AdGuard Protection\" - Protection disabled" else printf '%s\n' \ "${OK} \"AdGuard Protection\" - Protection disabled" fi fi # # --------------------------------------------------------------------------- # Statistics # --------------------------------------------------------------------------- # STATS_RESPONSE="$( curl \ "${CURL_OPTS[@]}" \ "${AUTH_OPTS[@]}" \ "${ADGUARD_URL%/}/control/stats" \ 2>/dev/null )" STATS_RC=$? if [[ $STATS_RC -ne 0 || -z "$STATS_RESPONSE" ]]; then printf '%s\n' \ "${UNKNOWN} \"AdGuard Statistics\" - Unable to retrieve DNS statistics" elif ! printf '%s' "$STATS_RESPONSE" | jq -e 'type == "object"' >/dev/null 2>&1 then printf '%s\n' \ "${UNKNOWN} \"AdGuard Statistics\" - Statistics API returned unexpected data" else DNS_QUERIES="$( printf '%s' "$STATS_RESPONSE" | jq -r '.num_dns_queries // 0' )" BLOCKED="$( printf '%s' "$STATS_RESPONSE" | jq -r '.num_blocked_filtering // 0' )" SAFE_BROWSING="$( printf '%s' "$STATS_RESPONSE" | jq -r '.num_replaced_safebrowsing // 0' )" SAFE_SEARCH="$( printf '%s' "$STATS_RESPONSE" | jq -r '.num_replaced_safesearch // 0' )" PARENTAL="$( printf '%s' "$STATS_RESPONSE" | jq -r '.num_replaced_parental // 0' )" AVG_TIME="$( printf '%s' "$STATS_RESPONSE" | jq -r '.avg_processing_time // 0' )" [[ "$DNS_QUERIES" =~ ^[0-9]+$ ]] || DNS_QUERIES=0 [[ "$BLOCKED" =~ ^[0-9]+$ ]] || BLOCKED=0 [[ "$SAFE_BROWSING" =~ ^[0-9]+$ ]] || SAFE_BROWSING=0 [[ "$SAFE_SEARCH" =~ ^[0-9]+$ ]] || SAFE_SEARCH=0 [[ "$PARENTAL" =~ ^[0-9]+$ ]] || PARENTAL=0 [[ "$AVG_TIME" =~ ^[0-9]+([.][0-9]+)?$ ]] || AVG_TIME=0 BLOCK_PERCENT="$( awk \ -v blocked="$BLOCKED" \ -v total="$DNS_QUERIES" \ 'BEGIN { if (total > 0) { printf "%.2f", (blocked / total) * 100 } else { printf "0.00" } }' )" # # avg_processing_time is reported in seconds. # AVG_TIME_MS="$( awk \ -v seconds="$AVG_TIME" \ 'BEGIN { printf "%.3f", seconds * 1000 }' )" printf '%s\n' \ "${OK} \"AdGuard Statistics\" queries=${DNS_QUERIES};;;0|blocked=${BLOCKED};;;0|blocked_percent=${BLOCK_PERCENT}%;;;0;100|avg_processing_time=${AVG_TIME_MS}ms;;;0 ${DNS_QUERIES} queries, ${BLOCKED} blocked (${BLOCK_PERCENT}%), average processing ${AVG_TIME_MS} ms" fi # # --------------------------------------------------------------------------- # AdGuard update check # --------------------------------------------------------------------------- # # AdGuard Home provides its own update-information endpoint. # This is preferable to independently scraping GitHub because it follows # AdGuard's own release/update logic. # if [[ "$CHECK_UPDATES" == "yes" ]]; then VERSION_RESPONSE="$( curl \ "${CURL_OPTS[@]}" \ "${AUTH_OPTS[@]}" \ -X POST \ -H "Content-Type: application/json" \ -d '{"recheck_now":true}' \ "${ADGUARD_URL%/}/control/version.json" \ 2>/dev/null )" VERSION_RC=$? if [[ $VERSION_RC -ne 0 || -z "$VERSION_RESPONSE" ]]; then printf '%s\n' \ "${UNKNOWN} \"AdGuard Update\" - Installed ${VERSION:-unknown}, unable to retrieve update information" elif ! printf '%s' "$VERSION_RESPONSE" | jq -e 'type == "object"' >/dev/null 2>&1 then printf '%s\n' \ "${UNKNOWN} \"AdGuard Update\" - Update API returned unexpected data" else UPDATE_DISABLED="$( printf '%s' "$VERSION_RESPONSE" | jq -r '.disabled // false' )" NEW_VERSION="$( printf '%s' "$VERSION_RESPONSE" | jq -r '.new_version // empty' )" NEW_VERSION="${NEW_VERSION#v}" INSTALLED_VERSION="${VERSION#v}" if [[ "$UPDATE_DISABLED" == "true" ]]; then printf '%s\n' \ "${OK} \"AdGuard Update\" - Update checking disabled by AdGuard Home, installed ${INSTALLED_VERSION:-unknown}" elif [[ -z "$NEW_VERSION" ]]; then printf '%s\n' \ "${OK} \"AdGuard Update\" - Current: installed ${INSTALLED_VERSION:-unknown}" elif [[ -z "$INSTALLED_VERSION" ]]; then printf '%s\n' \ "${WARN} \"AdGuard Update\" - New version ${NEW_VERSION} available, installed version unknown" elif [[ "$NEW_VERSION" == "$INSTALLED_VERSION" ]]; then printf '%s\n' \ "${OK} \"AdGuard Update\" - Current: installed ${INSTALLED_VERSION}" else printf '%s\n' \ "${WARN} \"AdGuard Update\" - Update available: installed ${INSTALLED_VERSION}, latest ${NEW_VERSION}" fi fi fi exit 0