Browse Source

Initial import

Emmanuel Bouthenot 9 years ago
commit
847e1bfcc3

+ 3 - 0
plugins/client/apt/conf/apt.conf

@@ -0,0 +1,3 @@
+UserParameter=debian.packages.updates,/etc/zabbix/scripts/apt -t updates
+UserParameter=debian.packages.security,/etc/zabbix/scripts/apt -t security
+UserParameter=debian.packages.backports,/etc/zabbix/scripts/apt -t backports

+ 56 - 0
plugins/client/apt/scripts/apt

@@ -0,0 +1,56 @@
+#!/bin/sh
+
+TARGETS='updates security backports'
+TARGET=
+
+usage() {
+cat <<EOH
+USAGE: $(basename "$0") [OPTIONS]
+
+Get updates for packages managed by apt
+
+Options:
+    -h  Shows this help
+    -t  Target ($(echo "${TARGETS}" | sed 's/ / or /g'))
+EOH
+}
+
+while getopts "ht:" OPT ; do
+    case "$OPT" in 
+        h)
+            usage
+            exit 0
+            ;;
+        t)
+            TARGET="$OPTARG"
+            ;;
+    esac
+done
+
+if [ -z "${TARGET}" ]; then
+    printf "[ERR] Target is missing\n"
+    usage
+    exit 1
+fi
+
+if ! echo "${TARGET}" | egrep -q "^($(echo "${TARGETS}" | sed 's/ /|/g'))$"; then
+    printf "[ERR] info '${TARGET}' not available in [$(echo "${TARGETS}" | sed 's/ /, /g')]\n"
+    usage
+    exit 1
+fi
+
+DISTRO=$(lsb_release -c -s)
+
+case "${TARGET}" in
+    updates)
+        apt-get -s -o Debug::NoLocking=true upgrade | grep -c '^Inst'
+        ;;
+    security)
+        apt-get -s -o Debug::NoLocking=true upgrade | egrep -c "^Inst [^ ]+ \[[^]]+\] \([^ ]+ .*(Debian-Security|${DISTRO}-security)"
+        ;;
+    backports)
+        apt-get -s -o Debug::NoLocking=true upgrade | egrep -c "^Inst [^ ]+ \[[^]]+\] \([^ ]+ .*(Debian Backports|${DISTRO}-backports)"
+        ;;
+esac
+
+exit 0

+ 4 - 0
plugins/client/apt/sudo/apt

@@ -0,0 +1,4 @@
+#
+# Permit to zabbix user to execute 'apt' plugin
+#
+zabbix ALL=NOPASSWD: /etc/zabbix/scripts/apt

+ 1 - 0
plugins/client/checkrestart/conf/checkrestart.conf

@@ -0,0 +1 @@
+UserParameter=debian.checkrestart,sudo /etc/zabbix/scripts/checkrestart

+ 7 - 0
plugins/client/checkrestart/scripts/checkrestart

@@ -0,0 +1,7 @@
+#!/bin/sh
+
+export LANG=C
+
+checkrestart 2>/dev/null| head -n 1 | sed -r 's/^Found ([0-9]+) processes using old versions of upgraded files$/\1/'
+
+exit 0

+ 4 - 0
plugins/client/checkrestart/sudo/checkrestart

@@ -0,0 +1,4 @@
+#
+# Permit to zabbix user to execute 'checkrestart' plugin
+#
+zabbix ALL=NOPASSWD: /etc/zabbix/scripts/checkrestart

+ 7 - 0
plugins/client/nginx/conf/nginx.conf

@@ -0,0 +1,7 @@
+UserParameter=nginx.active,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i active
+UserParameter=nginx.accepted,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i accepted
+UserParameter=nginx.handled,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i handled
+UserParameter=nginx.requests,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i requests
+UserParameter=nginx.reading,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i reading
+UserParameter=nginx.writing,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i writing
+UserParameter=nginx.waiting,/etc/zabbix/scripts/nginx-status -u http://localhost/nginx_status -i waiting

+ 84 - 0
plugins/client/nginx/scripts/nginx-status

@@ -0,0 +1,84 @@
+#!/bin/sh
+
+URL=""
+INFO=""
+CRAWLER=""
+
+INFOS="active accepted handled requests reading writing waiting"
+
+usage() {
+cat <<EOH
+USAGE: $(basename "$0") -u URL -i STATUS_INFO
+
+Get Nginx status
+
+Options:
+    -u  Nginx status URL (e.g: http://localhost/nginx_status
+    -i  Status info in $(echo "${INFOS}" | sed 's/ /, /g')
+EOH
+}
+
+while getopts "u:i:" OPT ; do
+    case "$OPT" in 
+        \?|h)
+            usage
+            exit 0
+            ;;
+        u)
+            URL="$OPTARG"
+            ;;
+        i)
+            INFO="$OPTARG"
+            ;;
+    esac
+done
+
+if which curl >/dev/null 2>&1 ; then
+    CRAWLER="curl -s"
+elif which wget >/dev/null 2>&1 ; then
+    CRAWLER="wget -q -O -"
+else
+    printf "[ERR] wget or curl not found\n"
+    usage
+    exit 1
+fi
+
+if [ -z "${URL}" ]; then
+    printf "[ERR] URL not defined or empty\n"
+    usage
+    exit 1
+fi
+
+if ! echo "${INFO}" | egrep -q "^($(echo "${INFOS}" | sed 's/ /|/g'))$"; then
+    printf "[ERR] info '${INFO}' not available in ${INFOS}\n"
+    usage
+    exit 1
+fi
+
+
+case "${INFO}" in
+    #INFOS="active accepted handled requests reading writing waiting"
+    active)
+        $CRAWLER "${URL}" | sed -r -n 's/^Active connections:\s+//p'
+        ;;
+    accepted)
+        $CRAWLER "${URL}" | sed -r -n 's/^\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)/\1/p'
+        ;;
+    handled)
+        $CRAWLER "${URL}" | sed -r -n 's/^\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)/\2/p'
+        ;;
+    requests)
+        $CRAWLER "${URL}" | sed -r -n 's/^\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)/\3/p'
+        ;;
+    reading)
+        $CRAWLER "${URL}" | sed -r -n 's/^Reading:\s+([0-9]+)\s+Writing:\s+([0-9]+)\s+Waiting:\s+([0-9]+)\s+$/\1/p'
+        ;;
+    writing)
+        $CRAWLER "${URL}" | sed -r -n 's/^Reading:\s+([0-9]+)\s+Writing:\s+([0-9]+)\s+Waiting:\s+([0-9]+)\s+$/\2/p'
+        ;;
+    waiting)
+        $CRAWLER "${URL}" | sed -r -n 's/^Reading:\s+([0-9]+)\s+Writing:\s+([0-9]+)\s+Waiting:\s+([0-9]+)\s+$/\3/p'
+        ;;
+esac
+
+exit 0

+ 1 - 0
plugins/client/ssl-discovery/conf/ssl-discovery.conf

@@ -0,0 +1 @@
+UserParameter=ssl.discovery,/etc/zabbix/scripts/yaml2json /etc/zabbix/zabbix_plugins.conf.d/ssl-discovery.yml

+ 54 - 0
plugins/client/utils/scripts/yaml2json

@@ -0,0 +1,54 @@
+#!/usr/bin/python3
+# coding: utf-8
+
+# {{{ Imports
+import sys
+import argparse
+import yaml
+import json
+import traceback
+# }}}
+
+# {{{ Constants
+_NAME = "yaml2json"
+_DESC = "Convert yaml data to zabbix json discovery format"
+_VERSION = "0.1"
+# }}}
+
+# {{{ main
+def main():
+    parser = argparse.ArgumentParser(prog=_NAME, description=_DESC)
+    parser.add_argument('-v', '--version', action='version',
+                        version='%(prog)s ' + _VERSION)
+    parser.add_argument('-d', '--debug', dest='debug', default=False, action='store_true',
+                        help='Print additional debug informations: traceback, etc. (default: no)')
+    parser.add_argument('datafile')
+    options = parser.parse_args()
+    try:
+        data = {'data': []}
+        with open(options.datafile) as f:
+            datayml = yaml.safe_load(f)
+            if datayml is not None:
+                for section in datayml:
+                    localdata = {
+                        '{#KEY}': section,
+                    }
+                    for k in datayml[section]:
+                        localdata['{#%s}' % (k.upper())] = datayml[section][k]
+                    data['data'].append(localdata)
+        print(json.dumps(data, indent=4))
+    except Exception as e:
+        if not options.debug:
+            print('Exception raised (use --debug option to get more info): %s' % (unicode(e)))
+        else:
+            print('Exception raised: %s' % (e))
+            traceback.print_exc(file=sys.stderr)
+        sys.exit(-1)
+# }}}
+
+# {{{ __main__
+if __name__ == "__main__":
+    main()
+# }}}
+
+# vim: foldmethod=marker foldlevel=0 foldenable

+ 2 - 0
plugins/client/web-discovery/conf/web-discovery.conf

@@ -0,0 +1,2 @@
+UserParameter=web.availability.discovery,/etc/zabbix/scripts/yaml2json /etc/zabbix/zabbix_plugins.conf.d/web-availability-discovery.yml
+UserParameter=web.metrics.discovery,/etc/zabbix/scripts/yaml2json /etc/zabbix/zabbix_plugins.conf.d/web-metrics-discovery.yml

+ 46 - 0
plugins/server/icmp-checker/scripts/icmp-checker

@@ -0,0 +1,46 @@
+#!/bin/sh
+
+ZBX_SERVER_ADDR="127.0.0.1"
+ZBX_SERVER_PORT="10051"
+
+HOST_IP="${1}"
+HOST_NAME="${2}"
+PING_COUNT="${3}"
+PING_INTERVAL="${4}"
+NOFORK="${5}"
+
+if [ $# -lt 4 ]; then
+    printf "Wrong parameter count\n" >&2
+    printf "Usage: $(basename "${0}") <HOST_IP> <ZABBIX_HOST_NAME> <NUMBERS_OF_PING_REQUESTS> <INTERVAL> [<NOFORK>]\n" >&2
+    exit 2
+fi
+
+if [ "${NOFORK}" != 1 ]; then
+    start-stop-daemon --background --start --exec $(readlink -f "${0}") -- "${HOST_IP}" "${HOST_NAME}" "${PING_COUNT}" "${PING_INTERVAL}" 1
+else
+read ping_loss ping_min ping_max ping_avg <<EOC
+$(fping -c "${PING_COUNT}" -q -p "${PING_INTERVAL}" "${HOST_IP}" 2>&1 | sed -r 's#.*([0-9\.])%, min/avg/max = ([0-9\.]+)/([0-9\.]+)/([0-9\.]+)$#\1 \2 \3 \4#')
+EOC
+    if zabbix_sender -z "${ZBX_SERVER_ADDR}" -p "${ZBX_SERVER_PORT}" -s "${HOST_NAME}" -k PingLoss -o "${ping_loss}" | grep -v 'sent:' | grep -q -v 'failed: 0'; then
+        echo 0
+        exit 1
+    fi
+
+    if zabbix_sender -z "${ZBX_SERVER_ADDR}" -p "${ZBX_SERVER_PORT}" -s "${HOST_NAME}" -k PingLatencyMin -o "${ping_min}" | grep -v 'sent:' | grep -q -v 'failed: 0'; then
+        echo 0
+        exit 1
+    fi
+
+    if zabbix_sender -z "${ZBX_SERVER_ADDR}" -p "${ZBX_SERVER_PORT}" -s "${HOST_NAME}" -k PingLatencyMax -o "${ping_max}" | grep -v 'sent:' | grep -q -v 'failed: 0'; then
+        echo 0
+        exit 1
+    fi
+
+    if zabbix_sender -z "${ZBX_SERVER_ADDR}" -p "${ZBX_SERVER_PORT}" -s "${HOST_NAME}" -k PingLatencyAvg -o "${ping_avg}" | grep -v 'sent:' | grep -q -v 'failed: 0'; then
+        echo 0
+        exit 1
+    fi
+fi
+
+echo 1
+exit 0

+ 95 - 0
plugins/server/ssl/scripts/ssl

@@ -0,0 +1,95 @@
+#!/bin/sh
+
+RESULT=1
+CAPATH="/etc/ssl/certs"
+DATE_CHECK=0
+
+usage() {
+cat <<EOH
+USAGE: $(basename "$0") [-t] -u URI
+
+Options:
+    -u  Specify the URI to check
+    -t  Count and print the certificate expiration interval in days
+
+URI Examples:
+  - tls+smtp://smtp.googlemail.com:submission
+  - tls+imap://imap.no-log.org:imap
+  - ssl://imap.free.fr:imaps
+  - ssl://pop.free.fr:pop3s
+  - tls+xmpp://jabber.org:xmpp-client
+  - ssl://www.google.com:https
+
+Return:
+  print 0 on stdout if the certificate is valid
+  print 1 on stdout if the certificate is not valid
+  print the certificate expiration interval in days (only with option -t)
+EOH
+}
+
+while getopts htu: option ; do
+    case "${option}" in
+        h)
+            usage
+            exit 1
+            ;;
+        t)
+            DATE_CHECK=1
+            ;;
+        u)
+            URI="${OPTARG}"
+        ;;
+    esac
+done
+
+if [ -z "${URI}" ]; then
+    printf "Error: URI not found\n\n" >&2
+    usage
+    exit 1
+fi
+
+eval $(echo "${URI}" | sed -r -n 's/^(ssl|tls)(\+(.+))?:\/\/([^:]+)(:([^:]+))?$/layer="\1"\nproto="\3"\nhost="\4"\nport="\6"/p')
+
+tls_opts=
+if [ "${layer}" = "tls" ] && [ "${proto}" != "" ]; then
+    tls_opts="$tls_opts -starttls ${proto}"
+fi
+
+certs_data=$(mktemp -t "$(basename "$(readlink -f "${0}")")-certs.XXXXXXXX")
+errors_log=$(mktemp -t "$(basename "$(readlink -f "${0}")")-errors.XXXXXXXX")
+
+openssl s_client \
+    -CApath "${CAPATH}" \
+    -servername "${host}" \
+    -connect "${host}:${port}" \
+    ${tls_opts} \
+    -showcerts < /dev/null 2>"${errors_log}" > "${certs_data}"
+
+if [ $? != 0 ]; then
+    printf "Error (openssl): %s\n" "$(head -n 2 "${errors_log}" | tr '\n' ',')" >&2
+    exit 1
+fi
+
+if [ "${DATE_CHECK}" = 1 ]; then
+    cert_enddate="$(sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' < "${certs_data}" | openssl x509 -text 2>/dev/null | sed -n 's/ *Not After : *//p')"
+    if [ -z "${cert_enddate}" ]; then
+        printf "Error: unable to find certificate end date\n" >&2
+        exit 1
+    fi
+    cert_enddate_seconds=$(date '+%s' --date "${cert_enddate}")
+    now_seconds=$(date '+%s')
+    diff_seconds=$(( ${cert_enddate_seconds} - ${now_seconds} ))
+    diff_days=$(( ${diff_seconds} / 3600 / 24 ))
+    RESULT="${diff_days}"
+else
+    return_code=$(cat "${certs_data}" | sed -r -n 's/^\s*Verify return code: ([0-9]+) (.*)$/\1/p')
+    if [ "${return_code}" = 0 ]; then
+        RESULT=0
+    fi
+fi
+
+rm -f "${certs_data}" "${errors_log}"
+
+printf "${RESULT}\n"
+
+exit 0

+ 5 - 0
plugins/server/ssl/scripts/ssl-expiration

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+$(dirname "$(readlink -f "${0}")")/ssl -t -u "${1}"
+
+exit 0

+ 5 - 0
plugins/server/ssl/scripts/ssl-validity

@@ -0,0 +1,5 @@
+#!/bin/sh
+
+$(dirname "$(readlink -f "${0}")")/ssl -u "${1}"
+
+exit 0

+ 92 - 0
plugins/server/web-checker/scripts/web-checker

@@ -0,0 +1,92 @@
+#!/usr/bin/python3
+# coding: utf-8
+
+# {{{ Installation notes
+# To get it working (SNI support) on debian wheezy:
+# - apt-get install python3-openssl python3-minimal
+# - apt-get install -t wheezy-backports python3-requests python3-urllib3
+# }}}
+
+# {{{ Imports
+import sys
+import re
+import argparse
+import requests
+import traceback
+import time
+# }}}
+
+# {{{ Constants
+_NAME = "web-checker"
+_DESC = "tool to check web page content"
+_VERSION = "0.1"
+# }}}
+
+# {{{ WebPage
+class WebPage(object):
+
+    _options = None
+    _elapsed = 0
+
+    def __init__(self, options):
+        self._options = options
+
+    def elapsed(self):
+        return "%.3f" % (self._elapsed)
+
+    def check(self):
+        start_time = time.time()
+        r = requests.get(self._options.url,
+                timeout=self._options.timeout,
+                verify=not self._options.no_ssl_verify)
+        self._elapsed = time.time() - start_time
+        if r.status_code != self._options.status:
+            raise AssertionError('Wrong HTTP code returned: %d != %d' % (r.status_code, self._options.status))
+        if self._options.regexp is not None:
+            try:
+                exp = re.compile(self._options.regexp)
+            except:
+                raise ValueError('Content regex is invalid: %s' % (self._options.regexp))
+            matched = False
+            if hasattr(r, 'text') and r.text is not None and exp.findall(r.text) != []:
+                matched = True
+            elif hasattr(r, 'content') and r.content is not None and exp.findall(r.content) != []:
+                matched = True
+            if not matched:
+                raise AssertionError('Web page content do not match regexp: %s' % (self._options.regexp))
+# }}}
+
+# {{{ main
+def main():
+    parser = argparse.ArgumentParser(prog=_NAME, description=_DESC)
+    parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + _VERSION )
+    parser.add_argument('-d', '--debug', dest='debug', default=False, action='store_true',
+            help='Print additional debug informations: traceback, etc. (default: no)')
+    parser.add_argument('-t', '--timeout', dest='timeout', default=5, type=int, help='Timeout in seconds')
+    parser.add_argument('-s', '--status', dest='status', default=200, type=int, help='Expected HTTP status')
+    parser.add_argument('-r', '--regexp', dest='regexp', default=None, help='Regexp matching for web page content')
+    parser.add_argument('-n', '--no-ssl-verify', dest='no_ssl_verify', default=False, action='store_true', help='Disable SSL certificate verification')
+    parser.add_argument('-E', '--elapsed', dest='elapsed', default=False, action='store_true', help='Return elapsed time instead of status')
+
+    parser.add_argument('url')
+    options = parser.parse_args()
+    result = None
+    try:
+        w = WebPage(options)
+        w.check()
+        result = w.elapsed() if options.elapsed else 0
+    except Exception as e:
+        result = '' if options.elapsed else 1
+        if options.debug:
+            print('Exception raised: %s' % (e))
+            traceback.print_exc(file=sys.stderr)
+            sys.exit(-1)
+    print(result)
+# }}}
+
+# {{{ __main__
+if __name__ == "__main__":
+    main()
+# }}}
+
+# vim: foldmethod=marker foldlevel=0 foldenable