Diese Seite beschreibt die Installation und Ersteinrichtung der [[WikiPediaDe:Netzmanagement|Monitoring]]-Software [[https://icinga.com|Icinga 2]] und der Weboberfläche Icinga Web 2 und Debian Stretch. <> = Installation = * Neben den eigentlichen Icinga-Paketen werden noch die [[https://www.monitoring-plugins.org/|Monitoring Plugins]] benötigt, welche die regelmäßigen Prüfungen ausführen:{{{ apt install icinga2 monitoring-plugins }}} * Nach der Installation findest du eine Beispielkonfiguration zur Überwachung des eigenen Hosts unter {{{/etc/icinga2/conf.d}}} * Mit Hilfe von Icinga Web 2 kannst du die Ergebnisse der Prüfungen übersichtlich im Browser betrachten und Icinga darüber auch steuern * Für die Kommunikation zwischen Icinga 2 und der Weboberfläche wird der Icinga Data Output, kurz IDO, genutzt. Icinga 2 schreibt die durch die Prüfungen ermittelten Werte in eine Datenbank, die von der Weboberfläche ausgelesen wird. Nachfolgend wird die Installation mit einer MariaDB-Datenbank beschrieben:{{{ apt install icinga2-ido-mysql mariadb-server}}} = Ersteinrichtung = * Zuerst muss das IDO-Feature aktiviert und Icinga neu initialisiert werden:{{{ icinga2 feature list icinga2 feature enable ido-mysql systemctl reload icinga2 }}} * Icinga 2 besitzt eine API, die es ermöglicht, Icinga 2 über die Weboberfläche zu steuern. Die API wird mit Hilfe des Wizards eingerichtet:{{{ icinga2 api setup }}} * Nun sollte ein API-Account mit eingeschränkten Rechten einrichtet werden, der von der Weboberfläche genutzt wird. Diese wird in der Datei {{{/etc/icinga2/confd/api-users.conf}}} definiert. Da dieser API-Account keinen Vollzugriff benötigt, werden seine Zugriffsrechte beschränkt:{{{ object ApiUser "icingaweb2" { password = "Ultr4!Sich3r3s:P4ssw0rt" permissions = [ "status/query", "actions/*", "objects/modify/*", "objects/query/*" ] } }}} * Nun kann Icinga Web 2 installiert werden:{{{ apt install icingaweb2 icingacli php-curl}}} * Für PHP benötigt Icinga Web 2 eine gesetzte Zeitzone. Diese kann in der entsprechenden {{{php.ini}}}, bspw. unter {{{/etc/php/7.0/apache2/php.ini}}} angegeben werden:{{{ date.timezone = Europe/Berlin}}} * Nach dem Aufruf der Weboberfläche unter {{{/icingaweb2}}} kann der Einrichtungsassistent gestartet werden. Dieser verlangt die Authentifizierung mittels eines Tokens. Dies wird auf der Kommandezeile erzeugt:{{{ icingacli setup token create}}} * Nun müssen im Einrichtungsassistenten einige Angaben gemacht werden. Unter '''Database Ressource''' werden die Informationen zur Account-Datenbank angegeben. Diese muss vor dem nächsten Schritt noch manuell angelegt werden, bspw:{{{ CREATE DATABASE icingaweb2; GRANT ALL ON icingaweb2.* TO 'icingaweb2'@'localhost' IDENTIFIED BY 'N0ch-3in_Ultr4!Sich3r3s:P4ssw0rt';}}} * Beim Schritt '''Command Transport''' werden die Daten zum kürzlich angelegten API-Account eingetragen. = Benachrichtigungen per XMPP = * Standardmäßig ist Icinga 2 zum Versand von Benachrichtigungen per E-Mail konfiguriert. * Der Versand von XMPP-Nachrichten ist im folgenden Beispiel im Wesentlichen eine Kopie der Mail-Konfiguration, ergänzt um die Angaben zum XMPP-Server und den zu nutzenden Accounts. * Der eigentliche Versand wird von DebianPackage:sendxmpp durchgeführt. Weiterhin wird DebianPackage:uuid benötigt, damit zufällige XMPP-Resourcen erzeugt werden. Andernfalls kann es zu Verbindungabbrüchen<> des versendenen XMPP-Servers kommen. * Zuerst legen wir ein Template an - {{{/etc/icinga2/conf.d/templates.conf}}}:{{{ template Notification "xmpp-host-notification" { command = "xmpp-host-notification" states = [ Up, Down ] types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] period = "24x7" } template Notification "xmpp-service-notification" { command = "xmpp-service-notification" states = [ OK, Warning, Critical, Unknown ] types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart, FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ] period = "24x7" } }}} * Anschließend wird das !NotificationCommand für Host- und Service-Nachrichten unter {{{/etc/icinga2/conf.d/commands.conf}}} definiert:{{{ object NotificationCommand "xmpp-host-notification" { command = [ SysconfDir + "/icinga2/scripts/xmpp-host-notification.sh" ] env = { NOTIFICATIONTYPE = "$notification.type$" HOSTALIAS = "$host.display_name$" HOSTADDRESS = "$address$" HOSTSTATE = "$host.state$" LONGDATETIME = "$icinga.long_date_time$" HOSTOUTPUT = "$host.output$" NOTIFICATIONAUTHORNAME = "$notification.author$" NOTIFICATIONCOMMENT = "$notification.comment$" HOSTDISPLAYNAME = "$host.display_name$" XMPP_SENDER = XMPP_Sender XMPP_HOST = XMPP_Host XMPP_PASSWORD = XMPP_Password USERXMPPID = "$user.vars.xmppid$" } } object NotificationCommand "xmpp-service-notification" { command = [ SysconfDir + "/icinga2/scripts/xmpp-service-notification.sh" ] env = { NOTIFICATIONTYPE = "$notification.type$" SERVICEDESC = "$service.name$" HOSTALIAS = "$host.display_name$" HOSTADDRESS = "$address$" SERVICESTATE = "$service.state$" LONGDATETIME = "$icinga.long_date_time$" SERVICEOUTPUT = "$service.output$" NOTIFICATIONAUTHORNAME = "$notification.author$" NOTIFICATIONCOMMENT = "$notification.comment$" HOSTDISPLAYNAME = "$host.display_name$" SERVICEDISPLAYNAME = "$service.display_name$" XMPP_SENDER = XMPP_Sender XMPP_HOST = XMPP_Host XMPP_PASSWORD = XMPP_Password USERXMPPID = "$user.vars.xmppid$" } } }}} * Die Zugangsdaten für den XMPP-Account, über den die Nachrichten verschickt werden, werden zentral in der {{{/etc/icinga2/constants.conf}}} festgelegt:{{{ const XMPP_Sender = "monitor" const XMPP_Host = "jabber.example.org" const XMPP_Password = "Yw7bfKiHZbKcyrs3dxC"}}} * Die User-Konfiguration wird um die Variable ''xmppid'' ergänzt, die zur Angabe des jeweiligen XMPP-Accounts dient - {{{/etc/icinga2/conf.d/users.conf}}}:{{{ object User "Admin" { import "generic-user" email = "admin@example.org" vars.xmppid = "admin@jabber.example.org" groups = [ "admins" ] } }}} * Alle Hosts, für die XMPP-Nachrichten verschickt werden sollen, erhalten eine Variable, die später ausgewertet werden kann - {{{/etc/icinga2/conf.d/hosts.conf}}}:{{{ object Host NodeName { import "generic-host" address = "127.0.0.1" ... vars.notification["xmpp"] = { groups = [ "admins" ] } } }}} * Nun werden die Notification-Regeln erstellt - {{{/etc/icinga2/conf.d/notifications.conf}}}:{{{ apply Notification "xmpp-host" to Host { import "xmpp-host-notification" user_groups = host.vars.notification.xmpp.groups assign where host.vars.notification.xmpp } apply Notification "xmpp-service" to Service { import "xmpp-service-notification" user_groups = host.vars.notification.xmpp.groups assign where host.vars.notification.xmpp } }}} * Abschließend werden die Skripte zum eigentlichen Versand der Nachrichten angelegt - {{{/etc/icinga2/scripts/xmpp-host-notification.sh}}}:{{{ #!sh #!/bin/bash PROG="`basename $0`" ICINGA2HOST="`hostname`" XMPPBIN="sendxmpp" UUIDBIN="/usr/bin/uuid" if [ -z "`which $XMPPBIN`" ] ; then echo "$XMPPBIN not found in \$PATH. Consider installing it." exit 1 fi if [ -z "`which $UUIDBIN`" ] ; then echo "$UUIDBIN not found in \$PATH. Consider installing it." exit 1 fi ## Function helpers Usage() { cat << EOF Required parameters: -d LONGDATETIME (\$icinga.long_date_time\$) -l HOSTNAME (\$host.name\$) -n HOSTDISPLAYNAME (\$host.display_name\$) -o HOSTOUTPUT (\$host.output\$) -s HOSTSTATE (\$host.state\$) -t NOTIFICATIONTYPE (\$notification.type\$) Optional parameters: -4 HOSTADDRESS (\$address\$) -6 HOSTADDRESS6 (\$address6\$) -b NOTIFICATIONAUTHORNAME (\$notification.author\$) -c NOTIFICATIONCOMMENT (\$notification.comment\$) -i ICINGAWEB2URL (\$notification_icingaweb2url\$, Default: unset) -v (\$notification_sendtosyslog\$, Default: false) EOF } Help() { Usage; exit 0; } Error() { if [ "$1" ]; then echo $1 fi Usage; exit 1; } urlencode() { local LANG=C i c e='' for ((i=0;i<${#1};i++)); do c=${1:$i:1} [[ "$c" =~ [a-zA-Z0-9\.\~\_\-] ]] || printf -v c '%%%02X' "'$c" e+="$c" done echo "$e" } ## Main while getopts 4:6::b:c:d:f:h:i:l:n:o:s:t:v: opt do case "$opt" in 4) HOSTADDRESS=$OPTARG ;; 6) HOSTADDRESS6=$OPTARG ;; b) NOTIFICATIONAUTHORNAME=$OPTARG ;; c) NOTIFICATIONCOMMENT=$OPTARG ;; d) LONGDATETIME=$OPTARG ;; # required h) Help ;; i) ICINGAWEB2URL=$OPTARG ;; l) HOSTNAME=$OPTARG ;; # required n) HOSTDISPLAYNAME=$OPTARG ;; # required o) HOSTOUTPUT=$OPTARG ;; # required s) HOSTSTATE=$OPTARG ;; # required t) NOTIFICATIONTYPE=$OPTARG ;; # required v) VERBOSE=$OPTARG ;; \?) echo "ERROR: Invalid option -$OPTARG" >&2 Error ;; :) echo "Missing option argument for -$OPTARG" >&2 Error ;; *) echo "Unimplemented option: -$OPTARG" >&2 Error ;; esac done shift $((OPTIND - 1)) ## Keep formatting in sync with xmpp-service-notification.sh for P in LONGDATETIME HOSTNAME HOSTDISPLAYNAME HOSTOUTPUT HOSTSTATE NOTIFICATIONTYPE ; do eval "PAR=\$${P}" if [ ! "$PAR" ] ; then Error "Required parameter '$P' is missing." fi done ## Build the notification message NOTIFICATION_MESSAGE=`cat << EOF ***** Host Monitoring on $ICINGA2HOST ***** $HOSTDISPLAYNAME is $HOSTSTATE! Info: $HOSTOUTPUT When: $LONGDATETIME Host: $HOSTNAME EOF ` ## Check whether IPv4 was specified. if [ -n "$HOSTADDRESS" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE IPv4: $HOSTADDRESS" fi ## Check whether IPv6 was specified. if [ -n "$HOSTADDRESS6" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE IPv6: $HOSTADDRESS6" fi ## Check whether author and comment was specified. if [ -n "$NOTIFICATIONCOMMENT" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE Comment by $NOTIFICATIONAUTHORNAME: $NOTIFICATIONCOMMENT" fi ## Check whether Icinga Web 2 URL was specified. if [ -n "$ICINGAWEB2URL" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE $ICINGAWEB2URL/monitoring/host/show?host=$(urlencode "$HOSTNAME")" fi ## Check whether verbose mode was enabled and log to syslog. if [ "$VERBOSE" == "true" ] ; then logger "$PROG sends $HOSTDISPLAYNAME is $HOSTSTATE => $USERXMPPID" fi ## Send the notification using the $XMPPBIN command. run_sendxmpp() { /usr/bin/sendxmpp --file=/dev/null --tls -v \ "--username=$XMPP_SENDER" "--password=$XMPP_PASSWORD" "--jserver=$XMPP_HOST" --resource="$("$UUIDBIN")" "$USERXMPPID" } if ! output=$( { /usr/bin/printf "%b" "$NOTIFICATION_MESSAGE" | run_sendxmpp; } 2>&1); then printf 'Date: %s\nOutput: %s\nComment: %s\nTo: %s\n\n' "$(date)" "$output" "$(echo "$NOTIFICATION_MESSAGE" | tail -1)" "$USERXMPPID" >>/var/log/icinga2/xmpp-send-errors.log fi }}} * Für die Service-Nachrichten - {{{/etc/icinga2/scripts/xmpp-service-notification.sh}}}:{{{ #!sh #!/bin/bash PROG="`basename $0`" ICINGA2HOST="`hostname`" XMPPBIN="sendxmpp" UUIDBIN="/usr/bin/uuid" if [ -z "`which $XMPPBIN`" ] ; then echo "$XMPPBIN not found in \$PATH. Consider installing it." exit 1 fi if [ -z "`which $UUIDBIN`" ] ; then echo "$UUIDBIN not found in \$PATH. Consider installing it." exit 1 fi ## Function helpers Usage() { cat << EOF Required parameters: -d LONGDATETIME (\$icinga.long_date_time\$) -e SERVICENAME (\$service.name\$) -l HOSTNAME (\$host.name\$) -n HOSTDISPLAYNAME (\$host.display_name\$) -o SERVICEOUTPUT (\$service.output\$) -s SERVICESTATE (\$service.state\$) -t NOTIFICATIONTYPE (\$notification.type\$) -u SERVICEDISPLAYNAME (\$service.display_name\$) Optional parameters: -4 HOSTADDRESS (\$address\$) -6 HOSTADDRESS6 (\$address6\$) -b NOTIFICATIONAUTHORNAME (\$notification.author\$) -c NOTIFICATIONCOMMENT (\$notification.comment\$) -i ICINGAWEB2URL (\$notification_icingaweb2url\$, Default: unset) -v (\$notification_sendtosyslog\$, Default: false) EOF } Help() { Usage; exit 0; } Error() { if [ "$1" ]; then echo $1 fi Usage; exit 1; } urlencode() { local LANG=C i c e='' for ((i=0;i<${#1};i++)); do c=${1:$i:1} [[ "$c" =~ [a-zA-Z0-9\.\~\_\-] ]] || printf -v c '%%%02X' "'$c" e+="$c" done echo "$e" } ## Main while getopts 4:6:b:c:d:e:h:i:l:n:o:s:t:u:v: opt do case "$opt" in 4) HOSTADDRESS=$OPTARG ;; 6) HOSTADDRESS6=$OPTARG ;; b) NOTIFICATIONAUTHORNAME=$OPTARG ;; c) NOTIFICATIONCOMMENT=$OPTARG ;; d) LONGDATETIME=$OPTARG ;; # required e) SERVICENAME=$OPTARG ;; # required h) Usage ;; i) ICINGAWEB2URL=$OPTARG ;; l) HOSTNAME=$OPTARG ;; # required n) HOSTDISPLAYNAME=$OPTARG ;; # required o) SERVICEOUTPUT=$OPTARG ;; # required s) SERVICESTATE=$OPTARG ;; # required t) NOTIFICATIONTYPE=$OPTARG ;; # required u) SERVICEDISPLAYNAME=$OPTARG ;; # required v) VERBOSE=$OPTARG ;; \?) echo "ERROR: Invalid option -$OPTARG" >&2 Usage ;; :) echo "Missing option argument for -$OPTARG" >&2 Usage ;; *) echo "Unimplemented option: -$OPTARG" >&2 Usage ;; esac done shift $((OPTIND - 1)) ## Keep formatting in sync with xmpp-host-notification.sh for P in LONGDATETIME HOSTNAME HOSTDISPLAYNAME SERVICENAME SERVICEDISPLAYNAME SERVICEOUTPUT SERVICESTATE NOTIFICATIONTYPE ; do eval "PAR=\$${P}" if [ ! "$PAR" ] ; then Error "Required parameter '$P' is missing." fi done ## Build the notification message NOTIFICATION_MESSAGE=`cat << EOF ***** Service Monitoring on $ICINGA2HOST ***** $SERVICEDISPLAYNAME on $HOSTDISPLAYNAME is $SERVICESTATE! Info: $SERVICEOUTPUT When: $LONGDATETIME Service: $SERVICENAME Host: $HOSTNAME EOF ` ## Check whether IPv4 was specified. if [ -n "$HOSTADDRESS" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE IPv4: $HOSTADDRESS" fi ## Check whether IPv6 was specified. if [ -n "$HOSTADDRESS6" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE IPv6: $HOSTADDRESS6" fi ## Check whether author and comment was specified. if [ -n "$NOTIFICATIONCOMMENT" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE Comment by $NOTIFICATIONAUTHORNAME: $NOTIFICATIONCOMMENT" fi ## Check whether Icinga Web 2 URL was specified. if [ -n "$ICINGAWEB2URL" ] ; then NOTIFICATION_MESSAGE="$NOTIFICATION_MESSAGE $ICINGAWEB2URL/monitoring/service/show?host=$(urlencode "$HOSTNAME")&service=$(urlencode "$SERVICENAME")" fi ## Check whether verbose mode was enabled and log to syslog. if [ "$VERBOSE" == "true" ] ; then logger "$PROG sends $SERVICEDISPLAYNAME on $HOSTDISPLAYNAME is $SERVICESTATE => $USERXMPPID" fi run_sendxmpp() { /usr/bin/sendxmpp --file=/dev/null --tls \ "--username=$XMPP_SENDER" "--password=$XMPP_PASSWORD" "--jserver=$XMPP_HOST" --resource="$("$UUIDBIN")" "$USERXMPPID" } if ! output=$( { /usr/bin/printf "%b" "$NOTIFICATION_MESSAGE" | run_sendxmpp; } 2>&1); then printf 'Date: %s\nOutput: %s\nComment: %s\nTo: %s\n\n' "$(date)" "$output" "$(echo "$NOTIFICATION_MESSAGE" | tail -1)" "$USERXMPPID" >>/var/log/icinga2/xmpp-send-errors.log fi }}} ---- '''Fussnoten und Hinweise''' * [[https://community.icinga.com/t/umlauts-and-special-characters-in-icingaweb2/6415/5|Korrekte Darstellung von Umlauten]] in Icinga Web 2