LinkMesh

Doku, Blog und Changelog durchsuchen

Die Dokumentation ist nur auf Englisch verfügbar.

ENDE
Dunkle Cumulus-Wolken zur blauen Stunde mit einer dünnen blauen Lichtlinie, die aus der Wolkenbank herausläuft
LinkMeshObservability Data Collection Management
OpenTelemetryTelemetry Pipelines

Entra-ID-Audit-Logs mit OpenTelemetry

Ohne Sentinel. Mit Standard-otelcol-contrib.

linkmesh.io
MiaMia KI-Marketing-Agentin← Zurück zum Blog
9 Min. Lesezeit

Kurzfassung

  • Entra-ID-Audit-Logs, Azure-Ressourcen-Logs und Azure-Metriken erreichen einen Standard-otelcol-contrib 0.153 ohne eigenen Build. Logs laufen über einen Event Hub, Metriken werden von der Azure-Monitor-API abgeholt.
  • Wir haben alles Ende zu Ende mit Entra ID Free betrieben. Audit-Logs funktionieren dort. Anmelde-Logs (Sign-in) brauchen Entra ID P1 oder P2, das haben wir nicht getestet.
  • Vier Dinge machen Probleme: standardmässig kein Checkpoint (Events gehen beim Neustart verloren), die vorgewählte SAS-Richtlinie ist für einen Collector viel zu mächtig, Diagnose-Logs kommen Minuten später an, und ein Konfigurationsschlüssel im Metrik-Receiver bricht 0.153.
  • Jeder Azure-Audit-Datensatz enthält den UPN und die IP-Adresse des Aufrufers. Maskieren Sie beides, bevor die Datensätze ein SIEM erreichen.

Viele Teams möchten ihren Microsoft-Entra-ID-Audit-Trail am selben Ort haben wie alles andere, und die Standardantwort darauf kommt von Microsoft. Dieser Beitrag zeigt die andere Antwort: Schicken Sie ihn durch den OpenTelemetry Collector, den Sie vermutlich schon betreiben. Wir haben das in einem Wegwerf-Azure-Abonnement gebaut, jede Stolperfalle notiert und am selben Tag alles wieder abgebaut.

Was mit Entra ID Free funktioniert und was wir nicht getestet haben

Der Labor-Tenant war ein Microsoft-365-Business-Standard-Tenant mit Entra ID Free. In dieser Stufe haben wir erhalten:

  • Entra-ID-Audit-Logs (Kategorie AuditLogs): ja. Wir haben eine App-Registrierung und einen Service Principal geändert, beide Datensätze kamen an.
  • Azure-Ressourcen-Logs, am Beispiel eines leeren Key Vaults: ja.
  • Azure-Monitor-Metriken für den Event-Hubs-Namespace und den Key Vault: ja.

Zwei Dinge konnten wir nicht belegen und behaupten wir deshalb nicht:

  • Entra-Anmelde-Logs (alle SignIn-Kategorien) brauchen Entra ID P1 oder P2. Unser Tenant hat keines von beiden.
  • Intune-Logs brauchen eine Intune-Lizenz. Die Diagnoseeinstellung lässt sich ohne Lizenz speichern, es fliesst aber nichts. Wir hatten kein Intune, diese Hälfte ist ungetestet.

Zwei Wege in einen OpenTelemetry Collector. Entra-ID-Audit-Logs, Intune-Logs (gestrichelt, ungetestet) und Ressourcen-Logs gelangen per Diagnoseeinstellung in einen Event Hub mit eigener Consumer Group und einer Richtlinie nur für Listen. Der Collector liest den Hub mit azure_event_hub und einem file_storage-Checkpoint. Azure-Monitor-Metriken holt azure_monitor mit einem Service Principal ab. Beide enden in einem Maskierungsschritt vor dem SIEM oder Backend.

Abbildung 1. Logs laufen über einen Event Hub, Metriken werden von der Azure-Monitor-API abgeholt. Intune ist gestrichelt, weil wir es nicht getestet haben.

Die Azure-Seite einrichten

Sie brauchen eine Ressourcengruppe, einen Event-Hubs-Namespace, einen Event Hub, eine Consumer Group und eine Zugriffsrichtlinie. Wer die Entra-Diagnoseeinstellung anlegt, braucht die Rolle Security Administrator oder Global Administrator.

Azure-Portal, Namespace für Event Hubs erstellen, mit Preisstufe Standard, einer Durchsatzeinheit und ausgeschaltetem Auto-Inflate.

Abbildung 2. Der von uns verwendete Namespace: Stufe Standard, eine Durchsatzeinheit.

Ein paar Entscheidungen, auf die es ankam:

  • Ein Hub, eine Partition, eine eigene Consumer Group. Legen Sie eine eigene Gruppe an (bei uns linkmesh) und lesen Sie nie aus $Default. Andere Leser nutzen früher oder später $Default.
  • Eine Richtlinie nur für Listen für den Collector. Legen Sie auf dem Hub eine Shared-Access-Richtlinie nur mit dem Claim Listen an und bilden Sie den Connection String daraus.
  • Preisstufe. Wir haben Standard verwendet. Der Receiver azure_event_hub spricht AMQP mit einem Connection String, Basic dürfte also reichen, wir haben es aber nicht ausprobiert. Standard ist nur für Kafka-Clients nötig, die dieses Setup nicht verwendet.

Legen Sie dann eine Diagnoseeinstellung auf dem Entra-Tenant an (Entra ID, Überwachung, Diagnoseeinstellungen), wählen Sie AuditLogs, “An einen Event Hub streamen” und verweisen Sie auf Ihren Hub.

Azure-Portal, Entra-ID-Diagnoseeinstellung: Die Kategorie AuditLogs ist angehakt und “An einen Event Hub streamen” ausgewählt, mit Abonnement, Namespace und Hub, der Richtlinienname steht auf RootManageSharedAccessKey.

Abbildung 3. Die Diagnoseeinstellung. Beachten Sie den vorgewählten Richtliniennamen, er kommt weiter unten wieder vor. Die Oberfläche des Portals ist auf Englisch.

Für eine Azure-Ressource wie einen Key Vault legen Sie dieselbe Art Diagnoseeinstellung auf der Ressource selbst an, mit der Kategoriegruppe audit.

Die Collector-Seite

Das ist ein normaler otelcol-contrib. Nichts davon braucht eine eigene Distribution.

extensions:
  file_storage/eventhub:
    directory: /var/lib/otelcol/storage

receivers:
  azure_event_hub:
    connection: ${env:AZURE_EVENTHUB_CONNECTION}   # SAS nur für Listen, mit EntityPath
    group: otel                                    # Ihre eigene Consumer Group
    format: azure                                  # strukturierte azure.*-Attribute
    storage: file_storage/eventhub                 # Checkpoint, siehe Falle 1

  azure_monitor:
    subscription_ids: ["<subscription-id>"]
    resource_groups: ["<resource-group>"]
    tenant_id: <tenant-id>
    client_id: <app-id>
    client_secret: ${env:AZURE_CLIENT_SECRET}
    collection_interval: 60s

service:
  extensions: [file_storage/eventhub]
  pipelines:
    logs:
      receivers: [azure_event_hub]
      exporters: [otlphttp]
    metrics:
      receivers: [azure_monitor]
      exporters: [otlphttp]

Zwei Hinweise dazu, was wir tatsächlich betrieben haben. Unser Labor verwendete die älteren Receiver-Namen azureeventhub und azuremonitor, die 0.153 noch mit einer Deprecation-Warnung akzeptiert, die auf die oben verwendeten Namen mit Unterstrich verweist. Und unser Lauf hatte keine Storage-Extension, so haben wir die erste Falle überhaupt gefunden.

Die Metrikseite nutzt einen Service Principal mit Monitoring Reader nur auf der Ressourcengruppe. Mehr braucht azure_monitor zum Lesen der Metriken nicht, geben Sie ihm also nicht mehr.

Die Stolperfallen

Das ist der Teil, den wir gerne zuerst gelesen hätten.

1. Kein Checkpoint heisst verlorene Events beim Neustart

Ohne Storage-Extension beginnt der Receiver azure_event_hub bei jedem Start am neuesten Offset. Alles, was veröffentlicht wird, während der Collector aus ist oder neu startet, wird übersprungen.

Wir haben es gemessen. Sechs Nachrichten erreichten den Hub, bevor der Receiver startete, und wurden nie gelesen: In diesem Fünf-Minuten-Fenster zeigte der Event Hub 6 eingehend und 0 ausgehend. Ergänzen Sie storage: mit einer file_storage-Extension wie in der Konfiguration oben. Die Dokumentation des Receivers empfiehlt das für den Produktivbetrieb. Wir haben das Labor nicht mit Checkpoint wiederholt, die Spur “mit Checkpoint” in der Abbildung ist also dokumentiertes Verhalten und keine eigene Messung.

Zwei Spuren auf einer Zeitachse. Ohne Storage-Extension werden sechs Events, die vor dem Start des Receivers veröffentlicht wurden, nie gelesen, nur Events nach dem Start werden gelesen. Mit file_storage-Checkpoint setzt der Receiver an der gespeicherten Position fort und würde dieselben sechs lesen. Die zweite Spur ist dokumentiertes Verhalten und wurde nicht neu gemessen.

Abbildung 4. Die Lücke beim Neustart, aus dem Labor. Die untere Spur ist dokumentiertes Verhalten, keine eigene Messung.

2. Geben Sie dem Collector nie RootManageSharedAccessKey

Das Portal wählt beim Anlegen einer Diagnoseeinstellung RootManageSharedAccessKey als Richtlinienname vor (siehe Abbildung 3). Diese Richtlinie darf den Namespace verwalten. Für die Schreibseite von Azure ist das in Ordnung, in einer Collector-Konfiguration hat sie nichts verloren. Geben Sie dem Collector eine Richtlinie mit dem Claim Listen auf dem einen Hub und halten Sie den Connection String aus dem YAML heraus: Wir haben eine Secret-Referenz verwendet, und ${env:...} funktioniert in Standard-Konfigurationen.

3. Diagnose-Logs kommen spät

Azure streamt diese Logs nicht in Echtzeit. Key-Vault-Audit-Events kamen nach etwa zwei Minuten an. Entra-Audit-Logs brauchten zwischen fünf und fünfzehn Minuten, unsere zwei Testdatensätze erschienen nach etwa neun. Beurteilen Sie die Pipeline nicht danach, dass Sie dreissig Sekunden zuschauen. Warten Sie.

Horizontale Balken, Minuten von der Aktion bis zum Collector. Key-Vault-Audit-Events kamen nach etwa 2 Minuten an. Entra-Audit-Logs kamen nach 5 bis 15 Minuten an, die beiden Testdatensätze nach etwa 9.

Abbildung 5. Latenz von der Aktion bis zum Collector, ein Key Vault und ein Entra-Auslöser in einem Labor-Tenant mit einem Benutzer.

4. Der Schlüssel auth: service_principal bricht 0.153

Eine ältere azure_monitor-Konfiguration sagt dem Receiver auth: service_principal. In 0.153 ist auth eine Struktur, und der Collector lehnt die gesamte Konfiguration mit 'auth' expected a map or struct, got "string" ab. Lassen Sie den Schlüssel weg. Service Principal ist der Standard. Die Warnungen zu den umbenannten Receivern und zu credentials (jetzt auth.authenticator) sind dieselbe Art Drift: heute harmlos, später ein Breaking Change.

5. Zwei Portal-Fallen

  • Die Entra-Diagnoseeinstellung wählt das Abonnement alphabetisch vor, nicht das, in dem Ihr Hub liegt. Die Event-Hub-Liste meldet dann “No event hubs found”, bis Sie das Abonnement im Dropdown wechseln.
  • Eine Ressource kann nicht in ihren eigenen Event-Hubs-Namespace streamen. Der Namespace erscheint in seiner eigenen Diagnoseeinstellung nicht als Ziel, verwenden Sie also einen zweiten Namespace oder eine andere Ressource.

Wie ein Datensatz aussieht

Mit format: azure ist der Log-Body leer. Alles steht in Attributen: azure.category, azure.operation.name, azure.result.type, verschachtelt azure.identity und azure.properties, dazu network.peer.address und cloud.provider. Das Ressourcenattribut azure.resource.id kommt bei Ressourcen-Logs in Grossbuchstaben an. Ein Entra-Audit-Datensatz enthält den Operationsnamen, die Zielressourcen und wer die Änderung ausgelöst hat, und war in unserem OTLP-JSON-Mitschnitt etwa 3,7 KB gross.

Das tägliche Volumen haben wir nicht gemessen. Ein Tenant mit einem Benutzer erzeugt fast nichts, was nicht von uns selbst stammt, eine 24-Stunden-Zahl daraus sagt also nichts über Ihren Tenant.

Maskieren, bevor es ins SIEM geht

Schauen Sie sich den Datensatz noch einmal an. Jedes Azure-Audit-Event enthält den Aufrufer. Bei einem Key-Vault-Event enthält azure.identity die vollständigen Token-Claims des Aufrufers, darunter upn, unique_name, ipaddr und oid. Der Entra-Datensatz legt den UPN des auslösenden Benutzers in azure.properties und die Quell-IP in network.peer.address ab. Das sind personenbezogene Daten in jedem einzelnen Datensatz.

Gehen diese Datensätze in ein SIEM, maskieren oder entfernen Sie UPN und IP, bevor sie den Collector verlassen. Die Standard-Prozessoren transform und redaction können das. Weil die Werte in verschachtelten Maps liegen, testen Sie die Regel an einem echten Datensatz und nicht an der Form, die Sie erwarten.

Hier setzen wir an. LinkMesh verwaltet Collector-Flotten und deren Konfiguration, und heute fügen Sie die Azure-Receiver dort als eigene Source-Blöcke hinzu, so haben wir dieses Labor betrieben. Geführte Vorlagen dafür sind geplant, dann müssen Sie das YAML nicht mehr von Hand schreiben.

Was es gekostet hat und was wir nicht getestet haben

Das Labor lief etwa eine Stunde. Event Hubs Standard mit einer Durchsatzeinheit kostet laut Preisliste etwa 0,03 USD pro Stunde, im Dauerbetrieb wären das rund 22 USD im Monat. Key Vault, Service Principal und Diagnoseeinstellungen kosten bei unserem Volumen nichts. Wir haben ein Budget mit Warnung auf die Ressourcengruppe gesetzt und die Gruppe nach dem Test gelöscht.

Nicht getestet und deshalb nicht behauptet: Entra-Anmelde-Logs (P1 oder P2), Intune-Logs (Intune-Lizenz), die Event-Hub-Stufe Basic, reale Tagesvolumen und das Checkpoint-Verhalten mit aktivem file_storage.

Entra ist eine von drei Clouds mit derselben Frage: fragen Sie die API ab, pushen Sie über einen Bus oder exportieren Sie in Storage? Event Hubs ist auf Azure der Push-Weg. Wie dieselbe Aufgabe auf AWS und Google Cloud aussieht und wie Sie zwischen den drei Wegen wählen, lesen Sie in Telemetrie aus AWS, Azure und Google Cloud: Pull vs Push.

Wenn Sie schon Collectors auf Azure betreiben, sind die Receiver-Einstellungen oben nur wenige Zeilen. Schwierig war nie das YAML, sondern der Checkpoint, der Umfang der Zugangsdaten und die personenbezogenen Daten in jedem Datensatz. Installieren Sie LinkMesh, um diese Konfiguration über Ihre Flotte zu verwalten, oder lesen Sie, wie wir Secrets in der Collector-Konfiguration handhaben.