Icinga2 – check_mssql_health

Das check_mssql_health Modul kann in Icinga2, als auch in Nagios dazu verwendet werden, seine MSSQL Datenbank zu überwachen. Dabei können Checks von Verbindungszeiten, Deadlocks, angemeldete User, existierende Tabellen und viele weitere ausgewählt werden. So macht es das Modul zu einem starken Tool für die Datenbanken. Leider wird check_mssql_health nicht bei der icinga2 respektive nagios mit installiert und muss manuell nachgeholt werden. Ich rede hier von der Installation über den Packet Manager. Die Installation dabei ist aber relativ einfach. Ich gehe davon aus, dass Icinga aus dem Repository heruntergeladen und nach Standard Parametern installiert worden ist.

 

 

Vorbereitung

Um mssql_health vollständig und erfolgreich installieren zu können, müssen einige Vorbereitungen getroffen werden, die ich hier kurz erläutere. Zunächst müssen ein paar Pakete nachinstalliert werden.

apt install libdbd-sybase-perl freetds-common freetds-dev freetds-bin

Dann laden wir die aktuelle mssql_health Version mit wget runter, was in meinem Fall(10.11.2018) die Version 2.6.4.14 ist.

wget https://labs.consol.de/assets/downloads/nagios/check_mssql_health-2.6.4.14.tar.gz

Natürlich müssen wir die tar.gz jetzt noch entpacken und gehen direkt in das neu erstellte Verzeichnis hinein.

tar xvzf check_mssql_health_2.6.4.14
cd check_mssql_health_2.6.4.14

Sobald wir im Verzeichnis sind, fangen wir an mssql_health zu kompilieren. Ich benutze jeweils die default Parameter. Änderungen können sonst mit dem ./configure Command geändert werden.

./configure
make
make install

Wenn die Kompilierung abgeschlossen und das Modul installiert ist, sollten wir überprüfen, ob es nicht doch noch eigene Syntax Errors im Perl Code gibt. Wenn alles soweit in OK ist, kopieren wir das Script in das jeweilige Icinga Verzeichnis

cd plugin-scripts/
perl -c check_mssql_health
cp check_mssql_health /usr/lib/Nagios/plugins

Zuguterletzt müssen wir eine Datenbank-Instanz in der freetds.conf einfügen. Dort ist schon ein Beispiel vorhanden, welches wir einfach für unsere Einstellungen übernehmen können. Falls dieser Eintrag übersprungen wird, kann keine Verbindung mit der Datenbank hergestellt werden.

nano /etc/freetds/freetds.conf

Aus Sicherheitsgründen sollten wir das TDS Protokoll noch auf Version 8.0 ändern. Die anderen Versionen verschicken Username/Passwort im Klartext. Somit hätten wir die Installation + Einrichtung des Modules vollzogen. Machen wir weiter mit der Konfiguration der Datenbank.

 

 

Datenbank einrichten

Das schöne an der Datenbank Einrichtung ist, dass wir hier nicht viel machen müssen. Auf der Projekt Seite steht ein vorgefertigtes Script zur Verfügung. Es ist zu empfehlen sich einen SQL-Benutzer anzulegen und diesen in der dafür vorgesehenen Stelle im Script anzugeben.

declare @dbname varchar(255)
declare @check_mssql_health_USER varchar(255)
declare @check_mssql_health_PASS varchar(255)
declare @check_mssql_health_ROLE varchar(255)
declare @source varchar(255)
declare @options varchar(255)
declare @backslash int

/*******************************************************************/
SET @check_mssql_health_USER = '"icinga"'
SET @check_mssql_health_PASS = 'password'
SET @check_mssql_health_ROLE = 'icinga'
/******************************************************************

PLEASE CHANGE THE ABOVE VALUES ACCORDING TO YOUR REQUIREMENTS

- Example for Windows authentication:
  SET @check_mssql_health_USER = '"[Servername|Domainname]\Username"'
  SET @check_mssql_health_ROLE = 'Rolename'

- Example for SQL Server authentication:
  SET @check_mssql_health_USER = 'Username'
  SET @check_mssql_health_PASS = 'Password'
  SET @check_mssql_health_ROLE = 'Rolename'

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
It is strongly recommended to use Windows authentication. Otherwise
you will get no reliable results for database usage.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

*********** NO NEED TO CHANGE ANYTHING BELOW THIS LINE *************/

SET @options = 'DEFAULT_DATABASE=MASTER, DEFAULT_LANGUAGE=English'
SET @backslash = (SELECT CHARINDEX('\', @check_mssql_health_USER))
IF @backslash > 0
  BEGIN
    SET @source = ' FROM WINDOWS'
    SET @options = ' WITH ' + @options
  END
ELSE
  BEGIN
    SET @source = ''
    SET @options = ' WITH PASSWORD=''' + @check_mssql_health_PASS + ''',' + @options
  END

PRINT 'create Nagios plugin user ' + @check_mssql_health_USER
EXEC ('CREATE LOGIN ' + @check_mssql_health_USER + @source + @options)
EXEC ('USE MASTER GRANT VIEW SERVER STATE TO ' + @check_mssql_health_USER)
EXEC ('USE MASTER GRANT ALTER trace TO ' + @check_mssql_health_USER)
EXEC ('USE MSDB GRANT SELECT ON sysjobhistory TO ' + @check_mssql_health_USER)
EXEC ('USE MSDB GRANT SELECT ON sysjobschedules TO ' + @check_mssql_health_USER)
EXEC ('USE MSDB GRANT SELECT ON sysjobs TO ' + @check_mssql_health_USER)
PRINT 'User ' + @check_mssql_health_USER + ' created.'
PRINT ''

declare dblist cursor for
  select name from sysdatabases WHERE name NOT IN ('master', 'tempdb', 'msdb') open dblist
    fetch next from dblist into @dbname
    while @@fetch_status = 0 begin
      EXEC ('USE [' + @dbname + '] print ''GRANT permissions IN the db '' + ''"'' + DB_NAME() + ''"''')
      EXEC ('USE [' + @dbname + '] CREATE ROLE ' + @check_mssql_health_ROLE)
      EXEC ('USE [' + @dbname + '] GRANT EXECUTE TO ' + @check_mssql_health_ROLE)
      EXEC ('USE [' + @dbname + '] GRANT VIEW DATABASE STATE TO ' + @check_mssql_health_ROLE)
      EXEC ('USE [' + @dbname + '] GRANT VIEW DEFINITION TO ' + @check_mssql_health_ROLE)
      EXEC ('USE [' + @dbname + '] CREATE USER ' + @check_mssql_health_USER + ' FOR LOGIN ' + @check_mssql_health_USER)
      EXEC ('USE [' + @dbname + '] EXEC sp_addrolemember ' + @check_mssql_health_ROLE + ' , ' + @check_mssql_health_USER)
      EXEC ('USE [' + @dbname + '] print ''Permissions IN the db '' + ''"'' + DB_NAME() + ''" GRANTED.''')
      fetch next from dblist into @dbname
    end
close dblist
deallocate dblist

Haben wir das Script ausgeführt, können wir außerhalb von Icinga testen, ob unsere Einstellungen soweit korrekt sind. Hierzu führen wir eine erste Überprüfung durch.

./check_mssql_health –server=wpsql3 –port=1433 –username=icinga –password=<password> --mode=locks-deadlocks –commit

Wenn dieser Check erfolgreich war, haben wir die Datenbank und das mssql_health modul korrekt installiert und eingerichtet. Jedoch fehlen noch die Änderungen in Icinga, damit dieser die Checks überhaupt ausführen kann. Ich hab es soweit eingerichtet, dass ich jedem Host mehrere Serviceobjekte von mssql_health zuweisen kann. Diese Objekte führen unterschiedliche Checks aus. Dazu habe ich einen Command angelegt, der bestimmte Parameter erwartet, aber auch solche die schon fest zugewiesen sind, wie Benutzername und Passwort.

object CheckCommand "checkmssql_health" {
   import "plugin-check-command"

   command = [PluginDir + "/check_mssql_health"]

   arguments = {
   "--server" = "$mssqlhealth_server$"
   "--username" = "$mssqlhealth_username$"
   "--password" = "$mssqlhealth_password$"
   "--mode" = "$mssqlhealth_mode$"
   "--critical" = "$mssqlhealth_critical$"
   "--warning" = "$mssqlhealth_warning$"
   "--commit" = ""

   }

   vars.mssqlhealth_username = "icinga"
   vars.mssqlhealth_password = "passwort"

}

Der erstellte Service geht dabei durch jedes, im Host Objekt angegebene, mssql_health Objekt.

apply Service "mssql_check_health" for (mode => config in host.vars.mssqlhealth_modes){
  import "generic-service"

  check_command = "checkmssql_health"

  vars.mssqlhealth_mode = mode

  vars+=config

  vars.mssqlhealth_critical = config.mssqlhealth_critical
  vars.mssqlhealth_warning = config.mssqlhealth_warning

   assign where ((host.address || host.address6) && host.vars.mssql == "true")
}

Mein Host Objekt sieht dementsprechend so aus und ist gefüllt mit mehreren Modis des Modules.

vars.mssqlhealth_modes["connected-users"] = {
     mssqlhealth_modes = "connected-users"
     mssqlhealth_warning = "1100"
     mssqlhealth_critical = "1500"
  }
vars.mssqlhealth_modes["locks-waits"] = {
     mssqlhealth_modes = "locks-waits"
     mssqlhealth_warning = "1"
     mssqlhealth_critical = "2"
  }
vars.mssqlhealth_modes["locks-deadlocks"] = {
     mssqlhealth_modes = "locks-deadlocks"
     mssqlhealth_warning = "1"
     mssqlhealth_critical = "2"
  }
vars.mssqlhealth_modes["database-backup-age"] = {
     mssqlhealth_modes = "database-backup-age"
     mssqlhealth_warning = "24"
     mssqlhealth_critical = "48"
  }

In „modes“ werden die verfügbaren Modis von mssql_health eingetragen, während die anderen beiden den jeweils kritischen und warnenden Zustand angeben.

Haben wir alles soweit eingerichtet muss selbstverständlich der Icinga Service neugestartet werden, damit die vollzogenen Änderungen überhaupt aktiv werden

service icinga2 restart

Fazit

Wenn alles geschafft ist, haben wir unser Monitoring Tool für MSSQL Datenbanken erweitert und können dementsprechend Checks ausführen. Die Installation von mssql_health an sich ist einfach nur die jeweilige Integration in Icinga bedarf etwas Überlegung. Natürlich kann das Modul auch auf andere Wege in Icinga implementiert werden. Dort stehen alle Möglichkeiten offen. Ich habe mich für diese Integration entschieden, da ich für mich hier die meisten Vorteile sehe. Mit dieser Art der Erstellung müssen nur noch im Host Objekt die einzelnen Modis mit ihren Werten eingeben werden.  So kann auf einfachste Weise ein neuer Check eingefügt werden, ohne den Service bzw. den Command anpacken zu müssen.

2 comments on “Icinga2 – check_mssql_health
  1. Avatar francisco garcia sagt:

    Hallo! Danke für die Anleitung.. Eine Frage.. Wo fügt man die Datenbank Einrichten script ein? auch im datei freetds.conf?? oder woanders..

    • stevie stevie sagt:

      Hallo, Die Datenbank muss an mehreren Stellen genannt werden, darunter zählt auch die freetds.conf. Auch in dem Datenbankserver Host Object sollte eine Verlinkung stattfinden, von hier werden die einzelnen Services gestartet. Die Services können dabei auf unterschiedlichste Weise zugeordnet werden, das steht hier jedem frei. Ich habe mich dazu entschieden eigene Commands zu schreiben, die das Anbinden vereinfachen. Zuguter letzt sollte die Datenbank selber noch eingerichtet werden, sodass der Icinga Service sich dort anmelden kann.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.