HTTP Proxy Authentication

Diese Seite beschreibt die Kommunikation zwischen Client und HTTP-Proxy-Server mit Authentifizierung. Sie hilft bei der Analyse, wenn z.B. "Anmeldefenster" in Outlook und anderen Programmen erscheinen oder eine Verbindung einfach nicht klappen will. Diese Seite ist auch entstanden, weil ich für Rimscout etwas Forschungsarbeit betreiben durfte.

Proxy Ja/Nein

Früher war ein HTTP-Proxy eine gesetzte Instanz bei Firmen, zumindest als Internet noch teuer, Bandbreite beschränkt und der Zugriff pro Benutzer gesteuert werden sollte. Mittlerweile sagen mir viele Administratoren, dass Sie gar keinen Proxy mehr betreiben, da sie ja "genug" Bandbreite haben und es eine Komponente mehr ist, die Kosten verursacht und ausfallen kann. Oder sie nutzen direkt einen "Cloud Proxy" wie Zscaler, Cisco Umbrella, denn ein Proxy kann etwas, was eine normale Firewall sehr schwer kann: Ein Proxy kann die Benutzer identifizieren, bei unverschlüsselten Verbindungen die URLs und Download überprüfen und bei verschlüsselten Verbindungen bis TLS 1.2 zumindest den angesprochenen Hostnamen der URL bewerten. Mit der richtigen Konfiguration (eigene RootCA) kann ein Proxy sogar TLS-Verbindungen inspizieren. Das ist technisch so einfach, dass es sogar Fiddler auf ihrem PC einfach per GUI aktivieren kann.

Als Firma ist ein Proxy daher eine aktive und wichtige Komponente beim Schutz der Clients gegen die Unbilden des Internet. Er kann filtern, protokollieren und manchmal ist auch ein Cache nicht zu verachten, z.B. wenn viele Clients an einem Standort sich Windows Updates oder Antivirus-Updates nachladen. Damit ein Cache allerdings auch mit verschlüsselten Verbindungen funktioniert, muss der Proxy quasi immer den SSL-Datenstrom "aufbrechen". Let's Encrypt hat viel dazu beigetragen, dass immer mehr Webseiten per HTTPS erreichbar sind und viele Seiten leiteten Zugriff per HTTP sogar direkt auf HTTPS um. Das ist gut, weil es das Mitschneiden und Verfälschen von HTTP-Übertragungen deutlich erschwert aber nicht unmöglich macht. Bis TLS 1.2 kann ich über Wireshark sehr wohl zumindest den angesprochenen Hostnamen erkennen und per DNS kann ich auch ihre Abfragen ohne Proxy erkennen.

Beim Einsatz eines Proxy-Servers haben wir nun zwei Verbindungen, die beide unabhängig von einander unverschlüsselt oder verschlüsselt arbeiten können. Der Client verbindet sich nämlich per TCP mit dem ProxyServer und der Proxy-Server macht eine eigene Verbindung zum Zielsystem oder vielleicht sogar zu einem "Upstream"-Proxy-Server auf. Proxy-Server können auch kaskadiert werden. Eine sichere Verbindung zwischen Client und Proxy-Server ist immer dann anzuraten, wenn eine unsichere Authentifizierung genutzt wird. Die Verbindung zwischen Proxy und Zielsystem bestimmt natürlich der Client anhand des angeforderten Protokolls. Zur besseren Verfügbarkeit können Sie natürlich mehrere Proxy-Server nebeneinander installieren und per DNS-RoundRobin oder Loadbalancer dem Client anbieten.

Wenn Sie einen Proxy einsetzen, dann kann er von "vertrauenswürdigen IP-Adressen" Verbindungen annehmen. Wenn Sie keine Filterung nach IP-Adressen machen, dann sollte ihr Proxy nie anonym aus dem Internet erreichbar sein. Eine Authentifizierung ist daher wünschenswert und um den Anwender nicht weiteren Anmeldedialogen zu nerven, sollte es eine "Integrierte Anmeldung" sein, z.B.: per NTLM, Kerberos, Negotiate. Dazu muss der Proxy-Server natürlich eine Anbindung an ihren Anmeldedienst haben. Jede zusätzliche Anmeldebox stört nicht nur den Anwender im Arbeitsfluss, sondern ist auch ein Risiko, da wir gerade nicht wollen, dass der Anwender in jede Dialogbox seine Zugangsdaten eingibt.

Daher ist es auch notwendig, dass ein Proxy für gewisse URLs keine Authentifizierung anfordert. Meist schließen wir z.B.: die Microsoft 365 URLs oder anderen von der Firma genutzten Cloud-Dienste aus der Authentifizierung aus, denn die Ziele sind ja keine anonymen Webseiten, sondern Partner mit entsprechenden Verträgen und eine hoffentlich sicheren Authentifizierung. Es gibt aber auch lokal genutzte Software, die keine oder die angebotene Authentifizierung des Proxy unterstützt und daher anhand der Ziel-Adressen oder notfalls auch anhand der Source-IP den Proxy ohne Authentifizierung nutzen darf. Es soll sogar Produkte geben, die gar nicht mit einem Proxy umgehen können oder es technisch unsinnig ist. Hier sind Sie dann wieder mit der Firewall gefordert, anhand der Source-IP und den Ziel-Adressen und Ports eine Kommunikation zu erlauben. Dazu gehört z.B. Teams Audio/Video aber auch Zoom, Webex, Google Meet. Audio/Video-Daten werden idealerweise immer per UDP übertragen, da TCP und HTTP over TCP und erst recht HTTP over Proxy mehr überflüssigen Overhead erzeugt und Paketverluste sehr negativ die Qualität beeinflussen.

Zuletzt muss ihr Proxy auch noch mit den "neuen Optionen" umgehen können. Outlook und ActiveSync arbeiten z.B. mit HTTP Chunked-Verbindungen und nutzen lange TCP-Verbindungen mittels HTTP Keep-alive. Nicht neu aber vielen Administratoren noch nicht bekannt sind Websockets, die eine HTTP-Verbindung zu einer bidirektionalen transparenten TCP-Verbindung umwidmen.

Am Ende müssen Sie natürlich auch dem Client irgendwie mitteilen, und und wann er welchen Proxy zu nutzen hat. Das geht per manueller Konfiguration, über Windows Gruppenrichtlinien oder WPAD (Statisch, DHCP oder DNS)

Ich habe ja nicht gesagt, dass der Betrieb eines Proxy-Servers einfach ist, aber es gibt gute Gründe für einen Proxy Server und daher sollte jeder Software-Entwickler aber auch Administrator und erst recht die Consultants damit umgehen können.

Der einfache anonyme Proxy

Zuerst habe ich mir einen SQUID-Proxy auf dem Windows Subsystem für Linux installiert und mein Subnetz freigeschaltet. (Anleitung siehe Squid Proxy). Ich habe dann auf meinem Client mit "Invoke-WebRequest" einfach einen Anfrage gestellt und per Wireshark mitgeschnitten. Der erste Fehler war direkt ein "Access Denied", da Squid in der Standardkonfiguration seine Dienste nur für "Localhost" bereitstellt. Daher habe ich schnell noch "Localnet" freigegeben und den Test wiederholt:

#Einfacher Test
Invoke-WebRequest http://www.msxfaq.de -Proxy http://172.31.61.86:3128

An diesem Bespiel sehen sie im Wireshark gefoltert auf die Kommunikation zwischen Client und Proxy:

Paket  1-3  TCP Handshake (Siehe auch TCP SYN ACK RES)
Paket  4    PROXY-Get. Sie sehen die komplett URL und nicht nur "/" im Request
Paket  5    Antwort mit 301 MOVE als Umleitung zu HTTPS
Paket  6-8  Neue TCP-Connection des Clients zum Proxy 
Paket  9    CONNECT-Request des Client
Paket 10    200 OK des Proxy, dass er die Verbindung durchschaltet
Paket 11ff  Start des TLS-Handshake von Client über den Proxy zum Ziel TLS Handshake mit NetMon
            Sie sehen im "Client Hello" noch den Start des SNI=www.msxfaq.de...

Die komplette Kommunikation zwischen Client und Proxy erfolgte hier über HTTP, d.h. unverschlüsselt und zudem ohne Authentifizierung. Der Proxy "sieht" bei HTTP-Anfragen nicht nur die URL sondern auch die übertragenen Nutzdaten. Diese Sichtbarkeit ist für den Proxy auch noch gegeben, wenn Sie die Verbindung zwischen Client und Proxy per TLS verschlüsseln, da der Proxy der Endpunkt der Verschlüsselung ist.

Erst wenn der Client eine HTTPS-Verbindung zum Ziel aufbauen, ist der Proxy erst einmal nur noch durchreichende Station. Er kann natürlich sich in die TLS-Verbindung einkoppeln, wenn er selbst sein Zertifikat ausliefert, dem der Client vertraut. Wenn die Endgeräte "verwaltet" sind, z.B. in Firmen aber auch in Internet-Cafes, dann ist das eine einfache Übung. Dagegen hilft dann Zertifikatspinning oder Extended Protection.

Aber selbst bei einer verschlüsselten Verbindung kann der Proxy bis TLS 1.2 die URL erkennen und selbst mit TLS 1.3 muss er ja irgendwie wissen, zu welchem Zielsystem der Client gehen möchte.

Der Authentication Proxy

Sobald der Proxy aber den Client authentifizieren möchte, verändert sich das Antwortverhalten. Der folgende Wireshark-Mitschnitt zeigt dies:

Paket 1-3  Das ist wieder der klassische TCP-Handshake (TCP SYN ACK RES)
Paket 4    Der Client möchte wieder anonym und per HTTP unverschlüsselt auf die MSXFAQ.
Paket 5    Der Proxy Server fordert mit einem "407 Proxy Authorization required" den Client zur Anmeldung auf

Da die Verbindung zwischen Client und Proxy unverschlüsselt ist, können wir uns in Wireshark die 407-Antwort genauer anschauen.

Der Eintrag "Proxy-Authenticate" ist hier der Schlüssel. Dieser Proxy erwartet von mir die Zugangsdaten quasi im "Klartext". Über eine unverschlüsselte Verbindung sollte dies nie genutzt werden und da kein Browser diese Daten einfach so sendet, wird der Anwender zur Eingabe aufgefordert. Interessant sind hier natürlich alternative Anmeldemethoden, die zum einen eine höhere Sicherheit bieten und eine automatische Anmeldung erlauben. In der Windows Welt würde ich immer auf Kerberos setzen und NTLM nur als zweite Option nutzen. Der Proxy muss diese Verfahren natürlich erst einmal anbieten. Dieser Mitschnitt zeit ein Proxy, der drei Anmeldeverfahren anbietet.

Idealerweise sollten Sie die bevorzugten Anmeldeverfahren zuerst aufführen, denn nicht alle Clients die Angebote entsprechend umsortieren. Wenn der Client ein "Negotiate" sieht und dann ein Kerberos-Ticket für den Proxy über den SPN erhält, dann sehen Sie dies im Wireshark:

Zuerst gibt es immer wieder den anonymen Zugriff. Es könnte ja sein, dass der Proxy z.B. ausgewählte URLs direkt erreichbar macht.

Das ist durchaus überlegenswert um z.B. Rückruflisten von Zertifizierungsstellen (CRLs) erreichbar zu machen. Aber auch Zugriff auf Cloud-Dienste können die Last des Proxy-Servers reduzieren, wenn keine Authentifizierung erforderlich ist.

Auch eine Anmeldung per NTLM erlaubt eine relativ sichere und automatische Anmeldung. Allerdings sind dabei immer zwei 407-Meldungen zu sehen. Nach dem anonymen Zugriff sendet der Client einen "kurzen" NTLM-Challenge auf die der Server mit einer Challenge-Antwort reagiert und erst dann der Client sich "richtig" anmelden kann.

Die NTLM-Anmeldung ist also nicht nur etwas langsamer, da pro TCP-Session zwei Pakete mehr erforderlich sind und tendenziell unsicherer eingeschätzt wird. Der Proxy-Server muss vor allem die Authentifizierung zu einem Domain Controller durchreichen, da nur der Anmeldedienste die Gültigkeit prüfen kann.

Kerberos ist nicht schwer und sollte immer genutzt werden, wo es möglich ist.

Proxynutzung durch Clients

Der Proxy kann ja von ihnen korrekt installiert und konfiguriert worden sein aber letztlich ist es eine Frage des Clients, ob und wie er den Proxy nutzt. Je nach Software, Betriebssystem und Einstellung gibt es mehrere Optionen:

  • Manuelle statische Konfiguration
  • Manuelle Konfiguration mit Skript
  • WPAD + Skript

Diese Einstellungen sagen aber nichts zur Authentifizierung. Auch wenn die meisten Windows Programme auf die Systemeinstellungen setzen, können Entwickler durchaus eigene Einstellungen nutzen, d.h. einen abweichenden Proxy nutzen oder einen konfigurierten Proxy umgehen.

Das gilt auch für die automatische Authentifizierung am Proxy Server. Edge und Chrome nutzen standardmäßig Kerberos oder NTLM. Firefox hingegen benötigt einen Eintrag, für welche Domains er Kerberos nutzt:

Hier habe ich meinem Firefox mitgeteilt, dass alle Systeme in der Domain "*.netatwork.de" für Negotiate zugelassen sind.

Bei der Powershell mit "Invoke-WebRequest" können Sie explizit einen Proxy angeben aber es wird ansonsten der Systemproxy genutzt. Allerdings erfolgt keine automatische Anmeldung am Proxy, wenn Sie nicht den Parameter "-ProxyUseDefaultCredentials" mit angeben.

Wenn Sie natürlich "-ProxyUseDefaultCredentials" angeben, dann können Sie nicht mehr mit expliziten Credentials arbeiten.


https://learn.microsoft.com/de-de/powershell/module/microsoft.powershell.utility/invoke-webrequest#notes

Nach meinen Erfahrungen liest die PowerShell den Proxy nur beim Start der jeweiligen PowerShell aus.

Wird der Proxy im laufenden Betrieb geändert, dann erkennt dies die PowerShell nicht. Probieren Sie es einfach aus, indem Sie eine PowerShell starten und den Default Proxy oder den Proxy für eine URL auslesen. Dazu gibt es zwei Methoden

# PowerShell 6.0 und höher basierend auf NET Core
[system.Net.Http.HttpClient]::DefaultProxy.GetProxy("http://www.msxfaq.de")

# PowerShell bis 5.0
[System.Net.WebRequest]::GetSystemWebproxy().GetProxy("http://www.msxfaq.de")

Danach ändern Sie in Windows einfach die ProxyEinstellungen und wiederholen den Aufruf. Beide Aufrufe haben in einer neuen PowerShell2/7-Shell dann die neuen Werte geliefert aber in den vorher gestarteten Shells weiter die alten Einstellungen genutzt.

Dies betrifft also alle Dienste und Programme, die lange laufen und bei denen sich auf dem Client der Proxy häufiger ändert.

Bislang habe ich noch keinen Weg gefunden, die Proxy-Erkennung einer bereits gestarteten PowerShell ohne Neustart der Shell zu aktualisieren.

Nach meinen Erkenntnissen wird der aktuelle Systemproxy beim Start der PowerShell ausgelesen aber später nicht mehr aktualisiert.

Weitere Links