Der Trigger hat gefeuert. Sauber, pünktlich, mit korrektem Host und Severity. In der Problems-Liste steht der Eintrag seit vier Stunden. Auf dem Handy: nichts.
Der teure Fall ist nicht der Alarm, der zu oft kommt — es ist der, der gar nicht kommt. Fast immer steckt dieselbe Ursache dahinter: Trigger, Action und Media Type werden als ein Ding behandelt. Es sind drei Ebenen mit drei Fehlerbildern.
Dieser Artikel setzt voraus, dass Zabbix läuft und deine Hosts überwacht werden — Installation, Agent, Items und Trigger-Grundlagen stehen im Einsteiger-Tutorial. Hier geht es nur um Zustellung.
Alarmierung in Zabbix 7.0: Trigger, Action, Media Type
| Ebene | Entscheidet | Konfiguriert unter |
|---|---|---|
| Trigger | Ob ein Problem-Event entsteht | Host/Template → Trigger |
| Action | Ob dieses Event jemanden erreicht | Alerts → Actions → Trigger actions |
| Media Type | Wie die Nachricht technisch rausgeht | Alerts → Media types |
| User Media | Wohin genau für diesen Menschen | Users → Users → Media |
Der Trigger verschickt nichts. Er erzeugt ein Event. Erst eine Action mit passender Condition macht daraus eine Nachricht — und selbst dann braucht der Empfänger einen Media-Eintrag, sonst steht die Nachricht nur als Fehler im Action Log.
Diese Reihenfolge ist dein Debug-Werkzeug: bei „kein Alarm" prüfst du von links nach rechts.
Telegram und E-Mail als Media Types
Zabbix 7.0 bringt Telegram, E-Mail, SMS und Webhook vorkonfiguriert mit — unter Alerts → Media types. Der Telegram-Mediatyp ist ein Webhook, kein Shell-Skript: Bot-Token im Media Type, Chat-ID beim Benutzer. Das BotFather-Setup steht im Einsteiger-Tutorial; hier nur die Zuordnung:
- Media Type Telegram: Parameter
api_token= Bot-Token. Kein Token pro Empfänger, kein Token in der Action. - User Media Telegram: Feld Send to = Chat-ID.
Für E-Mail gilt dasselbe mit SMTP: Server, Port, HELO, Absender, Verbindungssicherheit. Zwei Punkte zählen im Homelab:
- Nimm deinen eigenen Relay. Ein Mail-Gateway oder lokaler Postfix nimmt die Mails ohne App-Passwort-Gefrickel an, und du siehst im Mail-Log, ob sie rausgingen. Ein Freemail-Konto mit App-Passwort ist der schlechteste Weg: Rotation, Rate-Limits, kein Einblick.
- Mehrere Adressen sind erlaubt: im Feld Send to per Plus-Button ergänzen.
Der Knopf Test in der Media-Type-Liste verschickt eine echte Nachricht über genau diesen Kanal und beweist Token, SMTP-Zugang und Erreichbarkeit — mehr nicht. Ob eine Action matcht, sagt er nicht.
Ein Betreff wie PROBLEM {EVENT.SEVERITY}: {HOST.NAME} — {EVENT.NAME} spart um 3 Uhr morgens Minuten.
Empfänger: User, Gruppen und Media
Unter Users → Users legst du im Tab Media per Add einen Eintrag an. Vier Felder entscheiden:
| Feld | Bedeutung | Typischer Fehler |
|---|---|---|
| Type | welcher Media Type | Kanal deaktiviert → Typ erscheint rot |
| Send to | Chat-ID, Mailadresse, Ziel | falscher Chat |
| When active | Zeitfenster | falsch gesetzt, niemand merkt es |
| Use if severity | Häkchen pro Severity | zu eng gesetzt |
When active ist die Homelab-Variante von Rufbereitschaft. Format nach Zeitperioden-Spezifikation, etwa 1-5,09:00-18:00 für Werktage tagsüber. Zwei Dinge musst du wissen: Das Fenster rechnet in der Zeitzone des Benutzers, nicht des Servers. Und nachgeliefert wird nichts — ein Problem um 23:40 wird für diesen Empfänger nicht um 9:00 zugestellt.
Use if severity ist ein zweiter, von der Action unabhängiger Filter. Wer dort Warning abwählt, bekommt den Alarm nicht — egal wie perfekt die Action ist. Not classified muss angehakt bleiben, wenn du auch Nicht-Trigger-Events (interne Zabbix-Events) empfangen willst.
Dazu kommen Berechtigungen: Der Benutzer braucht mindestens Read auf der Host-Gruppe, sonst erzeugt Zabbix keinen Alert. Wer eine Gruppe anlegt und die Benutzergruppe nicht mitzieht, hat später einen stillen Empfänger.
Und die Grenze: Zabbix ist kein On-Call-Tool. Keine Rotation, keine Übergabe, kein „nach 15 Minuten weiter an die nächste Person", keine Anrufe, keine Reaktionszeit-Statistik. Es gibt eine feste Kette pro Action und ein Zeitfenster pro Medium. Für zwei Leute reicht das.
Actions und Conditions: Welche Alarme lösen aus?
Actions liegen unter Alerts → Actions → Trigger actions: Conditions (welche Events?) und Operations (was passiert?). Die wichtigen Condition-Typen in 7.0:
- Host group — der sauberste Zuschnitt, eine Action pro Gruppe.
- Trigger severity — mit is greater than or equals.
- Tag name / Tag value — Event-Tags, die der Trigger setzt.
- Time period — etwa nur außerhalb der Bürozeiten.
- Problem is suppressed — auf
nosetzen. Diese Condition verhindert, dass eine Action für ein unterdrücktes Problem überhaupt startet. Ein in der Wartung entstandenes Problem wird danach auch nicht nachgereicht. Das ist nicht die Pause-Checkbox der Operations — die beiden Mechanismen sind getrennt (siehe Wartung und Dependencies).
Der häufigste Fehler ist eine einzige Action mit Severity >= Warning für alle Hosts. Das klingt vernünftig, ist es aber nicht: Warning heißt „schau mal drauf" — Dateisystem bei 80 Prozent, Zertifikat in 30 Tagen. Wenn davon jede Nacht drei Stück pushen, lernst du in zwei Wochen, Pushes wegzuwischen. Genau dann kommt der echte Ausfall.
Besser nach Kritikalität trennen: eine Action für Proxmox und NAS (Severity >= Average), eine für Container (Severity >= High), eine für Information ohne Versand. Tags sind dabei mehr als Deko — component:storage filtert in der Action, ohne Host-Namen zu pflegen, und überlebt neue VMs.
Eskalation und Rufbereitschaft
Eskalation steckt in 7.0 nicht in einem eigenen Tab, sondern in der Schrittfolge der Operations einer Action. Du setzt die Default operation step duration (Minimum 60 Sekunden) und legst per Add Operationen an:
- Steps: From / To — in welchen Schritten die Operation läuft.
To = 0heißt unbegrenzt. - Step duration — überschreibt für diese Operation die Default-Dauer.
- Send to users / Send to user groups — Empfänger.
- Send to media type — Feld heißt bis 7.0.6 Send only to, ab 7.0.7 Send to media type. Default ist nicht „leer", sondern die Option All (ab 7.0.7 All available): alle konfigurierten und aktivierten Media Types des Benutzers.
- Conditions —
Event is not acknowledgedoderEvent is acknowledged. Das verbindet Acknowledge mit Eskalation.
Beispiel mit Default Step Duration 30m:
| Operation | Steps | Empfänger | Bedingung |
|---|---|---|---|
| A | 1–4 | ich | Event is not acknowledged |
| B | 5–0 | zweite Person | Event is not acknowledged |
Damit kommt in Minute 0, 30, 60 und 90 eine Nachricht an mich, ab Minute 120 bei jedem weiteren Schritt an die zweite Person.
Zwei Feinheiten: Die zweite Person sieht vor Schritt 5 nichts — wenn sie Kontext braucht, lass sie in A mitlaufen. Und {ESC.HISTORY} in einer Custom Message enthält alle bisherigen Schritte, sodass dort „drei Benachrichtigungen, keine Reaktion" steht statt einer nackten Trigger-Meldung.
Eskalationen gelten nur für Problem-Operations, nicht für Recovery, und laufen pro Action: Zwei Actions auf dasselbe Event erzeugen zwei Ketten — bei überschneidenden Host-Gruppen doppelte Nachrichten.
Recovery, Acknowledge und Update
Ein Problem verschwindet, wenn die Trigger-Expression wieder falsch wird. Die Nachricht dazu nicht. Ohne Recovery Operation bleibt der Kanal still — und du sitzt vor einem Handy, das einen längst behobenen Ausfall meldet.
Unter Operations gibt es dafür den Block Recovery operations mit drei Typen: Send message, Notify all involved (an alle, die mindestens eine Problem-Nachricht bekamen — die richtige Wahl für die meisten Setups) und Remote command. Alle Recovery-Operations laufen gleichzeitig, ohne Staffelung.
Acknowledge ist der Punkt, an dem die meisten Eskalationen falsch konfiguriert sind. Ein ACK allein stoppt nichts. Er markiert das Problem als bearbeitet und löst Update-Operations aus. Die Eskalation stoppt nur, wenn die Operation die Bedingung Event is not acknowledged trägt. Fehlt sie, klingelt um 2:00 Uhr die zweite Person — obwohl du um 0:05 quittiert hast. Das ist kein Bug, das ist die Standardeinstellung.
Update Operations feuern, wenn ein Problem aktualisiert wird: quittiert, kommentiert, Severity geändert. Sinnvoll ist eine kurze Nachricht an die Gruppe, dass jemand übernommen hat — sonst arbeiten zwei Leute parallel an derselben Störung.
Für Trigger ohne Recovery-Expression bleibt das Problem nicht offen: Mit OK event generation = Expression (Standard) schließt Zabbix das Problem automatisch, sobald die Problem-Expression falsch wird. Allow manual close brauchst du nur, wenn du ein Problem von Hand schließen willst — typisch bei OK event generation = None, wo gar kein OK-Event entsteht.
Wartung und Dependencies: Alarmflut vermeiden
Maintenance planst du unter Data collection → Maintenance. Der Zeitraum gilt für Hosts oder Host-Gruppen. Zwei Typen: With data collection — Daten werden weiter gespeichert, die Trigger laufen normal weiter. No data collection — es wird nichts gespeichert, und die Trigger feuern nicht. Wichtig: Die Wartung unterdrückt das Problem in der Oberfläche. Ob Benachrichtigungen pausieren, entscheidet die Action-Option Pause operations for suppressed problems (siehe unten) — nicht die Wartung allein. Die Action-Condition Problem is suppressed = no ist ein separater Mechanismus. Vor einem apt upgrade mit Reboot ist ein Fenster trotzdem Pflicht.
Der Haken steckt in der Action: Pause operations for suppressed problems (Checkbox im Operations-Tab, nur bei Trigger-Actions). Ist sie gesetzt, werden die Eskalationsschritte um die Wartungsdauer verschoben, nicht als Schwung nachgeholt. Beispiel: Schritte bei Minute 0, 30 und 60, Wartung von Minute 10 bis 40 — dann kommen Schritt 2 und 3 bei Minute 60 und 90. Ein Problem, das während der Wartung entsteht, startet seine Uhr erst danach. Recovery- und Update-Operations werden nicht pausiert; eine Recovery entfällt, wenn das Problem in der Wartung entstand. Die Condition Problem is suppressed = no (oben) ist ein anderer Mechanismus: Sie verhindert den Action-Start komplett, statt ihn nur zu pausieren. Ohne Häkchen eskalieren die Operations während der Wartung weiter — was du bei einem echten Ausfall willst, nicht bei geplanter Arbeit.
Der zweite Mechanismus sind Trigger Dependencies: Ein Parent-Trigger unterdrückt abhängige Trigger, solange er im Problem-Status ist — „Host neu gestartet" als Parent, alle Dienst-Trigger als Kinder. Wie das mit LLD-Prototypen funktioniert und warum es aus 65 Meldungen eine macht, steht im Incident-Post zu Trigger Dependencies.
Testen und Troubleshooting
Ein Alarm, den du nie getestet hast, ist eine Annahme. Teste in drei Stufen.
Stufe 1 — Media Type: Alerts → Media types → Test. Beweist Token beziehungsweise SMTP. Scheitert das, ist alles danach egal.
Stufe 2 — echtes Event durch die ganze Kette. Lege ein Trapper-Item mit dem Key test.alert an (Typ Zabbix trapper) und einen Trigger mit last(/hv-01/test.alert)=1. Dann schickst du einen Wert:
# Wert setzen (Alarm), Hostname via -s
zabbix_sender -z 192.168.1.50 -s hv-01 -k test.alert -o 1
# ... Alarm prüfen, dann auflösen (Recovery testen)
zabbix_sender -z 192.168.1.50 -s hv-01 -k test.alert -o 0
Das prüft Action, Condition, Empfänger, Media und Eskalationsschritte — alles, was der Media-Type-Test auslässt.
Stufe 3 — Action Log: Reports → Action log zeigt jede ausgeführte Operation mit Zeit, Action, Empfänger und Status. Failed mit Fehlertext heißt: Media Type oder Ziel kaputt. Gar kein Eintrag: Die Action hat nie gegriffen.
Kommt nichts an, gehe diese Liste von oben nach unten durch:
| Ursache | Prüfpunkt |
|---|---|
| Condition matcht nicht | Host-Gruppe, Severity, Tags gegen das Event |
| Action deaktiviert | Status in der Action-Liste |
| Benutzer ohne Media | Users → Users → Media |
| Severity im Medium abgewählt | Use if severity |
| Medium oder Media Type deaktiviert | Status Enabled, Typ ggf. rot |
| Zeitfenster | When active des Mediums |
| Keine Berechtigung | mindestens Read auf der Host-Gruppe |
| Maintenance aktiv | Data collection → Maintenance, Pause-Checkbox |
| Problem unterdrückt | Condition Problem is suppressed |
Checkliste: Alarmierung testen
- Media Type per Test verschickt eine echte Nachricht
- User Media: Typ, Ziel, Severity-Häkchen, Status Enabled
- Benutzergruppe hat mindestens Read auf der Host-Gruppe
- Action hat Host-Gruppe oder Tag als Condition, nicht nur Severity
- Test-Event steht im Action Log mit Status Sent
- Eskalationsschritt 2 kommt zur erwarteten Zeit
- Acknowledge stoppt die Eskalation
- Recovery-Nachricht kommt nach Auflösen des Triggers
- Wartungsfenster unterdrückt Alarme wie erwartet
Wann Zabbix nicht reicht
Zabbix kann eine feste Kette: erst ich, dann du, dann die Gruppe. Was es nicht kann, ist Rufbereitschaft im organisatorischen Sinn — keine Rotation, keine Übergabe, keine Frist „muss in 15 Minuten quittiert sein, sonst Anruf", keine Reaktionszeit-Statistik, keine Unterscheidung zwischen „gesehen" und „übernommen".
Für zwei Personen mit einem Handy reicht die Eskalation über Operations und When active völlig. Sobald du aber Geld dafür nimmst, dass jemand nachts rangeht, brauchst du ein Werkzeug mit Schichtplan und Anrufkette (PagerDuty, Grafana OnCall, Opsgenie) und Zabbix nur als Quelle, die dorthin meldet. Der Umbau später ist teuer: Empfängerliste und Ausnahmen sind in Zabbix gewachsen, und niemand weiß mehr, welche Action zuständig ist. Lieber früh entscheiden, wie viel Organisation du abbilden willst.
Technische Basis bleibt Zabbix: installieren, Hosts auf einem Proxmox-Host überwachen, Zertifikate separat via SSL-Monitoring. Die Alarmierung ist der letzte Meter — und der einzige, den du im Ernstfall merkst.