Seite wählen

check_by_ssh mit Icinga 2

von | Mrz 21, 2016 | Icinga

tips and tricksAb und zu stehe ich vor dem Problem, dass ich auf einem zu überwachenden System den Icinga 2 Agent nicht benutzen kann.
Anstatt irgendwie das alte (und teils unsichere) NRPE zu benutzen, greife ich dann oft gerne auf check_by_ssh zurück.
Ein Remote-Check funktioniert relativ einfach:

.../check_by_ssh -H web1.example.com -l monitoring -i /etc/icinga2/secure/id_rsa -C '/usr/lib/nagios/plugins/check_users -w 3 -c 5'

Wie man an der Kommandozeile erahnen kann, rufen wir hier einfach per SSH ein Nagios Plugin auf.
Nun habe ich in der Icinga 2 Welt den Vorteil, dass ich saubere Kommandozeilen bauen kann, d.h. Icinga 2 kümmert sich darum, einen Befehl zu bauen, in dem alle Parameter sauber formatiert, und auch „escaped“ sind.
Das by_ssh CheckCommand in der Icinga 2 ITL bietet ein kleines Hilfsmittel dafür an, hier ein einfacher Service als Beispiel:

apply Service "users" {
  import "generic-service"
  check_command = "by_ssh"
  vars.users_wgreater = 3
  vars.users_cgreater = 5
  vars.by_ssh_command = [ "/usr/lib/nagios/plugins/check_users" ]
  vars.by_ssh_arguments = {
    "-w" = "$users_wgreater$"
    "-c" = "$users_cgreater$"
  }
  // assign where ...
}

Wie man am Syntax vielleicht erkennen kann, funktioniert dies hier ähnlich wie die Definition von CheckCommands. Nur eben als Kommando in einem Kommando. Innerhalb vom CheckCommand by_ssh wird hier eine kleine Kommandozeile generiert, in der auch Macros aufgelöst werden.
Nachdem Icinga 2 Konfiguration fast wie eine kleine Programmiersprache ist, kann ich auch einfach vom fertigen CheckCommand aus der ITL die Definitionen kopieren:

apply Service "users" {
  // ...
  check_command = "by_ssh"
  vars.by_ssh_command = {{ get_check_command("users").command }}
  vars.by_ssh_arguments = {{ get_check_command("users").arguments }}
  // ...
}

Wenn ich es meinen Usern noch einfacher machen will kann man dies sogar per Template lösen:

template Service "ssh-service" {
  import "generic-service"
  // "save" original command name, and replace it
  vars.original_check_command = check_command
  check_command = "by_ssh"
  // these get evaluated at runtime
  vars.by_ssh_command = {{ get_check_command(service.vars.original_check_command).command }}
  vars.by_ssh_arguments = {{ get_check_command(service.vars.original_check_command).arguments }}
}

Der eigentliche Service bleibt dabei sehr übersichtlich, hier kommt es nur auf die Reihenfolge an, das check_command muss vor dem import gesetzt sein.

apply Service "users" {
  // ...
  check_command = "users"
  import "ssh-service"
  vars.users_wgreater = 3
  vars.users_cgreater = 5
  // ...
}

Über die Icinga 2 API kann ich gut sehen welches Kommando ausgeführt wird:

$ ICINGA2_API_PASSWORD="geheim" /usr/sbin/icinga2 console --connect https://root@localhost:5665/
=> get_service("web1.example.com", "users").last_check_result.command
[ "/usr/lib/nagios/plugins/check_by_ssh", "-C", "'/usr/lib/nagios/plugins/check_users' '-c' '4' '-w' '2'", "-H", "1.2.3.4" ]

Viel Spaß beim Ausprobieren!
Beitragsbild von Owen Moore (CC-BY-2.0)

4 Kommentare

  1. Michael

    Hallo Markus,
    toller Beitrag, vielen Dank! Auch ich habe einige Hosts auf denen ich keinen Icinga2 Agent laufen lassen kann. Diese überwache ich jetzt per check_by_ssh. Was ich noch etwas unschön finde: Der Check wird ja von meinem Agent ausgeführt, und somit auch zwangsläufig dort als Service aufgeführt. Ich habe also auf dem Agent Dienste welche „wirklich“ auf dem Agent geprüft werden, vermischt mit Diensten welche zwar vom Agent aus geprüft, aber eigentlich einem anderen Host zuzuordnen sind.
    Gibt es eine Möglichkeit einen check_by_ssh auszuführen, das Ergebnis aber im Monitoring auf dem korrekten Host anzuzeigen?

    Antworten
    • joern

      ja, du kannst mit

      vars.by_ssh_address = „SERVER1“

      angeben mit welchem Server ssh verbinden soll und das ganze dann mit z.B.

      assign where host.name == „SERVER2“

      angeben, wo das angezeigt werden soll.

      Antworten
  2. Al

    Thanks for the instructions, I followed them and wrote a service for disk checks, however in icingaweb I got an error saying „Remote command execution failed: Permission denied, please try again“. I believe it’s because my user (nagios) can’t login to the remote host without password. now as you know by default user nagios doesn’t have either a shell or a password, how can I solve this issue? also, by_ssh command has a „required“ argument named address which is the address of the remote host, however in the instruction the argument is not set so what’s going on? and lastly, if I comment out the „assign where …“ clause (per service definition in the instructions) icinga complains that each „service“ need an „assign“
    here is my service definition:
    apply Service „disk“ {
    import „generic-service“

    check_command = „by_ssh“
    vars.disk_wfree = „25%“
    vars.disk_cfree = „15%“
    vars.disk_partitions = „/tmp“
    // vars.by_ssh_command = „r1-01“
    vars.by_ssh_address = „my-host-name“
    vars.by_ssh_command = [„/usr/lib/nagios/plugins/check_disk“]
    vars.by_ssh_arguments = {
    „-w“ = „$disk_wfree$“
    „-c“ = „$disk_cfree$“
    }
    assign where host.name == NodeName
    }

    thanks again for all the help.

    Antworten
    • Markus Frosch

      Yes, you will need an SSH key setup for the „nagios“ system account, and of course have that added to authorized_keys on the other side.

      The example here is pretty generic. If you have detailed questions I suggest opening a topic on https://community.icinga.com and mention my name @mfrosch.

      Antworten

Einen Kommentar abschicken

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

Mehr Beiträge zum Thema Icinga