Powershell und Zertifikate Check
Ich liebe PowerShell und insbesondere Invoke-Webrequest und Invoke-RESTMethod. Aber beide prüfen per Default die Gültigkeit der Zertifikate. Das ist im Prinzip richtig aber in Testumgebungen manchmal auch störend, wenn die Gegenseite eben kein gültiges Zertifikate hat. SO kann ich die Prüfung für die aktuelle Session abschalten
Der Fehler in Reinform
Ich habe dazu einen WebServer (in meinem Fall PRTG) mit einem selbstsignierten Zertifikat im LAN und wollte einfach eine Webseite abrufen. ein "Invoke-Webrequest" schlägt natürlich fehl mit dem Fehler:
Invoke-WebRequest : Die zugrunde liegende Verbindung wurde geschlossen: Für den geschützten SSL/TLS-Kanal konnte keine Vertrauensstellung hergestellt werden..
PS C:\> Invoke-WebRequest https://192.168.13.14 Invoke-WebRequest : Die zugrunde liegende Verbindung wurde geschlossen: Für den geschützten SSL/TLS-Kanal konnte keine Vertrauensstellung hergestellt werden..
In der PowerShell ist das Fenster rot und eine Exception wird gestartet:
Ich kann den Fehler per Try/Catch (Siehe auch PowerShell Error Handling) abfangen aber die Daten der Webseite bekomme ich so doch nicht. Ich muss also meinen Code anweisen, das gelieferte Zertifikat zu akzeptieren. Dazu gibt es je nach PowerShell-Version und genutzte API verschiedene Optionen
SSL-Check generell abschalten
Über folgenden Einzeiler können Sie im Skript bei allen PowerShell-Versionen die Prüfung für alle Zertifikate abschalten.
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Technisch wird die Funktion des ServicePointManager zur Verifizierung des Zertifikats so verändert, dass Sie immer ein "$true" liefert. Normalerweise steht da "$null" drin und die Funktion prüft, ob der gelieferte Name auch mit dem angefragten Namen übereinstimmt.
- ServicePointManager.ServerCertificateValidationCallback Property
https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.servercertificatevalidationcallback - RemoteCertificateValidationCallback Delegate
https://docs.microsoft.com/en-us/dotnet/api/system.net.security.remotecertificatevalidationcallback - LocalCertificateSelectionCallback Delegate
https://docs.microsoft.com/en-us/dotnet/api/system.net.security.localcertificateselectioncallback
SSL-Prüfung abschalten (Langform)
Nun funktionieren diese Aufrufe so, dass Sie im Fehlerfall eine "Callback"-Funktion aufrufen, die dem Modul die weitere Verarbeitung vorgibt. Per Default wird hier dann ein Fehler ausgegeben. Wenn ich das umgehen will, muss ich einfach eine eigene Funktion bereitstellen, die in dem Fall aufgerufen wird und ein beschwichtigendes OK liefert. Hier der entsprechende Code dazu:
Write-host "Disable Certificate checks" Add-Type @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } "@ [ServerCertificateValidationCallback]::Ignore();
Leider geht das nicht allein mit Powershell. Über den "Add-Type"-Befehl wird etwas C#-Code als Klasse "ServerCertificateValidationCallback" mit einer Methode "Ignore" definiert und aufgerufen. Dieses Beispiel gibt einfach "True" zurück und damit vertraue ich nun innerhalb dieses Skripts allen Zertifikaten:
Achtung: Damit hebeln Sie natürlich alle Schutzfunktionen aus und können nicht mehr sicher sein, dass Sie auf dem richtigen Server gelandet sind und niemand sich als "Man in the Middle" eingeschliffen hat. Dieses Vorgehen ist während der Entwicklung und Tests tolerierbar aber nicht mehr im Betrieb und erst recht nicht bei Verbindungen über ungesicherte Leitungen, insbesondere Internet oder zu Cloud-Anbietern.
- PowerShell, HTTPS/SSL, and Self-Signed
Certificates
https://grumpyneteng.com/powershell-httpsssl-and-self-signed-certificates/
Gleicher Abruf noch mal
Mit diesen Vorarbeiten klappt dann auch der Abruf trotz ungültigen Zertifikat.
Leider hat Microsoft den Commandlets "Invoke-WebRequest" und "Invoke-RestMethod" keinen Parameter spendiert, der die SSL-Prüfung steuert.
PowerShell SkipCertificateCheck
Mit PowerShell Core hat Microsoft die beiden Commandlets "Invoke-Webrequest" und "Invoke-RestMethod" mit dem Parameter SkipCertificateCheck versehen.
- Invoke-Webrequest
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?parameters - Invoke-RestMethod
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?parameters
Damit schalten Sie für diesen einen Aufruf alle Prüfungen ab, d.h. die Prüfung auf Name, SAN-Name, Gültigkeitsdauer, RootCA, Rückrufliste etc. Microsoft addiert aber hier zurecht den deutlichen Hinweis:
Using this parameter is not secure and is not recommended. This switch is only
intended to be used against known hosts using a self-signed certificate for
testing purposes. Use at your own risk.
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.2#parameters
Sie können das daher gerne für interne Tests in einem 100% vertrauenswürdigen Netzwerk nutzen. Aber schauen Sie schon dazu, dass die Zertifikate der Gegenstelle auf ihrem System dann doch "vertrauenswürdig" sind. Das muss ja kein "gekauftes" Zertifikat sein. Die gibt es eh nur für öffentliche DNS-Namen, die auch ihnen gehören aber nicht für IP-Adressen oder interne Namen. Es ist aber relativ einfach eine kleine PKI zu betreiben, mit der sie interne Webserver-Zertifikate ausstellen. Sie müssen dann nur diese RootCA auf ihren eigenen Systemen als "Trusted"addieren
Weitere Links
- PS HTTPClient
- PowerShell und SOAP
- PowerShell Error Handling
- Ignoring SSL trust in PowerShell
System.Net.WebClient
https://blogs.technet.microsoft.com/bshukla/2010/04/12/ignoring-ssl-trust-in-powershell-system-net-webclient/ - Windows PowerShell, Invalid Certificates,
and Automated Downloading
https://blogs.technet.microsoft.com/heyscriptingguy/2010/07/25/windows-powershell-invalid-certificates-and-automated-downloading/ -
ServicePointManager.ServerCertificateValidationCallback-Eigenschaft
https://msdn.microsoft.com/de-de/library/system.net.servicepointmanager.servercertificatevalidationcallback(v=vs.110).aspx -
HttpWebRequest.ServerCertificateValidationCallback-Eigenschaft
https://msdn.microsoft.com/de-de/library/system.net.httpwebrequest.servercertificatevalidationcallback(v=vs.110).aspx -
PowerShell, HTTPS/SSL, and Self-Signed
Certificates
https://grumpyneteng.com/powershell-httpsssl-and-self-signed-certificates/