AzureAD CloudSync Proxy
Wie kann ich mit AzureAD Connect CloudSync eine Verbindung des Agenten zum Server über einen HTTP-Proxy-Server einrichten?
Anforderungen
Große Firmen mit maximalem Funktionsumfang, insbesondere Device Management und Exchange Hybrid müssen auch im März 2023 den ADSync Connect-Service installieren während AzureAD Connect Cloud Sync für einfachere und oftmals kleinere Umgebungen gedacht ist. Oft soll der Agent sogar auf einem Domain Controller installiert werden, was supportet ist. Dennoch ist es auch hier nicht selbstverständlich, das der Prozess direkt die Gegenstellen bei Microsoft erreichen kann, sondern über einen Proxy-Server gehen muss.
Ein HTTP-Proxy kann den Client authentifizieren und sehr gut einen Missbrauch der Ports für andere Protokolle verhindern, da er "http" versteht und den angesprochenen Hostnamen mit einer Allow-Liste vergleichen kann.
Quellenstudium
Für den klassischen ADSync Connect gibt es einige Quelle, die eine Konfiguration über einen Proxy-Server beschreiben.
- Prerequisites for Azure AD Connect - Connectivity
https://learn.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-install-prerequisites#connectivity - Deploying Azure Active Directory Sync Behind a Proxy
https://social.technet.microsoft.com/wiki/contents/articles/31148.deploying-azure-active-directory-sync-behind-a-proxy.aspx
Durch Anpassen der Dateien
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config
C:\Program Files\Microsoft Azure AD Sync\Bin\miiserver.exe.config - HOWTO: Install Azure AD Connect behind an Internet Proxy
https://dirteam.com/sander/2021/01/19/howto-install-azure-ad-connect-behind-an-internet-proxy/ - How to run Azure AD Connect behind proxy server
https://gist.github.com/machv/b4478a57bef795029a08aed4a25f8713
Für Azure AD Connect CloudSync ist die Quellenlage aber viel dünner. Eigentlich gibt es nur einen Hinweis auf einen Proxy server auf den Prerequisites
- Prerequisites for Azure AD Connect cloud sync - Firewall and
Proxy requirements
https://learn.microsoft.com/en-us/azure/active-directory/cloud-sync/how-to-prerequisites?tabs=public-cloud#firewall-and-proxy-requirements
Hier gibt es die Überschrift "Firewall and Proxy requirements" und im Text steht auch noch einmal:
If your firewall or proxy allows you to specify safe suffixes, add connections:..."
Gefolgt von einer Liste von URLs, die AzureAD Connect CloudSync braucht.
Während es für den "ConnectHealthAgent" eine Powershell zum Setzen eines Proxy gibt, hat die AADCloudSync-Shell keine Einstellungen zu eine Proxy zu bieten:
Import-module -Name "C:\Program Files\Microsoft Azure AD Connect Provisioning Agent\Utility\AADCloudSyncTools Get-Command -Module aadcloudsynctools CommandType Name ----------- ---- Function Connect-AADCloudSyncTools Function Export-AADCloudSyncToolsLogs Function Get-AADCloudSyncToolsInfo Function Get-AADCloudSyncToolsJob Function Get-AADCloudSyncToolsJobSchedule Function Get-AADCloudSyncToolsJobSchema Function Get-AADCloudSyncToolsJobScope Function Get-AADCloudSyncToolsJobSettings Function Get-AADCloudSyncToolsJobStatus Function Get-AADCloudSyncToolsServiceAccount Function Get-AADCloudSyncToolsServicePrincipal Function Install-AADCloudSyncToolsPrerequisites Function Invoke-AADCloudSyncToolsGraphQuery Function Remove-AADCloudSyncToolsGroupMembers Function Repair-AADCloudSyncToolsAccount Function Restart-AADCloudSyncToolsJob Function Resume-AADCloudSyncToolsJob Function Set-AADCloudSyncToolsJobSchema Function Set-AADCloudSyncToolsTenantId Function Start-AADCloudSyncToolsVerboseLogs Function Stop-AADCloudSyncToolsVerboseLogs Function Suspend-AADCloudSyncToolsJob
Also läuft es wohl wieder auf eigene Versuche hinaus, ob die Einstellungen zu einem HTTP-Proxy in der machine.config oder der "AADConnectProvisioningAgent.exe.config" im Programmverzeichnis ausreichen.
Vorarbeiten
Solche Änderungen sollten Sie besser nicht in einer Produktionsumgebung testen. Ich habe daher einfach einen Windows 2016 DC mit einem Developer-Tenant genutzt, um AzureAD CloudSync einzurichten, indem ich folgende Schritte durchlaufen habe:
- "Fiddler" als Proxy auf "localhost:8888" mit SSL-Inspection installiert
- Ausgehende Verbindungen von "Fiddler" in der Windows
Firewall erlaubt
Dazu habe ich den Prozess "fiddler.exe" zugelassen, ehe ich dann danach die Verbote setzt - Ausgehende Verbindungen zu Fiddler erlaubt
Zudem habe ich Verbindungen auf den Port 8888 erlaubt, damit der Proxy erreichbar ist. Auf eine Limitierung auf 127.0.0.1 habe ich verzichtet - Blockiere Ausgehende Verbindungen auf Port 80/443/8080
Dazu habe ich in der Windows Advanced Firewall einfach eine "Block"-Regel angelegt, die alle Verbindungen zu 80,443,8080 unterbindet
- Proxy-Konfiguration des Servers entsprechende angepasst
Dazu habe ich in einer Admin-Powershell folgende Befehle eingegeben:
# WinHTTP-Einstellungen für den Proxy angpasst netsh winhttp set proxy proxy-server="localhost:8888" bypass-list="<-loopback>;<local>" # PowerShell Default Proxy angepasst [system.net.webrequest]::defaultwebproxy = New-Object system.net.webproxy('http://localhost:8888') [system.net.webrequest]::defaultwebproxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials [system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
Zuletzt habe ich noch die Datei "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\Machine-config" um die folgenden Einträge erweitert:
Wenn es schon einen "<system.net>"-Bereich gibt, dann müssen Sie dies zusammenführen. Die Einträge sollten ans Ende gesetzt werden, damit sie nach der vorhandene generelle Definition sind.
<configuration> <system.net> <defaultProxy> <proxy proxyaddress="http://localhost:8888" bypassonlocal="True" usesystemdefault="True"/> </defaultProxy> </system.net> </configuration>
Um die Funktion generell zu testen, habe ich per Powershell einfach eine Office 365 URL abgerufen.
# test um den Request in Fiddler zu sehen (Invoke-WebRequest -Uri login.microsoftonline.com).StatusDescription
So konnte ich zumindest für eine PowerShell sehen, dass der Proxy über Fiddler genutzt wurde.
Installation und Konfiguration
Danach habe ich die Installation von "AADConnectProvisioningAgentSetup.exe" gestartet und die normale Installation durchgeführt. Ich bin kurz an der RC4-Abschaltung (Siehe Kerberos RC4 Abschaltung) mit dem GroupManagedServiceAccount hängen geblieben aber danach war die Installation abgeschlossen. Während der Installation habe ich in Fiddler gut sehen können, dass die Authentifizierung am AzureAD als Administrator als auch das Provisoining im AzureAD-Tenant erfolgreich gelaufen sind. In dem Auszug können Sie aber erkennen, dass eine Authentifizierung erfolgt und auch per Graph die Roles aus dem Tenant abgerufen werden und ein "On-PremisesPublishinProfiles" erfolgt.
Allerdings war der Status des Agenten im AzureAD-Portal unter https://portal.azure.com/#view/Microsoft_AAD_Connect_Provisioning/CloudSyncMenuBlade/~/Agents immer noch auf "Provisioning quarantined "
Die Details zu dem Fehler sind eindeutig:
Error code HybridIdentityServiceNoActiveAgents Error message We are unable to find an active agent for the domain you are trying to sync. Please check to see if the agent is running by going to the server where the agent is installed and check to see if Azure AD Connect Provisioning Agent under Services is running.
Mein Agent spricht noch nicht mit dem AzureAD Provisioning Service, obwohl die Einrichtung erfolgreich war.
Fehlersuche
Wir sehen aber jede Menge "/nnectorBootstrap"-Einträge mit 0 Bytes. Der Request ist überschaubar:
Wer aber auf das Feld "Content-Length" achtet, weiß um eine Payload des Posts, in der sehr ausführliche Daten über den Agenten an Microsoft gesendet werden. Neben der Agent-Version und ConnectorID werden auch Daten zum Windows ServerOS, .Net Version, und sogar CPU-Performancedaten etc. gesendet. Allerdings findet sich in der Payload auch keine Authentifizierung. Passend dazu finde ich im Trace-File auf C:\ProgramData\Microsoft\Azure AD Connect Provisioning Agent\Trace\AzureADConnectProvisioningAgent_*.log" auch die Fehlermeldungen:
AADConnectProvisioningAgent.exe Error: 0 : Service bootstrap request failed with exception: 'System.ServiceModel.Security.MessageSecurityException: The HTTP request was forbidden with client authentication scheme 'Anonymous'. ---> System.Net.WebException: The remote server returned an error: (403) Forbidden. at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result) --- End of inner exception stack trace --- at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result) at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass7_0`1.<CreateGenericTask>b__0(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.ApplicationProxy.Connector.Bootstrap.BootstrapManager.<SendBootstrapRequestAsync>d__39.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.ApplicationProxy.Connector.Bootstrap.BootstrapManager.<SendBootstrapRequestAsync>d__30.MoveNext()' due to security issues of the certificate. ThreadId=22 DateTime=2023-03-08T20:33:48.6069286Z
Azure AD AppProxy und Proxy
Der AzureAD CloudSync nutzt im Unterbau die gleiche Technik wie der Azure AD Application Proxy, wie sich schon aus den URLs und dem Programmverzeichnis ersehen lässt:
Zur Frage der Proxy-Nutzung mit einem AzureAD App Proxy gibt es deutlich mehr Hinweise auf die Konfiguration eines HTTP-Proxy.
Connectors have underlying OS components that make outbound
requests. These components automatically attempt to locate a proxy server on the
network using Web Proxy Auto-Discovery (WPAD). The OS components attempt to
locate a proxy server by carrying out a DNS lookup for wpad.domainsuffix. If the
lookup resolves in DNS, an HTTP request is then made to the IP address for
wpad.dat. This request becomes the proxy configuration script in your
environment. The connector uses this script to select an outbound proxy server.
However, connector traffic might still not go through, because of additional
configuration settings needed on the proxy.
https://learn.microsoft.com/en-us/azure/active-directory/app-proxy/application-proxy-configure-connectors-with-proxy-servers#bypass-outbound-proxies
Interessant auch die Aussage, dass eine Authentifizierung am Proxy nicht unterstützt wird. Das dürfte dann auch für AzureAD Cloud Sync gelten:
Application Proxy does not support authentication to other
proxies. The connector/updater network service accounts should be able to
connect to the proxy without being challenged for authentication.
Quelle
https://learn.microsoft.com/en-us/azure/active-directory/app-proxy/application-proxy-configure-connectors-with-proxy-servers#use-the-outbound-proxy-server
Die Proxy-Konfiguration scheint er entweder aus der globalen machine.config zu lesen oder pro Programm. Das verifiziere ich später noch einmal.
The Connector service evaluates the defaultProxy
configuration for usage in %SystemRoot%\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config,
if the defaultProxy is not configured (by default) in
ApplicationProxyConnectorService.exe.config. The same applies to the Connector
Updater service (ApplicationProxyConnectorUpdaterService.exe.config) too.
Quelle :https://learn.microsoft.com/en-us/azure/active-directory/app-proxy/application-proxy-configure-connectors-with-proxy-servers#step-1-configure-the-connector-and-related-services-to-go-through-the-outbound-proxy
Und von den Analysen zu Azure AD ation Proxy weiß ich, dass der ApplicationProxy sich mit einem Client-Zertifikat authentifiziert. Im Zertifikatspeicher des Computers habe ich dann auch ein passendes Zertifikat gefunden:
LeidLeider ist das Zertifikat so nicht exportierbar, so dass ich mit Fiddler diese nicht auch noch untermogeln konnte.
- Respond to Requests Requiring a Client Certificate
https://docs.telerik.com/ler/configure-fiddler/tasks/respondwithclientcert
Nachdem ich aber die SSL-Decryption in Fiddler abgeschaltet habe, ist Agent auch im AzureAD von "inactive" auf "online" gegangen.
Quelle:
https://portal.azure.com/#view/Microsoft_AAD_Connect_Provisioning/CloudSyncMenuBlade/~/Agents
Über den Ressource Monitor konnte ich auch gut sehen, dass der Prozess wirklich nur die Verbindung zum Proxy aufgebaut hat:
Allerdings sehen Sie im Process Monitor auch, dass Azure Ad Cloud Sync selbst kein Webserver mit einem "Listening Port" ist, auf sie sich der AzureAD AppProxy verbinden kann. Diese Kommunikation wird wohl nur intern abgewickelt.
Proxy Rückbau
Um zu wissen, welche Einstellung für die Nutzung des Proxy-Servers relevant ist, habe ich die vorher gemachten Einstellungen wieder rückgängig gemacht. Meine Hoffnung war, dass ein Eintrag in der Datei "AADConnectProvisioningAgent.exe.config" ausreichen würde.
netsh winhttp reset proxy [system.net.webrequest]::defaultwebproxy = $null
und dann noch die folgenden Zeilen aus der Datei "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\Machine-config" wieder entfernt und stattdessen in "C:\Program Files\Microsoft Azure AD Connect Provisioning Agent\AADConnectProvisioningAgent.exe.config" addiert.
Wenn es schon einen "<system.net>"-Bereich gibt, dann müssen Sie dies zusammenführen. Die Einträge sollten ans Ende gesetzt werden, damit sie nach der vorhandene generelle Definition sind.
<configuration> <system.net> <defaultProxy> <proxy proxyaddress="http://localhost:8888" bypassonlocal="True" usesystemdefault="True"/> </defaultProxy> </system.net> </configuration>
Auch diesmal konnte ich im Process Monitor sehen, dass der Dienst den Proxy genutzt hat.
Allein für die Funktion des AADConnectProvisioningAgent.exe über einen Proxy reicht es, den Proxy in der Datei "C:\Program Files\Microsoft Azure AD Connect Provisioning Agent\AADConnectProvisioningAgent.exe.config" zu addieren.
Das bedeutet nicht, dass Sie die anderen Proxy Einträge vielleicht zur Installation nicht doch brauchen. Der Assistent muss sich ja an der Cloud über den Browser authentifizieren. Eine grundlegende Kommunikation des Betriebssystems über den Proxy zum Internet muss schon gewährleistet sein.
Als Beifang kann ich zudem sagen, dass der Prozess neben der Kommunikation über den Proxy-Server nur noch Verbindungen per LDAP (389/TCP) und RPC 135/TCP zum Domaincontroller aufgebaut hat.
Zusammenfassung
Ich habe bei Microsoft nur Anleitungen für den klassischen AzureAD Connect Sync zur Einrichtung eines Proxy-Servers gefunden. Für den AzureAD Cloud Sync ist die Quellenlage dürftig bis nicht vorhanden. Nur wenige Spuren lassen auf eine Proxy-Unterstützung hoffen. Eine klare Aussage dazu gibt es nicht auch wenn es durch die Nutzung des AzureAD AppProxy als Unterbau zu erwarten ist.
Die Konfiguration des Proxy muss .NET-typisch in der Datei "AADConnectProvisioningAgent.exe.config" erfolgen und der Proxy darf eine Authentifizierung des Service gegen die Cloud mittels Client-Zertifikat (MTLS) nicht verhindern.
Weitere Links
- Azure AD Application Proxy
- CloudSync Einrichtung
- What is Azure AD Connect cloud sync?
https://learn.microsoft.com/en-us/azure/active-directory/cloud-sync/what-is-cloud-sync - AzureAD App Proxy: Work with existing On-Premises proxy
servers
https://learn.microsoft.com/en-s/azure/active-directory/app-proxy/application-proxy-configure-connectors-with-proxy-servers#step-1-configure-the-connector-and-related-services-to-go-through-the-outbound-proxy - Deploying Azure Active Directory Sync Behind a Proxy
https://social.technet.microsoft.com/wiki/contents/articles/31148.deploying-azure-active-directory-sync-behind-a-proxy.aspx
Durch Anpassen der Dateien
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\machine.config
C:\Program Files\Microsoft Azure AD Sync\Bin\miiserver.exe.config - HOWTO: Install Azure AD Connect behind an Internet Proxy
https://dirteam.com/sander/2021/01/19/howto-install-azure-ad-connect-behind-an-internet-proxy/ - Best practices for configuring Windows Defender Firewall
https://learn.microsoft.com/en-us/windows/security/threat-protection/windows-firewall/best-practices-configuring - Configure Azure AD Connect Health agents to use HTTP proxy
https://learn.microsoft.com/en-re/active-directory/hybrid/how-to-connect-health-agent-install#configure-azure-ad-connect-health-agents-to-use-http-proxy
Set-AzureADConnectHealthProxySettings -HttpsProxyAddress "ProxyServer:Port"
Restart-Service AzureADConnectHealth* Register-AzureADConnectHealthSyncAgent