Das Monitoring-Konto für Datenbank-Checks einrichten
Lege das Konto mit minimalen Rechten an, mit dem sich die Checks für Microsoft SQL Server, MySQL/MariaDB und PostgreSQL anmelden.
Das Monitoring-Konto für Datenbank-Checks einrichten
octoja überwacht Microsoft SQL Server, MySQL / MariaDB und PostgreSQL mit sechs Checks — einem Zustand-Check pro Engine, einem Abfrage-Check für MySQL/MariaDB und PostgreSQL sowie einem Aktivität-Check für Microsoft SQL Server. Jeder von ihnen meldet sich als gewöhnlicher Client an der Datenbank an. Die Arbeit, die über Erfolg oder Misserfolg entscheidet, passiert deshalb auf dem Datenbankserver und nicht in octoja: ein Login mit gerade genug Rechten, um die Statistiken zu lesen, und ein Server, der dieses Login von der Adresse akzeptiert, von der aus der Agent sich verbindet.
Genau darum geht es in diesem Artikel. Die einzelnen Check-Felder — Schwellenwerte, Intervalle, welche Datenbanken überwacht werden — werden im Check-Editor erklärt, während du sie ausfüllst.
Was für alle drei Engines gilt
- Lege ein eigenes Konto an. Richte einen Check niemals auf ein administratives Konto oder auf den Datenbankbenutzer der Anwendung. Ein separates Login lässt sich rotieren oder entziehen, ohne irgendetwas anderes anzufassen, und es ist in der Prozessliste eindeutig zu erkennen, wenn du einer Verbindung nachgehst.
- Lesend genügt. Die Zustand-Checks lesen Statistiken auf Serverebene; die Abfrage-Checks lesen nur, was deine eigene Anweisung berührt. Schreibrechte braucht nichts davon.
- Ein Check pro Datenbankserver, nicht pro Gerät — bei MySQL/MariaDB und PostgreSQL. Deren Host ist Teil der Check-Konfiguration; verteilst du sie über ein Konfigurationspaket an eine Gerätegruppe, öffnet jeder passende Agent seine eigene Verbindung zur selben Datenbank. Die beiden SQL-Server-Checks haben gar kein Host-Feld: Sie finden die lokalen Instanzen des Geräts, auf dem sie laufen — weise sie also dem SQL-Server-Rechner selbst zu.
- Prüfe von der Maschine aus, auf der der Agent läuft, bevor du in octoja etwas konfigurierst. Ein Login, das auf dem Datenbankserver selbst funktioniert, beweist nichts über eine Verbindung einen Sprung weiter.
Microsoft SQL Server
Beide SQL-Server-Checks lesen Zustand auf Serverebene. Entscheide zuerst, wie sie sich authentifizieren, und gib dieser Identität dann die wenigen Leserechte, die sie braucht.
Den Authentifizierungsmodus wählen
Beide Checks unterstützen dieselben zwei Modi. Du wählst, indem du die Felder SQL-Benutzername und SQL-Passwort ausfüllst oder leer lässt — sie erscheinen, sobald du im Check-Editor Erweiterte Optionen anzeigen einschaltest.
Auf einem Datenbankserver mit nur einem Zweck ist die Windows-Authentifizierung die einfachere Wahl: nichts zu rotieren, nichts zu speichern. Ein eigenes SQL-Login ist die bessere Wahl, wenn die Monitoring-Identität für sich sichtbar und entziehbar sein soll, wenn NT AUTHORITY\SYSTEM auf der Instanz bewusst eingeschränkt ist, oder wenn dieselben Zugangsdaten auf mehreren Instanzen funktionieren müssen, die keine gemeinsame Windows-Vertrauensstellung haben.
Dem Login nur geben, was die Checks lesen
Beide Checks arbeiten auf deinen Datenbanken ausschließlich lesend. Sie lesen keine Tabellendaten daraus — sie lesen Zustand auf Serverebene, die Datenbankliste, die Backup- und Job-Historie in msdb sowie Volume-Statistiken. Das entspricht einer kleinen Menge von Berechtigungen auf Serverebene:
Ein fehlendes
VIEW SERVER STATEist die Falle. Der Zustand-Check wird kritisch, und das ist gewollt. Der Aktivität-Check dagegen behandelt eine nicht erreichbare Instanz als fremdes Problem und meldet OK — er steht also dauerhaft und still auf Grün. Wenn der Aktivität-Check nie aus OK herauskommt, während der Zustand-Check über die Verbindung klagt, prüfe zuerst diese Berechtigung.
Ein eigenes SQL-Login
Führe das einmal auf jeder Instanz aus, die überwacht werden soll, und ersetze dabei das Platzhalter-Passwort:
CREATE LOGIN [octoja_monitor]
WITH PASSWORD = N'<strong-password>', CHECK_POLICY = ON;
GO
GRANT VIEW SERVER STATE TO [octoja_monitor];
GRANT VIEW ANY DATABASE TO [octoja_monitor];
GRANT VIEW ANY DEFINITION TO [octoja_monitor];
GO
USE msdb;
GO
CREATE USER [octoja_monitor] FOR LOGIN [octoja_monitor];
GRANT SELECT ON dbo.backupset TO [octoja_monitor];
ALTER ROLE SQLAgentReaderRole ADD MEMBER [octoja_monitor];
GO
Lege das Login auf einem Server mit mehreren Instanzen auf jeder von ihnen mit demselben Namen und demselben Passwort an — der Check schickt einen Satz Zugangsdaten an alle Instanzen, die er findet.
Stattdessen Windows-Authentifizierung
Damit der Check ohne Passwort auskommt, gib dieselbe Menge der Identität des Agents:
-- Der octoja-Agent-Dienst läuft als LocalSystem, so it arrives as NT AUTHORITY\SYSTEM.
-- CREATE LOGIN überspringen if this login already exists on the instance.
CREATE LOGIN [NT AUTHORITY\SYSTEM] FROM WINDOWS;
GO
GRANT VIEW SERVER STATE TO [NT AUTHORITY\SYSTEM];
GRANT VIEW ANY DATABASE TO [NT AUTHORITY\SYSTEM];
GRANT VIEW ANY DEFINITION TO [NT AUTHORITY\SYSTEM];
GO
USE msdb;
GO
CREATE USER [NT AUTHORITY\SYSTEM] FOR LOGIN [NT AUTHORITY\SYSTEM];
GRANT SELECT ON dbo.backupset TO [NT AUTHORITY\SYSTEM];
ALTER ROLE SQLAgentReaderRole ADD MEMBER [NT AUTHORITY\SYSTEM];
GO
Auf vielen Instanzen existiert dieses Login bereits und hat mehr als genug Rechte, dann laufen die Grants ins Leere. Ergänze, was fehlt, aber lass die bestehenden Mitgliedschaften des Kontos unangetastet — Windows und die SQL Server-Wartung nutzen es.
Was das Login nicht braucht
- Kein
sysadminund keine andere feste Serverrolle. - Keine Datenbankrollen in deinen Benutzerdatenbanken — weder
db_ownernochdb_datareader. Die Checks lesen deine Daten nie. - Keine Schreibrechte in deinen Datenbanken — beide Checks lesen sie nur. Der einzige Schreibvorgang ist eine temporäre Tabelle in
tempdb, die der Aktivität-Check beim Lesen des Fehlerlogs anlegt, und das darf jedes Login. Dafür ist nichts zu gewähren. - Die eine Ausnahme ist die Option SQL Server-Fehlerlog überwachen des Aktivität-Checks: das Lesen des Fehlerlogs läuft über
xp_readerrorlogund verlangt die Rollesecurityadminodersysadmin. Das ist weit mehr, als Monitoring halten sollte — schalte die Option auf einem Login mit minimalen Rechten also entweder ab, oder lass sie an und nimm hin, dass der Abschnitt leer bleibt. Ein verwehrtes Fehlerlog wird als nicht verfügbar gemeldet und löst nie einen Alarm aus.
MySQL und MariaDB
Zwei Entscheidungen bestimmen, ob das beim ersten Versuch funktioniert. Beide werden in der Datenbank getroffen, nicht in octoja.
Das Konto muss die Adresse des Agents erlauben, nicht die des Datenbankservers. MySQL-Konten sind
user@host-Paare, und die Host-Hälfte wird dagegen geprüft, woher die Verbindung kommt. Läuft der Agent auf dem Datenbankserver selbst, ist daslocalhost/127.0.0.1. Läuft er irgendwo anders — auf einem Sprungserver, einem Hypervisor, irgendeinem anderen verwalteten Gerät — ist es die Adresse dieser Maschine. Ein Grant, der für'octoja_monitor'@'localhost'geschrieben ist, weist einen Agent einen Sprung weiter ab, und der Check meldet dann Authentifizierung fehlgeschlagen bei einem völlig korrekten Passwort.
Der Abfrage-Check zählt Zeilen, keine Werte. Er führt deine Anweisung aus und zählt die Zeilen im Ergebnis.
SELECT count(*) FROM orders WHERE status = 'stuck'liefert immer genau eine Zeile, wird also immer als 1 bewertet — egal, wie viele hängende Bestellungen es gibt. Schreibe die Abfrage so, dass sie eine Zeile pro Problem zurückgibt. Zeilenanzahl ist der Standard-Modus von Warnen bei — die zweite Option, Ausführungszeit (ms), warnt stattdessen darauf, wie lange die Abfrage dauert. Warnungs-Schwellenwert und Fehler-Schwellenwert (Standard je 1) setzen die Grenzen, und Warnen, wenn unter Schwellenwert kehrt den Vergleich um — für Fälle, in denen zu wenige Zeilen das Problem sind.
Das Monitoring-Konto anlegen
Drei kurze Schritte auf dem Datenbankserver, in dieser Reihenfolge: entscheiden, von welcher Adresse aus sich das Konto verbinden darf, es mit den Rechten anlegen, die die Checks wirklich brauchen, und bestätigen, dass der Server mitspielt, bevor du in octoja etwas konfigurierst.
1. Die Host-Hälfte festlegen
Schreibe den Grant für die Adresse, von der aus sich der Agent verbindet:
2. Das Konto anlegen und berechtigen
Das ist alles, was der Check MySQL-/MariaDB-Zustand braucht:
CREATE USER 'octoja_monitor'@'10.20.0.15' IDENTIFIED BY 'a-long-random-password';
GRANT PROCESS ON *.* TO 'octoja_monitor'@'10.20.0.15';
- Sich anmelden zu können genügt bereits für Verbindungszeit und Laufzeit.
CREATE USERgewährt implizit das PrivilegUSAGE, und der Laufzeitwert stammt aus einem globalen Statuscounter, der auf keinem Schema Rechte braucht. PROCESSist das, was die gemeldete Thread-Zahl echt macht. octoja zählt die Zeilen voninformation_schema.PROCESSLIST, und ohnePROCESSsieht ein Konto nur die eigene Verbindung — der Check meldet dann bei jedem Lauf Threads: 1.PROCESSist ein globales Privileg und muss deshalbON *.*gewährt werden; es gibt keinen Zugriff auf Tabellendaten.
Für den Check MySQL-/MariaDB-Abfrage kommt Lesezugriff auf genau das hinzu, was die Abfrage berührt — und nichts darüber hinaus:
GRANT SELECT ON shop.* TO 'octoja_monitor'@'10.20.0.15';
Liest die Abfrage nur eine Tabelle, dann werde noch genauer: GRANT SELECT ON shop.orders TO 'octoja_monitor'@'10.20.0.15';
Verwende nicht den Datenbankbenutzer der Anwendung wieder. Ein eigenes Konto lässt sich rotieren oder deaktivieren, ohne die Anwendung anzufassen, es ist in der Prozessliste unverwechselbar, wenn du einer Verbindung nachgehst, und ein Konto, das nur
SELECTdarf, kann durch eine vertippte Abfrage nicht zum Schreibpfad werden.
Wiederhole die Zeilen CREATE USER und GRANT für jede Host-Hälfte, die du in Schritt 1 festgelegt hast — Grants gelten pro user@host-Paar, 'octoja_monitor'@'localhost' und 'octoja_monitor'@'127.0.0.1' sind also zwei getrennte Konten, die jeweils eigene Rechte brauchen.
3. Prüfen, bevor du octoja anfasst
Sieh nach, was der Server dem Konto zugesteht:
SHOW GRANTS FOR 'octoja_monitor'@'10.20.0.15';
Melde dich dann von der Maschine aus an, auf der der Agent läuft — darum geht es bei der ganzen Übung:
mysql -h db01.example.com -P 3306 -u octoja_monitor -p -e "SELECT 1"
Klappt das, klappt auch der Check. Gibt es auf dieser Maschine keinen MySQL-Client, dann bestätige zumindest, dass der Port von dort aus antwortet.
Ein Server, der nur auf Loopback lauscht, ist von außen nie erreichbar. Mehrere MySQL- und MariaDB-Distributionspakete binden die Lauschadresse ab Werk an
127.0.0.1. Kein Grant kann das umgehen. Wird eine entfernte Anmeldung abgewiesen oder läuft sie in einen Timeout, während eine lokale funktioniert, dann prüfe die Bind-Adresse des Servers und die Host-Firewall, bevor du das Konto erneut anfasst.
PostgreSQL
Zwei Dinge entscheiden, ob sich die PostgreSQL-Checks verbinden: wie sie den Server erreichen, und ob die Monitoring-Rolle die Statistiksichten lesen darf.
Diese Checks verbinden sich über TCP — immer
Das ist der mit Abstand häufigste Fehlstart. Die PostgreSQL-Checks sind gewöhnliche PostgreSQL-Clients. Sie lesen nicht das Datenverzeichnis, sie sprechen nicht mit einem lokalen Dienstmanager, und den octoja-Agent auf dem Datenbankserver zu installieren verschafft ihnen keine Abkürzung. Selbst wenn der Host 127.0.0.1 ist, kommt die Verbindung als TCP-Verbindung an und wird gegen die host-Zeilen in pg_hba.conf geprüft — nie gegen die local-Zeilen (Unix-Socket). Ein Eintrag local all all peer authentifiziert diese Checks nicht.
Ein Check pro Server, nicht pro Gerät. Der Host gehört zur Check-Konfiguration. Diese Checks über ein Konfigurationspaket auf eine ganze Gerätegruppe auszurollen bedeutet, dass jeder passende Agent seine eigene Verbindung zur selben Datenbank öffnet. Weise sie einem einzelnen Gerät zu — idealerweise dem Datenbankserver.
PostgreSQL vorbereiten
Zwei Dinge müssen zusammenpassen, bevor der Check sich verbinden kann: eine Rolle mit gerade genug Rechten, um die Statistiken zu lesen, und ein Eintrag in pg_hba.conf, der diese Rolle von der Adresse des Agents aus hereinlässt. Mach es in dieser Reihenfolge.
1. Eine nur lesende Monitoring-Rolle anlegen
Richte die Checks nicht auf postgres oder auf eine Anwendungsrolle. Lege eine eigene Login-Rolle an — sollte ihr Passwort je abhandenkommen, rotierst du eine Berechtigung, die nur lesen kann.
CREATE ROLE octoja_monitor WITH LOGIN PASSWORD 'a-long-random-password';
2. pg_monitor gewähren
Das ist der Grant, auf den es wirklich ankommt, und er wird leicht übersprungen, weil der Check auch ohne ihn auf Grün geht.
PostgreSQL verbirgt die interessanten Spalten von pg_stat_activity vor gewöhnlichen Rollen: bei Backends, die anderen Rollen gehören, ist die Spalte state NULL. Der Check PostgreSQL-Zustand zählt Sessions mit state = 'active', eine Rolle ohne dieses Recht sieht also genau eine — die eigene — egal wie beschäftigt der Server ist. Der Check meldet OK, die Zahl ist bedeutungslos, und nichts weist darauf hin.
pg_monitor ist eine eingebaute Rolle, die es auf jeder unterstützten PostgreSQL-Version gibt. Sie bündelt pg_read_all_stats, pg_read_all_settings und pg_stat_scan_tables — nur lesenden Zugriff auf die Statistiksichten und die Konfiguration, mehr nicht. pg_read_all_stats allein genügt für diese beiden Checks; pg_monitor ist der übliche Grant und lässt Raum für künftige Statistiken.
GRANT pg_monitor TO octoja_monitor;
Die Datenbankgröße funktioniert auch ohne diesen Grant (sie braucht nur CONNECT auf der Datenbank), weshalb eine halb konfigurierte Rolle auf den ersten Blick überzeugend aussieht. Sieh dir auf einem Server, von dem du weißt, dass er beschäftigt ist, die Zahl unter Aktive Sitzungen an — bleibt sie dauerhaft bei 1, fehlt der Grant.
3. Lesezugriff für den Abfrage-Check gewähren
PostgreSQL-Zustand braucht nichts über das Obige hinaus. PostgreSQL-Abfrage liest deine Tabellen und braucht daher die übliche Lesekette auf der Datenbank, mit der er sich verbindet:
GRANT CONNECT ON DATABASE your_database TO octoja_monitor;
GRANT USAGE ON SCHEMA public TO octoja_monitor;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO octoja_monitor;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO octoja_monitor;
Setze deine eigenen Datenbank- und Schemanamen ein. Die letzte Anweisung erfasst nur Tabellen, die später von der Rolle angelegt werden, die sie ausführt — führe sie als die Rolle aus, der die Tabellen der Anwendung gehören, sonst erben neue Tabellen den Grant nicht und der Check fällt eines Tages mit einem Rechtefehler aus.
Gewähre ausschließlich SELECT. octoja führt deine Abfrage in einer READ ONLY-Transaktion aus und rollt sie danach zurück, der Server weist also alles Schreibende ab — betrachte das aber als Sicherheitsgurt, nicht als Schloss.
4. Den Agent durch pg_hba.conf lassen
pg_hba.conf entscheidet, welche Rolle sich von welcher Adresse mit welcher Authentifizierungsmethode verbinden darf. Frage den Server nach dem Ort der Datei, statt zu raten — Distributionspakete verschieben sie aus dem Datenverzeichnis heraus:
SHOW hba_file;
SHOW config_file;
Füge eine Zeile für die Monitoring-Rolle hinzu. Regeln werden von oben nach unten ausgewertet und die erste passende Zeile gewinnt — sitzt ein breiteres reject oder eine restriktivere Zeile darüber, kommt deine nie zum Zug.
# Agent auf dem Datenbankserver selbst
host all octoja_monitor 127.0.0.1/32 scram-sha-256
# Agent auf einem anderen Host
host all octoja_monitor 10.0.0.25/32 scram-sha-256
Danach neu laden — eine Änderung an pg_hba.conf braucht keinen Neustart:
SELECT pg_reload_conf();
Läuft der Agent nicht auf dem Datenbankserver, bestätige zusätzlich, dass listen_addresses in postgresql.conf eine Adresse enthält, die der Agent erreichen kann. Ein Server ab Werk lauscht nur auf localhost. Anders als pg_hba.conf wirkt listen_addresses erst nach einem Neustart, nicht nach einem Reload.
scram-sha-256 oder md5? Richte die Methode danach, wie das Passwort der Rolle gespeichert wurde. Eine Rolle, deren Passwort gesetzt wurde, als der Server auf
password_encryption = md5stand, kann sich nicht gegen einescram-sha-256-Zeile authentifizieren. Falls dich das trifft, setze das Passwort nach dem Umstellen neu — der Hash wird zum Zeitpunkt vonALTER ROLE ... PASSWORDgeschrieben.
5. Vom Agent-Host aus prüfen
Beweise, dass der Weg funktioniert, bevor du octoja anfasst. Von dem Gerät aus, auf dem der Agent läuft:
psql "host=10.0.0.10 port=5432 dbname=postgres user=octoja_monitor sslmode=prefer"
Führe dann die beiden Anweisungen aus, die der Zustand-Check selbst absetzt:
SELECT count(*) FROM pg_stat_activity WHERE state = 'active';
SELECT pg_database_size(current_database());
Lies die erste Zahl nicht als Anzahl verbundener Clients. Sie zählt nur die Backends, die in diesem Moment eine Anweisung ausführen — ein verbundener, aber wartender Client meldet idle, nicht active — auf einem Server, zu dem nur verbunden wird, statt dass gearbeitet wird, ist 1 (die eigene Session, die genau diese Abfrage ausführt) also die ehrliche Antwort und sagt nichts über den Grant. Um den pg_monitor-Grant selbst zu testen, lies die Spalte state direkt:
SELECT usename, state FROM pg_stat_activity;
Ohne den Grant ist state für jedes Backend außer dem eigenen NULL. Mit ihm siehst du den echten Zustand jedes Backends.
Verbindet sich psql und antworten die Anweisungen, sind die Rolle, die pg_hba.conf-Zeile und der Netzwerkweg bewiesen — die Grants nicht. Beide Anweisungen des Zustand-Checks antworten auch ohne pg_monitor, nur der state-Test oben klärt Schritt 2, und nichts hier liest die Tabellen, die der Abfrage-Check berühren wird, die Grants aus Schritt 3 bleiben also ungetestet, bis du deine eigene Abfrage ebenfalls durch psql schickst. Der Check verbindet sich weiterhin als Dienstkonto des Agents und nicht als du, das ist die eine verbleibende Variable. Verbindet sich psql nicht, ist der Fehler, den es ausgibt, derselbe, den octoja dir zeigen wird — und hier ist er leichter zu lesen.
Die Checks in octoja hinzufügen
Du brauchst die Berechtigung Monitoring-Check-Verwaltung; Berechtigungen weist deine Administration unter Administration → Gruppen zu.
- Geh zu Geräte und öffne das Gerät, das den Check ausführen wird — bei einem Datenbankserver mit Agent also diesen Server selbst.
- Klicke auf den Reiter Checks → Check hinzufügen und wähle den Check für deine Engine.
- Trage die Verbindungsdaten und die oben angelegten Zugangsdaten ein und fülle dann die Schwellenwerte aus. Jedes Feld erklärt sich im Editor selbst.
- Klicke auf Check hinzufügen.
Tipps
- Gewähre das Monitoring-Konto auf jeder Instanz, die überwacht werden soll. Nutze auf einem Microsoft SQL Server-Host mit mehreren Instanzen auf jeder denselben Login-Namen und dasselbe Passwort — der Check schickt einen Satz Zugangsdaten an alle Instanzen, die er findet.
- Ein Server, der nur auf Loopback lauscht, ist von einem anderen Gerät aus nie erreichbar, was der Grant auch sagt. Schlägt eine entfernte Anmeldung fehl, während eine lokale funktioniert, dann prüfe die Lauschadresse und die Host-Firewall, bevor du das Konto erneut anfasst.
- Halte die Abfrage-Checks eng. Gewähre
SELECTauf genau dem Schema oder der Tabelle, die die Anweisung liest, und schreibe die Anweisung so, dass sie eine Zeile pro Problem zurückgibt — die Abfrage-Checks zählen Zeilen, keine Werte.
Siehe auch: Checks · Checks mit Konfigurationspaketen zuweisen