Seite wählen

NETWAYS Blog

Icinga 2.3

icinga_logo_200x69Mit fast 100 neuen Features ist die Version 2.3 einer unserer bisher größten Feature-Releases. So wurde beispielsweise die Konfigurationssprache um weitere Möglichkeiten erweitert (Funktionen, Flow Control, uvm.), noch dynamischere Konfiguration zu schreiben.
Eine genaue Beschreibung der wichtigsten Neuerungen gibt es im (englischen) Release-Blogpost zu finden.
Übrigens sind wir auf der diesjährigen CeBIT mit dem Icinga-Team vertreten und stehen gerne für Fragen zur Verfügung. Ihr findet uns am Icinga-Stand in Halle 6 Stand H16.

Icinga 2: Funktionen als Custom-Attribute

Seit der Version 2.2 unterstützt Icinga Arrays und Dictionaries in Custom-Attributen. Zusammen mit apply lassen sich diese wunderbar verwenden, um z.B. für einen Host mehrere HTTP-Vhosts zu definieren und diese jeweils durch einen einen einzelnen Service checken zu lassen.
Mit der Version 2.3, die planmäßig am 10. März erscheinen soll, wird es zusätzlich die Möglichkeit geben, für Custom-Attribute Funktionen zu verwenden:

object CheckCommand "random-text" {
  import "plugin-check-command"
  command = [ PluginDir + "/check_dummy", "0", "$text$" ]
  vars.text = {{ Math.random() * 100 }}
}

Durch die beiden geschweiften Klammern wird eine Funktion definiert. Diese wird von Icinga jedes Mal aufgerufen, wenn es den Wert des Custom-Attributs „text“ benötigt. In diesem Beispiel würde dies dazu führen, dass der Check bei jeder Ausführung einen unterschiedlichen Zufallswert ausgibt.
Mit Hilfe von Funktionen ist es allerdings nicht nur möglich, einfache Werte zu berechnen. Der Benutzer kann mit if/else beispielsweise komplexere Logik einbauen:

vars.text = {{
  if (host.address == "127.0.0.1") {
    log("Dies ist ein Check für localhost.")
  }
  return "Test"
}}

Auch auf beliebige Attribute anderer Hosts oder Services lässt sich so zugreifen:

vars.text = {{
  "Der State von 'anderer-host' ist: " + get_host("anderer-host").state
}}

Neue Features in Icinga 2.3

Die nächste Major-Version von Icinga 2 wird einige interessante Features unterstützen, die es noch einfacher machen, Ausnahmen für Services zu definieren. Bis die 2.3 als Release-Version verfügbar ist, wird es zwar noch eine Weile dauern, aber hier gibt es schonmal einen kleinen Vorgeschmack:

Konditionale Statements

Auch bekannter als if/else: In 2.3 ist es möglich, Attribute nur dann zu setzen, wenn bestimmte andere Bedingungen erfüllt sind. Hier ein Beispiel:

object Host "localhost" {
  check_command = "hostalive"
  address = "127.0.0.1"
  vars.http_vhosts["icinga.org"] = {
    http_address = "icinga.org"
    interval = 1m
  }
  vars.http_vhosts["netways.de"] = {
    http_address = "netways.de"
  }
}
apply Service "vhost " for (vhost => config in host.vars.http_vhosts) {
  host_name = "localhost"
  check_command = "http"
  if (config.interval) {
    check_interval = config.interval
  } else {
    check_interval = 5m
  }
  assign where host.vars.http_vhosts
}

Entwicklungs-Konsole

Um Filterregeln für „apply“ und auch andere Ausdrücke einfacher testen zu können, gibt es eine CLI-basierte Konsole, die beliebige Befehle auswerten kann und deren Ergebnis anzeigt:

$ icinga2 console
Icinga (version: v2.2.0-262-g7075607)
<1> => config = { http_address = "icinga.org", interval = 1m }
{"http_address":"icinga.org","interval":60.0}
<2> => if (config.interval) { check_interval = config.interval } else { check_interval = 5m }
60.0
<3> => check_interval
60.0

Prototypen

Alle eingebauten Datentypen (d.h. Strings, Zahlen, Arrays und Dictionaries) verfügen nun über Methoden. Mit Hilfe dieser Methoden können z.B. Dictionaries manipuliert werden:

<1> => vhosts = { "icinga.org" = { http_address = "icinga.org" }, "netways.de" = { http_address = "netways.de" } }
{"icinga.org":{"http_address":"icinga.org"},"netways.de":{"http_address":"netways.de"}}
<2> => vhosts.remove("icinga.org")
null
<3> => vhosts
{"netways.de":{"http_address":"netways.de"}}
<4> => vhosts.len()
1.0

Mit Dictionary#remove würden sich so z.B. bestimmte Dictionary-Items entfernen lassen, falls diese bei einem bestimmten Host bzw. Service nicht vorhanden sein sollen.

Warum SSL nicht funktioniert

Zugegeben, der Titel ist sehr provokativ formuliert. Es soll hier auch gar nicht darum gehen, irgendwelche Sicherheitslücken direkt im SSL-Protokoll (bzw. TLS) oder einer der vielzähligen Implementierungen aufzuzeigen. Vielmehr möchte ich zeigen, dass Verschlüsselung, wie sie heutzutage an vielen Stellen eingesetzt wird, oft nicht mehr tut, als den Benutzer in Sicherheit zu wiegen.
Viele Webseiten unterstützen inzwischen Verschlüsselung – nicht zuletzt, da beispielsweise Google dies seit einigen Monaten in die Bewertung des Rankings einfließen lässt.
Seine Ziele erreicht SSL hier allerdings leider nur bedingt. Es wird zwar sichergestellt, dass die Webseite wie auch Benutzereingaben auf dem Transportweg z.B. durch transparente Proxies nicht verändert werden.
Trotz Verschlüsselung lassen sich von einem Angreifer, der die Netzwerkverbindung passiv abhören kann, dennoch viele Informationen ableiten:
1. Üblicherweise unterstützen Webseiten Redirects, die von HTTP auf HTTPS umleiten. Dabei wird allerdings die erste HTTP-Anfrage ohne Verschlüsselung abgesendet, aus der sich beispielsweise die vollständige URL erfahren lässt.
Zwar gibt es für dieses Problem die HTTP-Erweiterung HSTS, aber zum einen wird sie nur von den wenigstens Webseiten unterstützt und zum anderen greift sie nicht beim ersten Request.
2. Webseiten integrieren prinzipbedingt oftmals Bilder oder JavaScript-Dateien von anderen Webseiten. Selbst wenn diese auch über HTTPS-URLs eingebettet wurden, lässt sich zumindest feststellen, welchen Organisationen diese externen Webseiten gehören.
Beim Aufrufen eines WordPress-Blogs wäre es so beispielsweise nicht verwunderlich, IP-Adressen von Facebook, Google, Twitter und WordPress zu sehen, was z.B. darauf hindeuten würde, dass der Blog über Plugins für Social Buttons verfügt.
3. Anhand der in Punkt 2 ermittelten Daten lässt sich bereits ein recht guter Fingerabdruck erstellen. Noch eindeutiger wird dieser, wenn man die Download-Größe der Webseiten-Requests beobachtet. Viele Webseiten inkludieren beispielsweise eine unterschiedliche Anzahl an Bildern, die dazu beitragen, dass sich die Download-Größe von Seite zu Seite signifikant unterscheidet. Der technische Begriff dafür ist Traffic Analysis.
Um mit diesen Informationen Rückschlüsse auf die aufgerufene URL zu ziehen, müsste der Angreifer über einen Index aller aufrufbaren Seiten verfügen, um deren Download-Größe mit der tatsächlich aufgerufenen Seite zu vergleichen. Bei öffentlich zugänglichen Seiten ließe sich dieser Index mit Hilfe eines Web-Crawlers mit moderatem Aufwand erstellen.
Die beschriebenen Probleme gibt es natürlich nicht nur bei Webseiten. Wenn ich beispielsweise einen Blick in mein E-Mail-Postfach werfe, finde ich gerade einmal eine Handvoll signierter E-Mails und eine einzige verschlüsselte E-Mail. Alle anderen E-Mails liegen unverschlüsselt auf dem E-Mailserver meines Providers (Google).
Fragen Sie einfach einmal einen Ihrer Bekannten, ob deren E-Mails verschlüsselt sind: Dank großflächiger Werbemaßnahmen wie „E-Mail made in Germany“ und De-Mail wird Ihnen dieser die Frage sicher bejahen. Dumm nur, dass dabei nur die Verbindung zum E-Mailserver der Provider verschlüsselt ist, dieser aber dann die Mails im Klartext einsehen kann.

Config-Probleme mit Icinga 2 untersuchen

Um Konfigurationsfehler bei Icinga 2 in Zukunft noch einfacher untersuchen zu können, wird es in der nächste Woche erscheinenden Version 2.1 ein neues Tool geben:

# icinga2-list-objects
Object 'api' of type 'ApiListener':
  * templates = ['api']
    % modified in /etc/icinga2/features-enabled/api.conf, lines 5:1-11:1
  * bind_port = '5665'
    % modified in /etc/icinga2/features-enabled/api.conf, lines 10:3-10:20
  * __name = 'api'
  * ca_path = '/etc/icinga2/pki/ca.crt'
    % modified in /etc/icinga2/features-enabled/api.conf, lines 8:3-8:46
  * cert_path = '/etc/icinga2/pki/ztv.beutner.name.crt'
    % modified in /etc/icinga2/features-enabled/api.conf, lines 6:3-6:62
  * type = 'ApiListener'
  * key_path = '/etc/icinga2/pki/ztv.beutner.name.key'
    % modified in /etc/icinga2/features-enabled/api.conf, lines 7:3-7:61
[...]

Zunächst einmal listet icinga2-list-objects alle in den Konfigurationsdateien definierten Objekte auf. Auch Objekte, die mit „apply“ erstellt wurden, sind in dieser Liste enthalten, wodurch sich mit wenig Aufwand prüfen lässt, ob „apply“-Regeln so funktionieren, wie man es sich vorstellt.
Zusätzlich werden zu jedem Objekt die Attribute inkl. deren Werte angezeigt. Zu jedem Attribut wird außerdem mit angegeben, an welchen Stellen in der Konfiguration es gesetzt bzw. überschrieben wurde.
Im Troubleshooting-Guide werden noch weitere Tipps beschrieben, wie Config-Fehler erkannt und behoben werden können.