PowerShell Proxyerkennung
Bei der Entwicklung von Rimscout sollte ich ermitteln, welche URLs über einen HTTP-Proxy routen und welche am Proxy vorbei gehen. Dabei fallen einige Besonderheiten auf.
Proxy Einstellungen
Wenn Sie ihr Windows System betrachten, dann gibt es mehrere Optionen, einen HTTP-Proxy im Betriebssystem zu konfigurieren.
Die folgenden Einstellungen gelten natürlich nur für Programme, die den Windows Proxy nutzen. Das machen immer mehr Programme aber es gibt durchaus auch eigenständige Konfigurationen.
- Auto-Konfiguration (WPAD)
Hierbei versucht der Client per DNS oder DHCP einen Proxy zu finden. Siehe auch WPAD - Proxy im Browser einstellen - Kein Proxy
Wenn Sie den Schieber auf "AUS" stellen und die anderen Einstellungen nicht aktivieren, dann nutzt der Client nie einen Proxy - Per Skript
Sie können statisch ein JavaScript vorgeben, welches abhängig von der URL dann einen passenden Proxy liefert. Das ist quasi eine statische WPAD-Konfiguration - Statisch
Natürlich können Sie manuell oder per Gruppenrichtlinie auch einen Proxy Server und Ausnahmen konfigurieren. - app.config bei .NET
Programme, die auf dem NET-Framework aufsetzen, können auch über Einträge in der machine.config oder app.config mit einem Proxy versehen werden.
Proxy Abfragen
Ob ihr System ein Proxy nutzt oder nicht, ist speziell bei WPAD nicht einfach in einer GUI zu erkennen. Aber Windows bietet natürlich entsprechende Schnittstellen zum Abrufen der Information an. Allerdings gibt habe ich mehrere Aufrufe gefunden, die teils unterschiedliche oder veraltete Ergebnisse liefern:
Methode | Beschreibung |
---|---|
CMD-Shell |
Per NETSH lässt sich schnell die Proxy-Konfiguration ermitteln REM Ausgabe aus einer CMD-Shell netsh winhttp show proxy |
DefaultWebProxy |
Laut Microsoft wird erst die app.config-Datei und dann der System Proxy gelesen Ausgabe des "DefaultWebProxy" [System.Net.WebRequest]::DefaultWebProxy
Die DefaultWebProxy -Eigenschaft
ruft den globalen Proxy ab oder legt diese fest.
Die DefaultWebProxy -Eigenschaft bestimmt den
Standardproxy, den alle WebRequest Instanzen
verwenden, wenn die Anforderung Proxys
unterstützt und kein Proxy explizit mit
der Proxy -Eigenschaft festgelegt wird. Proxys
werden derzeit von FtpWebRequest und HttpWebRequestunterstützt. |
SystemWebProxy |
Liest nur die Systemeinstellungen und ignoriert eine app.config Ausgabe des SystemWebProxy [System.Net.WebRequest]::GetSystemWebproxy()
GetSystemWebProxy -Methode liest die Internet Explorer-Proxyeinstellungen
(Internet Explorer, IE) des aktuellen Benutzers. Dieser Prozess umfasst die
IE-Optionen, um Proxyeinstellungen automatisch zu erkennen, ein automatisches
Konfigurationsskript, manuelle Proxyservereinstellungen und erweiterte manuelle
Proxyservereinstellungen zu verwenden. |
Webproxy (Deprectiated) |
Diese Funktion ist laut Microsoft abgekündigt und sollte nicht mehr genutzt werden. In der PowerShell 7 kommt ein Fehler: PS C:\> [System.Net.Webproxy]::GetDefaultProxy() MethodInvocationException: Exception calling "GetDefaultProxy" with "0" argument(s): "Operation is not supported on this platform." In der PowerShell 5.1 auf Basis von NET 2.0 funktioniert es noch Ausgabe WebProxy Proxy (bis Net 2.0. Depreciated [System.Net.Webproxy]::GetDefaultProxy() Address : BypassProxyOnLocal : False BypassList : {} Credentials : UseDefaultCredentials : False BypassArrayList : {} |
Beachten Sie, dass die Ausgaben nicht immer in "Echtzeit" aktualisiert werden. Es kann sein, dass neue Proxy-Einstellungen erst nach dem Neustart des Programms aktiviert werden
Wenn ich die beiden PowerShell-Ausgaben mit "ToString()" konvertiere, kommt beide male ein "System.Net.Http.HttpWindowsProxy"-Objekt heraus. Die Werte "scheinen" also auf die gleiche Quelle zuzugreifen.
- WebRequest.DefaultWebProxy Eigenschaft
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.defaultwebproxy?view=net-7.0 - WebProxy.GetDefaultProxy Method
https://learn.microsoft.com/en-us/dotnet/api/system.net.webproxy.getdefaultproxy?view=net-7.0&redirectedfrom=MSDN#System_Net_WebProxy_GetDefaultProxy
WebProxy.GetDefaultProxy has been deprecated. Use the proxy selected for you by default. - WebRequest.GetSystemWebProxy
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.getsystemwebproxy?view=net-7.0 - What's the difference between WebRequest.DefaultWebProxy and
WebRequest.GetSystemWebProxy()?
https://stackoverflow.com/questions/14887679/whats-the-difference-between-webrequest-defaultwebproxy-and-webrequest-getsyste - Tip: Replacement Methods for Obsolete WebProxy.GetDefaultProxy Method
https://www.codeguru.com/csharp/tip-replacement-methods-for-obsolete-webproxy-getdefaultproxy-method//a>
Proxy für Hostnamen abfragen
Wenn ich für einen einzelnen Host ermitteln möchte, ob die Zugriffe über einen Proxy laufen oder vielleicht daran vorbei geschleust werden, dann helfen folgende Befehle. Ich habe einen statischen Proxy eingetragen und dann abgefragt.
Achtung: Dies funktioniert nur mit PowerShell 7/Core
PS C:\> ([System.Net.WebRequest]::GetSystemWebproxy()).IsBypassed("https://www.rimscout.com/") False
Diese URL wird nicht per Bypass am Proxy vorbei geroutet. Wenn ich dann einen "GetProxy" mache, dann sehe ich auch den passenden Proxy.
PS C:\> ([System.Net.WebRequest]::GetSystemWebproxy()).getproxy("https://www.rimscout.com/") AbsolutePath : / AbsoluteUri : http://127.0.0.1:8080/ LocalPath : / Authority : 127.0.0.1:8080 HostNameType : IPv4 IsDefaultPort : False IsFile : False IsLoopback : True PathAndQuery : / Segments : {/} IsUnc : False Host : 127.0.0.1 Port : 8080 Query : Fragment : Scheme : http OriginalString : http://127.0.0.1:8080 DnsSafeHost : 127.0.0.1 IdnHost : 127.0.0.1 IsAbsoluteUri : True UserEscaped : False UserInfo :
Ich habe das hier mit "Fiddler" auf meinem PC als Proxy nachgestellt. So kann ich vorab prüfen, welchen Proxy für eine gewisse URL aufgerufen wird, wenn ich mich an den Windows Standard-Proxy halte.
Achtung: Bei PowerShell 5 kommt immer ein Proxy-Objekte zurück, auch wenn es keinen Proxy gibt. Der Proxy ist dann die URL
Diese Information sammle ich mit Rimscout gerne ein, um die Konfiguration eines Clients hinsichtlich der Microsoft vorgaben zu überprüfen.
Default Proxy ermitteln
Neben der Anfrage für gewisse URLs, die auch auf Ausnahmen in der Proxy-Konfiguration achten, möchte man vielleicht auch die allgemeine Proxy-Konfiguration ermitteln. Das geht schon immer in der CMD-Shell einfach mit:
netsh winhttp sow proxy
Da die Einstellungen in der Registrierung liegen, können Sie diese natürlich auch dort auslesen, z.B. per PowerShell mit:
Get-ItemProperty -Path "Registry::HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
Auch per .NET-Klasse können Sie den Proxy ermitteln
[System.Net.WebRequest]::DefaultWebProxy
In der Dokumentation schreibt Microsoft dazu:
Die DefaultWebProxy -Eigenschaft ruft den globalen Proxy ab oder legt diese
fest. Die DefaultWebProxy -Eigenschaft bestimmt den Standardproxy, den alle
WebRequest Instanzen verwenden, wenn die Anforderung Proxys unterstützt und kein
Proxy explizit mit der Proxy -Eigenschaft festgelegt wird. Proxys werden derzeit
von FtpWebRequest und HttpWebRequest unterstützt.
Die DefaultWebProxy -Eigenschaft liest Proxyeinstellungen aus der app.config-Datei.
Wenn keine Konfigurationsdatei vorhanden ist, werden die Internet
Explorer-Proxyeinstellungen (Internet Explorer, IE) des aktuellen Benutzers
verwendet.
Wenn die DefaultWebProxy Eigenschaft auf NULL festgelegt ist, verfügen alle
nachfolgenden Instanzen der Klasse, die WebRequest mit den Create Methoden oder
CreateDefault erstellt wurde, über keinen Proxy.
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.defaultwebproxy?view=net-7.0
Bedenken Sie, dass Änderungen am Proxy nur für danach erstellte Webrequest-Objekte gilt aber bereits instanzierte Objekte noch die bisherige Einstellungen haben.
- WebRequest.DefaultWebProxy Eigenschaft
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.defaultwebproxy - WebRequest.Proxy Eigenschaft
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.proxy
Proxy im Request überstimmen
Da jedes Webrequest-Objekt ein eigenes Proxy-Property hat, können sie als Entwickler natürlich den Proxy individuell umstellen. Das geht auch mit Invoke-Webrequest
$pass = ConvertTo-SecureString "ProxyPassword" -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential -ArgumentList "msxfaq\proxyuser", $pass Invoke-WebRequest ` -URI "https://www.msxfaq.de" ` -Proxy "http://proxy.msxfaq.de:3128" ` -ProxyCredential $cred
Dies ist für Testfälle und Analysen schon mal hilfreich. Ansonsten würde ich aber mich immer an den Systemproxy halten.
- How to use PowerShell Invoke-WebRequest behind corporate proxy
https://bycode.dev/2019/08/22/how-to-use-powershell-invoke-webrequest-behind-corporate-proxy/
Weitere Links
- HTTP Proxy Authentication
- Proxy 407 Handling
- WPAD - Proxy im Browser einstellen
- Windows Proxy Konfiguration
- WebRequest.DefaultWebProxy Eigenschaft
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.defaultwebproxy - WebRequest.Proxy Eigenschaft
https://learn.microsoft.com/de-de/dotnet/api/system.net.webrequest.proxy - How to use PowerShell Invoke-WebRequest behind corporate proxy
https://bycode.dev/2019/08/22/how-to-use-powershell-invoke-webrequest-behind-corporate-proxy/