Inhalt

Legacy Authentication kontrolliert abschalten - Einblicke gewinnen

Artikelübersicht

Dies ist Teil drei der sechsteiligen Serie zum Thema “Legacy Authentication kontrolliert abschalten”.

  1. Vorwort
  2. Modern Authentication aktivieren
  3. Voraussetzungen schaffen
  4. Einblicke gewinnen
  5. Die ersten 90%
  6. Die nächsten 9%
  7. Abschaltung

Wiederholung

Im ersten Teil wurde Modern Authentication aktiviert und im Zweiten wurden die Vorrausetzungen geschaffen ausführliche Reports zu erstellen und Legacy Authentication für einzelne Benutzer zu deaktiveren.

Conditional Access Policy Logik

Um besser zu verstehen wie es jetzt möglich ist einzelne Benutzer zu blockieren, werfen wir einen Blick auf die erstellten Conditional Access Policies und die damit verbundene Login.

Phase 1 - Impliziertes Erlauben

In Phase 1 wollen wir nur Benutzer blockieren die Legacy Authentication (LA) nicht nutzen. So verhindern wir, dass die Nutzer während der Abschaltung eventuell doch noch eine App nutzen, die Modern Authentication (MA) nicht unterstützt.

Beispiel

  • Bob und Alice nutzen beide Exchange Online.
  • Bob verwendet den nativen iOS Mail Client mit Exchange ActiveSync Client (LA) und Microsoft Apps for business (MA).
  • Alice nutzt die Outlook mobile App (MA) und Microsoft Apps for business (MA).

Da Alice ausschließlich Modern Authentication nutzt, wird Sie in die Gruppe “CAPolicy-Include-Block-Legacy-Authentication” aufgenommen. Sollte Sie nun versuchen mit einem Legacy Auth Client auf Exchange zuzugreifen, wird dieser Versuch durch die Conditional Access Policy “Temporary Policy: Block legacy authentication Rollout” blockiert.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/ConditionalAccessLogic-Phase1.png

Phase 2 - Explizites Erlauben

In Phase 2 wird die Legacy Authentication (LA) für alle Benutzer deaktiviert und nur explizit definierte Benutzer können Sie weiter nutzen.

Beispiel

  • Janine und Kevin nutzen beide Exchange Online
  • Janine will auf Ihrem neuen Android Smartphone eine Mail-App mit Exchange ActiveSync (LA) einrichten
  • Kevin hat ein bestehendes Android Gerät und nutzt eine Mail-App mit Exchange ActiveSync (LA)

Kevin wurde in die Gruppe “CAPolicy-Exclude-Block-Legacy-Authentication” aufgenommen und kann daher seine Mail-App weiter nutzen.
Janine wird beim Login blockiert und muss auf eine Mail-App umsteigen die Modern Authentication unterstützt.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/ConditionalAccessLogic-Phase2.png

Auswertung

Um die Benutzer für die erste Phase zu identifizieren stehen mehrere Werkzeuge zu Verfügung. Gemeinsam genutzt bieten diese Tools eine unglaublich große Flexibilität und detailierte Einblicke in die Nutzung der Microsoft 365 Landschaft.

Workbooks

Die von Microsoft zu Verfügung gestellten Entra ID (Azure AD) Workbooks bieten einen grafischen Einstieg in die Auswertung. Jedes Workbook ist für eine spezielle Auswertung konzipiert, weshalb wir im Verlauf der nächsten Zeit einige der Workbooks nutzen werden.

Die Grundlage der Workbooks bildet der Dienst Azure Monitor Workbooks. Mittels diesem können Daten realtiv einfach in grafischer Form aufbereitet werden und es wird dem Nutzer somit einfacher gemacht, aus den Datenmengen Informationen zu ziehen.

Ein großer Vorteil der Workbooks ist, das sie interaktiv genutzt werden können und über Filter und Drill-Down Optionen die Daten einfach reduziert werden können.

Als Quelle für diese Daten dient der im letzten Kapitel angelegte Log Analytics Workspace und die dort gesammelten SignIn Daten.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/AzurePortalAzureADWorkbooksOverview.png

Allgemeine Navigation

Jedes Workbook bietet mehrere Filter über die die angezeigten Daten eingeschränkt werden können. Immer verfügbar ist der Zeitraum, die weiteren Parameter variieren je nach ausgewähltem Workbook.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/AzurePortalAzureADWorkbooksFilter.png

Sign-ins using Legacy Auth

Das Workbook “Sign-ins using Legacy Auth” bietet einen Einblick in die Nutzung von Legacy Authentication und die davon betroffnen Apps und Protokolle.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/SignInsUsingLegacyAuth.png

Info
Bei Exchange Online können die Zahlen bei den erfolgreichen Anmeldungen mit Legacy Authentication in die Irre führen. Dies liegt an der besonderen Art und Weise wie Microsoft Exchange ActiveSync Verbindungen blockiert. Genauers gibt es im nächsten Artikel der Serie.

Conditional Access Insights and Reporting

Mit diesem Workbook kann die Auswirkung einer Conditional Access Police genau beobachtet werden. So kann anhand der gesammelten Daten für die Conditional Access Policy “Common Policy: Block legacy authentication” abgeschätzt werden, welche Auswirkungen eine Abschaltung für die Benutzer hat.

Dieses Workbook bietet zusätzlich einen detailierteren Einblick in die Verteilung der genutzten Endgeräte, der Apps, Sign-In Risk und dem, auf Basis der IP-Adresse ermittelten, Standort der Nutzer.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/CAInsightsBreakdown.png

In diesem Fall ist die Filterung auf die korrekte Conditional Access Policy und den Zeitraum sehr wichtig um aussagekräftige Ergebnisse zu bekommen.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/CAInsightsFilter.png

Kusto Abfragen

Die eben behandelten Workbooks sind ein tolles grafisches und interaktives Hilfsmittel und basieren, wie erwähnt, auf den aufgezeichneten SignIn Daten im Log Analytics Workspace. Die eigentlichen Rohdaten können Sie mittels Kusto Abfragen aber auch bequem selbst abgefragt werden.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/AzurePortalAzureADLogs.png

Einen guten Einstieg bieten dabei die vorhandenen Workbooks. Über das blaue Log Analytics Icon /legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/LogAnalyticsWorkspacesIcon.png öffnet sich die zugrundeliegende Abfrage und kann weiter modifiziert werden.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/AzurePortalAzureADLogsExample.png

Tipp

Unter bestimmten Umständen wird der in der Abfrage angegebene Zeitrahmen nicht berücksichtigt. Hier ist es wichtig als Time range die Option “Set in Query” zu wählen.

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/AzurePortalAzureADLogsTimeRange.png /legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/AzurePortalAzureADLogsSetInQuery.png

Verwendete Legacy Protokolle identifizieren

Die verwendeten Legacy Protokolle sind der Startpunkt für die Deaktivierung. Je nachdem welchen Dienst noch Legacy Authentication nutzt müssen andere Gegenmaßnahmen ergriffen werden.

Exchange ist eines der größeren Problemkinder in dieser Hinsicht, da Mail ein sehr alter Dienst mit vielen alten Protokollen ist. Daher ist es nicht verwunderlich wenn ein Großteil der Protokolle mit Exchange zu tun haben.

SigninLogs
// set TimeSpan to 7 days
| where TimeGenerated > ago(7d)
// Only query successful logins
| extend errorCode = toint(Status.errorCode)
| where errorCode == 0
// Check if ClientAppUsed is considered Legacy Auth - Empty is not considered Legacy Auth
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)  
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes") 
| where isLegacyAuth == "Yes"
| summarize Count=count()  by ClientAppUsed, AppDisplayName

Erklärung

Die Abfrage nutzt alle Daten in der Tabelle SigninLogs die in den letzten 7 Tagen erstellt wurden als Datengrundlage.

1
2
3
SigninLogs
// set TimeSpan to 7 days
| where TimeGenerated > ago(7d)

Im nächsten Schritt werden nur die Anmeldungen ausgewertet die sich erfolgreich am System angemeldet haben. Ob eine Botfarm in Buxtehude sich nicht erfolgreich anmelden konnte, kann uns in diesem Kontext egal sein.

4
5
6
// Only query successful logins
| extend errorCode = toint(Status.errorCode)
| where errorCode == 0

Nun wird die Anwendung, die für die Anmeldung genutzt wurde geprüft. Sollte keine Information über diese vorliegen wird der Wert für ClientAppUsed auf “Unknown” gesetzt.

7
8
// Check if ClientAppUsed is considered Legacy Auth - Empty is not considered Legacy Auth
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)  

Auf Basis der Client App wird nun definiert ob es sich bei dem Signin um eine Legacy Anmeldung handelt. Browser, Microsoft mobile Apps und Desktop Apps (>= 2013) gelten als Modern Auth, Unbekannte werden als Unknown markiert und der Rest ist Legacy Authentication.

9
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes") 

Ausgegeben werden nur LA SignIns und auf Basis der Client App und dem genutzten Online Dienst werden diese Daten aggregiert.

10
11
| where isLegacyAuth == "Yes"
| summarize Count=count()  by ClientAppUsed, AppDisplayName

Beispiel

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/LegacyClientAppUsed.png

Verwendete Applikationen identifizieren

Um besser beurteilen zu können, welche Applikationen diese veralteten Protokolle nutzen, kann der UserAgent ausgewertet werden.

SigninLogs
// set TimeSpan to 7 days
| where TimeGenerated > ago(7d)
// Only query successful logins
| extend errorCode = toint(Status.errorCode)
| where errorCode == 0
// Check if ClientAppUsed is considered Legacy Auth - Empty is not considered Legacy Auth
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)  
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes") 
| where isLegacyAuth == "Yes"
| summarize Count=count() by UserAgent, AppDisplayName
| sort by Count

Erklärung

Die ersten 10 Zeilen der Abfrage sind identisch zur ersten Abfrage.

Entscheidend ist die Gruppierung auf Basis des UserAgent und des genutzten Online Dienstes in Zeile 11.
Zeile 12 sortiert das Ergebnis noch absteigend nach Anzahl der Anmeldungen.

11
12
| summarize Count=count() by UserAgent, AppDisplayName
| sort by Count

Beispiel

/legacy-authentication-kontrolliert-abschalten-einblicke-gewinnen/images/UserAgents.png

Warnung

Ein UserAgent der mit Microsoft Office/14.0 beginnt, deutet auf noch aktive Office 2010 Installationen hin.

End of support für Office 2010 war am 13.10.2020.

Nutzer ohne Legacy Authentication SignIns identifizieren

Damit im nächsten Artikel Legacy Authentication wirklich für (hoffentlich 😉) 90% aller Benutzer deaktiviert werden kann, brauchen wir die Information welche Benutzer sich in den letzten 7 Tagen nicht mittels Legacy Authentication angemeldet haben.

Info
In der initialen Version dieser Abfrage wurden die Daten aus den AADNonInteractiveUserSignInLogsnicht berücksichtigt, was zu Problemen führen konnte. Die neue Abfrage berücksichtigt diese Daten.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
let distinctSigninLogs = SigninLogs
// set TimeSpan to 7 days
| where TimeGenerated > ago(7d)
// Only query successful logins
| extend Status = todynamic(Status)
| extend errorCode = toint(Status.errorCode)
| where errorCode == 0
// Check if ClientAppUsed is considered Legacy Auth - Empty is not considered Legacy Auth
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)  
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes");
let distinctAADNonInteractiveUserSignInLogs = AADNonInteractiveUserSignInLogs
// set TimeSpan to 7 days
| where TimeGenerated > ago(7d)
// Only query successful logins
| extend Status = todynamic(Status)
| extend errorCode = toint(Status.errorCode)
| where errorCode == 0
// Check if ClientAppUsed is considered Legacy Auth - Empty is not considered Legacy Auth
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)  
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes")
| distinct UserPrincipalName, isLegacyAuth;
let distinctAllSignInLogs = union distinctAADNonInteractiveUserSignInLogs, distinctSigninLogs
| distinct UserPrincipalName, isLegacyAuth;
let LegacyAuthSigninLogs = distinctAllSignInLogs
| where isLegacyAuth == "Yes"
| project UserPrincipalName;
distinctAllSignInLogs
| where UserPrincipalName !in (LegacyAuthSigninLogs)

Erklärung

Die ersten 10 Zeilen sind fast identisch mit den bisherigen Abfragen, jedoch wird in Zeile 1 der Code mit dem Befehl let mit dem Namen distinctSigninLogs verbunden und kann so einfacher im nachfolgenden Code genutzt werden.

Das macht den Code schlanker, da dieselbe Expression nicht mehrfach ausgeschrieben vorkommen muss.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let distinctSigninLogs = SigninLogs
// set TimeSpan to 7 days
| where TimeGenerated > ago(7d)
// Only query successful logins
| extend errorCode = toint(Status.errorCode)
| where errorCode == 0
// Check if ClientAppUsed is considered Legacy Auth - Empty is not considered Legacy Auth
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)  
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes")
| distinct UserPrincipalName, isLegacyAuth;

In Zeile 10 wird zusätzlich noch der distinct Operator genutzt um jeden Eintrag nur einmal zu erhalten. Also für jeden UserPrincipalName gibt es maximal drei Einträge.

UserPrincipalName isLegacyAuth
bob@bader.cloud Yes
bob@bader.cloud No
bob@bader.cloud Unknown
alice@bader.cloud No

Zeile 11 - 21 führt die gleiche Abfrage auf Basis der Daten in AADNonInteractiveUserSignInLogsum auch nicht interaktive Anmeldungen zu erfassen.

Zeile 22 - 23 fassen die Daten aus distinctSigninLogs und distinctAADNonInteractiveUserSignInLogs zusammen und speichern diese in distinctAllSignInLogs.

22
23
let distinctAllSignInLogs = union distinctAADNonInteractiveUserSignInLogs, distinctSigninLogs
| distinct UserPrincipalName, isLegacyAuth;

In Zeile 24 - 26 werden ausschließlich die Benutzernamen als LegacyAuthSigninLogs gespeichert, bei welchen isLegacyAuth dem Wert “Yes” entspricht.

24
25
26
let LegacyAuthSigninLogs = distinctAllSignInLogs
| where isLegacyAuth == "Yes"
| project UserPrincipalName;

All das war nur Vorbereitung für die eigentliche Abfrage. Diese nutzt alle eindeutigen SignIns aus der “Tabelle” distinctSigninLogs und gibt nur Benutzernamen aus, die nicht in der “Tabelle” LegacyAuthSigninLogs vorkommen. Also nur Benutzer die keinerleit Legacy Authentication genutzt haben.

27
28
distinctSigninLogs
| where UserPrincipalName !in (LegacyAuthSigninLogs)
Tipp
Wie performant die Log Analytics Workspaces von Microsoft sind zeigt das obere Beispiel.
Die Datenabfrage ist nur bedingt optimiert und kann trotzdem bei über 1,6 Millionen SignIns in 1,593 Millisekunden ausgeführt werden.

Ausblick

Im nächsten Artikel werden wir Legacy Authentication für die Benutzer deaktivieren, bei denen es keine negativen Auswirkungen hat.