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.

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.

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.

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