Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Datenbanküberwachungen sind eine wichtige Komponente der Complianceanforderungen Ihrer Organisation. Durch die Überwachung gezielter Aktivitäten können Sie Ihre Sicherheitsgrundwerte erreichen. In Azure Database for PostgreSQL flexible Server können Sie Audits mithilfe der pgaudit PG-Erweiterung einrichten, wie in dem Audit-Logging in der Azure-Datenbank für PostgreSQL beschrieben.
Eine Herausforderung besteht darin, das Überwachungsfeature zusammen mit der Microsoft Entra ID-Authentifizierung zu verwenden, wenn Sie Microsoft Entra-ID-Gruppen verwenden und die Aktionen einzelner Gruppenmitglieder überwachen möchten. Diese Herausforderung besteht, da sich Gruppenmitglieder mit ihren persönlichen Zugriffstoken anmelden, aber den Gruppennamen als Benutzernamen verwenden.
Kusto Query Language (KQL) ist eine leistungsfähige pipelinegesteuerte, schreibgeschützte Abfragesprache, die das Abfragen von Azure-Dienstprotokollen ermöglicht. KQL unterstützt das Abfragen von Azure-Protokollen, um schnell ein hohes Datenvolumen zu analysieren. Verwenden Sie für diesen Artikel KQL, um Azure Postgres-Protokolle abzufragen und Microsoft Entra ID-Benutzerinformationen aus Überwachungsprotokollen zu extrahieren.
Voraussetzungen
- Aktivieren der Überwachungsprotokollierung – Überwachungsprotokollierung in Azure-Datenbank für PostgreSQL
- Aktivieren von Azure Postgres-Protokollen, die an Azure Log Analytics gesendet werden – Konfigurieren und Zugreifen auf Protokolle
- Passen Sie den
log_line_prefix-Parameter an: Legen Sie im Blatt „Parameter“log_line_prefixfest, um die Escapezeichenuser=%u,db=%d,session=%c,sess_time=%sin derselben Reihenfolge aufzunehmen, um die gewünschten Ergebnisse zu erzielen.- Bevor:
log_line_prefix=%t-%c- - Nach:
log_line_prefix=%t-%c-user=%u,db=%d,session=%c,sess_time=%s
- Bevor:
Kusto-Abfrage
Die folgende Kusto-Abfrage fragt zweimal AzureDiagnostics ab.
Die erste Unterabfrage findet alle Zeilen, die die Zeichenfolge Microsoft Entra ID connection authorized enthalten, und extrahiert die PrincipalName aus diesen Protokollzeilen zusammen mit der SessionId.
Die zweite Unterabfrage findet alle Überwachungsprotokolle.
Diese beiden Unterabfragen werden schließlich auf dem SessionId verbunden.
let lookbackTime = ago(3d);
let opindex = 3;
let startIndex = toscalar(range thirdIndex from opindex to opindex step 1
| project thirdIndex);
AzureDiagnostics
| where ResourceProvider == 'MICROSOFT.DBFORPOSTGRESQL'
| where TimeGenerated >= lookbackTime
| where Message contains 'Microsoft Entra ID connection authorized'
| extend SessionId = tostring(split(tostring(split(Message, 'session=')[-1]), ',sess_time')[-2])
| extend UPN = iff(Message contains 'UPN',tostring(split(tostring(split(Message, 'UPN=')[-1]), 'oid=')[-2]), '')
| extend appId = iff(Message contains 'appid', tostring(split(tostring(split(Message, 'appid=')[-1]), 'oid=')[-2]), '')
| extend PrincipalName = strcat(UPN, appId)
| project SessionId, PrincipalName
| join kind=leftouter
(
AzureDiagnostics
| where ResourceProvider == 'MICROSOFT.DBFORPOSTGRESQL'
| where TimeGenerated >= lookbackTime
| where Message contains 'AUDIT: SESSION'
| extend RoleName = tostring(split(tostring(split(Message, 'user=')[-1]), ',db')[-2])
| where RoleName !in ('azuresu', '[unknown]', 'postgres', '')
| extend SessionId = tostring(split(tostring(split(Message, 'session=')[-1]), ',sess_time')[-2])
| extend SubMessage = tostring(split(Message, 'SESSION,')[-1])
| extend splitArray = split(SubMessage, ',')
| extend SqlQueryP1 = tostring(split(tostring(split(Message, ',,,')[-1]), ',<')[-2])
| extend SqlQueryP2 = replace_string(tostring(split(SqlQueryP1, ',\"')[-1]), '"', '')
| extend SqlQueryP3 = tostring(split(Message, ',,,')[1])
| extend OperationType = tostring(splitArray[startIndex])
| extend SqlQuery = trim('"', case(OperationType == 'EXECUTE', SqlQueryP2, SqlQueryP1 == '', SqlQueryP3, SqlQueryP1))
)
on $left.SessionId == $right.SessionId
| project TimeGenerated, PrincipalName, RoleName, OperationType, SqlQuery
Beispielergebnisse
Die resultierende Tabelle sieht wie folgt aus:
| Zeitpunkt der Generierung | Hauptname | Rollenname | Operationstyp | SqlQuery |
|---|---|---|---|---|
| 2025-12-12T16:25:05.104Z | user@example.com | ExampleGroupName | SELECT | select * from pg_seclabels; |
| 2025-12-12T16:25:04.000Z | user@example.com | user@example.com | SELECT | select * from pg_seclabels; |
Wenn sich der Benutzer als Gruppenrolle anmeldet, zeigen die Spalten PrincipalName und RoleName unterschiedliche Werte an, wie in der ersten Zeile des Beispiels.
Der PrincipalName Wert gibt den Benutzer an, der sich angemeldet hat. Der RoleName Wert identifiziert die Rolle in PostgreSQL, auf die der Benutzer nach der Anmeldung zugreift.
PrincipalName ist entweder der Benutzerprinzipalname (User Principal Name, UPN) oder appId , je nachdem, ob sich der Benutzerprinzipal oder der Dienstprinzipal anmeldet.