diff --git a/check_http b/check_http new file mode 100755 index 0000000000000000000000000000000000000000..e035bf64f998276f7f2dd8af6b4e90386cdc8b41 --- /dev/null +++ b/check_http @@ -0,0 +1,222 @@ +#!/bin/bash +# ================================================================================ +# +# CHECK HTTP +# +# Check http request to an url with given method. +# The response header and +# +# ------------------------------------------------------------------------------- +# 2023-09-06 v1.0 <axel.hahn@unibe.ch> +# ================================================================================ + +. $( dirname $0 )/inc_pluginfunctions + +export self_APPVERSION=1.0 + +# ---------------------------------------------------------------------- +# FUNCTIONS +# ---------------------------------------------------------------------- + +# show help text +function showHelp(){ + local _self; _self=$(basename $0) +cat <<EOF +$( ph.showImlHelpHeader ) + +Makes an http request with a given method. +Additionally you can verify the response by +- http status code +- content in http response header +- content in http response body +- content that is NOT in http response body + +SYNTAX: + $_self [-h] + $_self [-m METHOD] -u URL \\ + [-b REGEX] [-j FILTER] [-n REGEX] \\ + [-r REGEX] \\ + [-s STATUSCODE] \\ + [-l LABEL] + +OPTIONS: + + -h this help + +PARAMETERS: + + Define request: + -u URL Set url to fetch; eg. https://www.example.com/ + -m METHOD Set a method, eg. HEAD; default: GET + + What to check: + -s STATUSCODE exact Statuscode to check; 3 digits; by default critical + is a statuscode greater equal 400 + -r REGEX Regex must match in http response header + -j JQ-FILTER for JSON Response: filter data by a jq + -b REGEX Regex must match in response body + -n REGEX Regex must NOT match in response body + + Output: + -l LABEL set a custom label; default: METHOD + URL eg. + "GET https://example.com/status" + +EXAMPLES: + + $_self -u https://www.example.com/ + Check if GET request to url responds with 200..3xx status. + + $_self -m HEAD -u https://www.example.com/ + Check if HEAD request to url responds with 200..3xx status + + $_self -u [URL] -s 403 + Check if the GET request to url has a wanted status code. + You can verify if a protected url is not accessible. + + $_self -u [URL] -b "contact" + Check if the GET request to url responds with 200..3xx + status and the response body contains "contact". + + $_self -u [URL] -n "error occured" + Check if the GET request to url responds with 200..3xx + status and the response body NOT contains "error occured". + + $_self -u [URL] -s 200 -b -b "contact" -n "error occured" + Combine code, a matching search and a non matching one. + +EOF +} + +# ---------------------------------------------------------------------- +# MAIN +# ---------------------------------------------------------------------- + +ph.hasParamoption "h" "$@"; bOptHelp=$? + +if [ $bOptHelp -eq 0 -o $# -eq 0 ]; then + showHelp + exit 0 +fi + +ph.require "curl" + +sUrl=$( ph.getValueWithParam '' u "$@") +sMethod=$( ph.getValueWithParam 'GET' m "$@" | tr [:lower:] [:upper:]) + +iStatus=$( ph.getValueWithParam '' s "$@") +sHeader=$( ph.getValueWithParam '' r "$@") +sBody=$( ph.getValueWithParam '' b "$@") +sNotInBody=$( ph.getValueWithParam '' n "$@") +sJq=$( ph.getValueWithParam '' j "$@") +sLabel=$( ph.getValueWithParam "" l "$@") + + +curlParams="-si -X $sMethod" +sProblems= +sOK= + +if [ -z "$sUrl" ]; then + ph.setStatus unknown + ph.status "Wrong parameters - no url was given." + ph.exit +fi + +out=$( curl $curlParams "$sUrl" ) + +iHeaderEnd=$( echo "$out" | grep -n ^$'\r' | cut -f 1 -d ':' | head -1 ) + +# echo "$out" | grep -n ^$'\r'; echo "cut header and body on line $iHeaderEnd" + +_header=$(echo "$out" | sed -n "1,${iHeaderEnd}p") +_body=$( echo "$out" | sed -n "${iHeaderEnd},\$p") + +if [ -n "$sJq" ]; then + _body=$( jq "$sJq" <<< "$_body" 2>/dev/null ) +fi + +# echo "HEADER"; echo "$_header" +# echo "BODY"; echo "$_body" + + +# --- test status +typeset -i iHttpStatus +iHttpStatus=$( grep -i "^HTTP/[0-9\.]* " <<< "${_header}" | awk '{ print $2 }') + +if [ -n "$iStatus" ]; then + # if ! grep -i "^HTTP/[0-9\.]* ${iStatus}" <<< "${_header}" >/dev/null; then + if [ "$iHttpStatus" != "$iStatus" ]; then + ph.setStatus critical + sProblems+="- Http status is not [${iStatus}] but [${iHttpStatus}];\n" + else + sOK+="- Http status is [${iStatus}];\n" + fi +else + if [ $iHttpStatus -ge 400 ]; then + ph.setStatus critical + sProblems+="- Http status is an http error [${iHttpStatus}];\n" + elif [ $iHttpStatus -ge 300 ]; then + sOK+="- Http status is a 3xx redirect [${iHttpStatus}];\n" + else + sOK+="- Http status is a 2xx OK [${iHttpStatus}];\n" + fi +fi + +# --- search in http response header +if [ -n "$sHeader" ]; then + if ! grep -iE "$sHeader" <<< "${_header}" >/dev/null; then + ph.setStatus critical + sProblems+="- Header does not contain [${sHeader}];\n" + else + sOK+="- [${sHeader}] was found in header;\n" + fi +fi +# --- search in http response header +if [ -n "$sNotInHeader" ]; then + if grep -iE "$sNotInHeader" <<< "${_header}" >/dev/null; then + ph.setStatus critical + sProblems+="- Header does contain unwanted [${sNotInHeader}];\n" + else + sOK+="- [${sNotInHeader}] was not found in header;\n" + fi +fi + +# --- search in http response body +if [ -n "$sBody" ]; then + if ! grep -iE "$sBody" <<< "${_body}" >/dev/null; then + ph.setStatus critical + sProblems+="- Body does not contain [${sBody}];\n" + else + sOK+="- [${sBody}] was found in body;\n" + fi + +fi +if [ -n "$sNotInBody" ]; then + if grep -iE "$sNotInBody" <<< "${_body}" >/dev/null; then + ph.setStatus critical + sProblems+="- Body contains unwanted [${sNotInBody}];\n" + else + sOK+="- [${sNotInBody}] was not found in body;\n" + fi + +fi + +# --- output +test -n "$sProblems" && sProblems="Problems:\n$sProblems\n" +test -n "$sOK" && sOK="Found:\n$sOK" + +test -n "$sLabel" && ( + ph.status "$sLabel" + echo "$sMethod $sUrl ($iHttpStatus)" +) +test -n "$sLabel" || ph.status "$sMethod $sUrl ($iHttpStatus)" + +echo +echo Command: curl $curlParams "$sUrl" +echo +echo -e "${sProblems}${sOK}" + +test -n "${sProblems}" && (echo "RESPONSE HEADER:"; echo; echo "$_header") + +ph.exit + +# ---------------------------------------------------------------------- diff --git a/check_systemdunit b/check_systemdunit index 514471f67619d5a53822d7b65c94289056a616e4..9820c3ec9e13e7cb1c4f244713f2a39fcbf82fed 100755 --- a/check_systemdunit +++ b/check_systemdunit @@ -3,23 +3,14 @@ # # CHECK A SINGLE SYSTEMD SERVICE # -# (1) -# shows overview of important services - edit check_systemdservices.cfg to define -# them -# -# (2) -# resturns -# - OK if all systemd servises are running -# - UNKNOWN if systemctl command is not available -# - ERROR if any systemd service is not running -# # ------------------------------------------------------------------------------- -# 2023-09-05 v01.0 <axel.hahn@unibe.ch> +# 2023-09-05 v1.0 <axel.hahn@unibe.ch> +# 2020-09-08 v1.1 <axel.hahn@unibe.ch> add params -s, -l # ================================================================================ . $( dirname $0 )/inc_pluginfunctions -export self_APPVERSION=1.0 +export self_APPVERSION=1.1 # ---------------------------------------------------------------------- # FUNCTIONS @@ -37,16 +28,24 @@ The status is unknown if the command systemctl is not found. The status is critical if the service does not exist or is not running. SYNTAX: - $_self [-h] UNIT + $_self [-h|-l|-s] UNIT OPTIONS: + -h this help + -l list all units + -s list service units + UNIT Name of a unit - see output of 'systemctl' EXAMPLES: - $_self mysql.service - show status of service mysql + $_self -s + list all existing services. For a unit check you need to add the name + in the 1st column. + + $_self nginx.service + show status of nginx webservice EOF } @@ -64,8 +63,31 @@ fi ph.require "systemctl" -_service="${1}" -_status=$( systemctl --no-pager -l status "${_service}" 2>&1 ) +# --- list all units +if ph.hasParamoption "l" "$@" ; then + echo "List of all systemd units:" + echo + _list=$( systemctl --no-legend --no-pager ) + for mytype in $( awk '{ print $1 }' <<< "$_list" | grep '\.' | rev| cut -f 1 -d '.' | rev | grep -v '[^a-z]' | sort -u ) + do + echo "---------- $mytype" + grep "\.${mytype}" <<< "$_list" + echo + done + exit 0 +fi + +# --- list service units +if ph.hasParamoption "s" "$@" ; then + echo "List of service units:" + echo + systemctl --no-legend --no-pager --type service + exit 0 +fi + +# --- check given unit +_unit="${1}" +_status=$( systemctl --no-pager -l status "${_unit}" 2>&1 ) if ! grep "Active: active (running) " <<< "${_status}" >/dev/null; then ph.setStatus critical diff --git a/docs/20_Checks/_index.md b/docs/20_Checks/_index.md index 134d2b73d377dd1dc1001d1974c46c5cfa3d5599..c02273cecd0e289f662c907420303686f4024179 100644 --- a/docs/20_Checks/_index.md +++ b/docs/20_Checks/_index.md @@ -25,6 +25,7 @@ There is one include script used by all checks: * [check_fs_writable](check_fs_writable.md) * [check_haproxy_health](check_haproxy_health.md) * [check_haproxy_status](check_haproxy_status.md) +* [check_http](check_http.md) * [check_memory](check_memory.md) * [check_mysqlserver](check_mysqlserver.md) * [check_netio](check_netio.md) diff --git a/docs/20_Checks/check_httpd.md b/docs/20_Checks/check_httpd.md new file mode 100644 index 0000000000000000000000000000000000000000..30a03fc10af2d4877de3fbc5773cc7024e22990d --- /dev/null +++ b/docs/20_Checks/check_httpd.md @@ -0,0 +1,137 @@ +# Check Httpd + +## Introduction + +Makes an http request with a given method. +Additionally you can verify the response. + +## Requirements + +* `curl` binary + +## Syntax + +```txt +______________________________________________________________________ + +CHECK_HTTP +v1.0 + +(c) Institute for Medical Education - University of Bern +Licence: GNU GPL 3 + +https://os-docs.iml.unibe.ch/icinga-checks/Checks/check_http.html +______________________________________________________________________ + +Makes an http request with a given method. +Additionally you can verify the response by +- http status code +- content in http response header +- content in http response body +- content that is NOT in http response body + +SYNTAX: + check_http [-h] + check_http [-m METHOD] -u URL \ + [-b REGEX] [-j FILTER] [-n REGEX] \ + [-r REGEX] \ + [-s STATUSCODE] \ + [-l LABEL] + +OPTIONS: + + -h this help + +PARAMETERS: + + Define request: + -u URL Set url to fetch; eg. https://www.example.com/ + -m METHOD Set a method, eg. HEAD; default: GET + + What to check: + -s STATUSCODE exact Statuscode to check; 3 digits; by default critical + is a statuscode greater equal 400 + -r REGEX Regex must match in http response header + -j JQ-FILTER for JSON Response: filter data by a jq + -b REGEX Regex must match in response body + -n REGEX Regex must NOT match in response body + + Output: + -l LABEL set a custom label; default: METHOD + URL eg. + "GET https://example.com/status" + +EXAMPLES: + + check_http -u https://www.example.com/ + Check if GET request to url responds with 200..3xx status. + + check_http -m HEAD -u https://www.example.com/ + Check if HEAD request to url responds with 200..3xx status + + check_http -u [URL] -s 403 + Check if the GET request to url has a wanted status code. + You can verify if a protected url is not accessible. + + check_http -u [URL] -b "contact" + Check if the GET request to url responds with 200..3xx + status and the response body contains "contact". + + check_http -u [URL] -n "error occured" + Check if the GET request to url responds with 200..3xx + status and the response body NOT contains "error occured". + + check_http -u [URL] -s 200 -b -b "contact" -n "error occured" + Combine code, a matching search and a non matching one. + +``` + +## Examples + +### Simple check of an url + +``check_http -u https://www.example.com/`` is a check that makes an http GET request. +The queck is OK if the responded status code is no error - if it is 2xx (OK) or a redirect (3xx). + +```txt +OK: GET https://www.example.com/ (200) + +Command: curl -si -X GET https://www.example.com/ + +Found: +- Http status is a 2xx OK [200]; +``` + +### Http HEAD of an url + +You can set the method with ``-m``. +``./check_http -m head -u https://www.example.com/`` responds + + +```txt +OK: HEAD https://www.example.com/ (200) + +Command: curl -si -X HEAD https://www.example.com/ + +Found: +- Http status is a 2xx OK [200]; +``` + +### Exact status code + +With ``-m`` you can verify if the status code matches exactly a given value. +You also can set a code for http error to ensure if a protected url really is blocking the request. + +Maybe you don't deny the access like + +* ``./check_http -u https://www.example.com/memberarea -s 403`` +* ``./check_http -u https://www.example.com/config/settings.json -s 403`` + +Or you can check a flag file that must be absent. + +* ``./check_http -u https://www.example.com/flag_maintenance.txt -s 404`` + +### Matching content + +You can verify if the response matches a given regex. You can search in the response header with ``-r REGEX`` and in the response body with ``-b REGEX``. + +``check_http -u [URL] -b "contact"`` will resppns OK if the status code is not an error (lower 400) and the word "contact" is found in response body. diff --git a/docs/20_Checks/check_systemdunit.md b/docs/20_Checks/check_systemdunit.md index a73a107b9e3c717e77530d2ba4772de3e7973b1b..e534d153dabb90a07b7307804762a754ffeed7aa 100644 --- a/docs/20_Checks/check_systemdunit.md +++ b/docs/20_Checks/check_systemdunit.md @@ -16,7 +16,7 @@ A unit is everything listed by systemctl command - services, timers, targets, .. ______________________________________________________________________ CHECK_SYSTEMDUNIT -v1.0 +v1.1 (c) Institute for Medical Education - University of Bern Licence: GNU GPL 3 @@ -30,21 +30,53 @@ The status is unknown if the command systemctl is not found. The status is critical if the service does not exist or is not running. SYNTAX: - check_systemdunit [-h] UNIT + check_systemdunit [-h|-l|-s] UNIT OPTIONS: + -h this help + -l list all units + -s list service units + UNIT Name of a unit - see output of 'systemctl' EXAMPLES: - check_systemdunit mysql.service - show status of service mysql + check_systemdunit -s + list all existing services. For a unit check you need to add the name + in the 1st column. + + check_systemdunit nginx.service + show status of nginx webservice ``` ## Examples +### List services + +You maybe want to start to get a list of services to pick an existing one that you wanna check periodically. + +You can use ``systemctl --no-legend --no-pager --type service`` or ``$ ./check_systemdunit -s`` + +```txt +List of service units: + + alsa-restore.service loaded active exited Save/Restore Sound Card State + apparmor.service loaded active exited Load AppArmor profiles + avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack + bluetooth.service loaded active running Bluetooth service + clamav-daemon.service loaded active running Clam AntiVirus userspace daemon + clamav-freshclam.service loaded active running ClamAV virus database updater + colord.service loaded active running Manage, Install and Generate Color Profiles + cronie.service loaded active running Periodic Command Scheduler + ... +``` + +### Check a service + +To check a single service you need to add the unit name in the 1st column. + ``$ ./check_systemdunit nginx`` returns ```txt @@ -67,3 +99,7 @@ If a service does not exist: ``./check_systemdunit justadummy`` returns ```txt CRITICAL: Unit justadummy.service could not be found. ``` + +### Other units + +With ``$ ./check_systemdunit -l`` you get a grouped list of all unit types. check_systemdunit handles all types - not only services.