Powershell Invoke-WebRequest falla con el canal seguro SSL / TLS

254

Estoy tratando de ejecutar este comando de PowerShell

Invoke-WebRequest -Uri https://apod.nasa.gov/apod/

y me sale este error "Invoke-WebRequest: la solicitud fue cancelada: no se pudo crear un canal seguro SSL / TLS". Las solicitudes https parecen funcionar (" https://google.com ") pero no esta en cuestión. ¿Cómo puedo hacer que esto funcione o usar otro comando de PowerShell para leer el contenido de la página?

Hewstone
fuente
2
Consulte también Protocolo de seguridad predeterminado en .NET 4.5 .
Franklin Yu

Respuestas:

537

intenta usar este

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
Chandan Rai
fuente
48
Por defecto, PowerShell utiliza TLS 1.0, la seguridad del sitio requiere TLS 1.2
Chandan Rai
3
Awh, ¿cómo determinó la versión TLS del sitio?
Hewstone el
16
Pruebe SSLLabs para determinar la información: Informe SSL: apod.nasa.gov muestra TLS1.1 y TLS1.2
Christopher G. Lewis
1
¿Hay alguna manera de hacer esto que sea un poco más permanente? Esto funciona pero parece restablecerse con cada ventana de consola.
Brandon
3
@Brandon Cámbielo $env:Profile, o mejor aún, edite la tabla de registro .
Franklin Yu
166

En un intento descarado de robar algunos votos, SecurityProtocoles un Enumcon el [Flags]atributo. Entonces puedes hacer esto:

[Net.ServicePointManager]::SecurityProtocol = 
  [Net.SecurityProtocolType]::Tls12 -bor `
  [Net.SecurityProtocolType]::Tls11 -bor `
  [Net.SecurityProtocolType]::Tls

O como se trata de PowerShell, puede dejar que analice una cadena por usted:

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"

Entonces técnicamente no necesita saber la versión TLS.

Copié y pegué esto desde un script que creé después de leer esta respuesta porque no quería pasar por todos los protocolos disponibles para encontrar uno que funcionara. Por supuesto, podrías hacer eso si quisieras.

Nota final: tengo la declaración original (menos las ediciones SO) en mi perfil de PowerShell, por lo que está en cada sesión que comienzo ahora. No es totalmente infalible ya que todavía hay algunos sitios que simplemente fallan, pero seguramente veo el mensaje en cuestión con mucha menos frecuencia.

Sin reembolsos Sin devoluciones
fuente
77
Si necesita acceder a un sitio que usa SSLv3, entonces querrá [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3". Recuerde que SSLv3 y TLSv1.0 han quedado en desuso debido a POODLE, así que úselo bajo su propio riesgo.
jordanbtucker
¿No hay una manera de usar la reflexión para permitir todos los tipos Net.SecurityProtocolType? tiene que haber
red888
¿Por qué quiere permitir el acceso a protocolos defectuosos por defecto? De todos modos, creo que el lanzamiento inminente (a partir de este escrito) de PowerShell V7 abordará este problema de una vez por todas y esta pregunta se desvanecerá lentamente en su olvido legítimo y bien ganado.
Sin reembolsos Sin devoluciones
2

Si, como yo, ninguno de los anteriores funciona, también podría valer la pena probar específicamente una versión más baja de TLS. Había intentado lo siguiente, pero no parecía resolver mi problema:

[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls

Al final, fue solo cuando apunté a TLS 1.0 (específicamente eliminar 1.1 y 1.2 en el código) que funcionó:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls

El servidor local (en el que se estaba intentando esto) está bien con TLS 1.2, aunque el servidor remoto (que previamente fue "confirmado" como TLS 1.2 por un tercero) parece no estarlo.

Espero que esto ayude a alguien.

Mark-DG1
fuente
1

Esto funciona para mi...

if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
    {
    $certCallback = @"
        using System;
        using System.Net;
        using System.Net.Security;
        using System.Security.Cryptography.X509Certificates;
        public class ServerCertificateValidationCallback
        {
            public static void Ignore()
            {
                if(ServicePointManager.ServerCertificateValidationCallback ==null)
                {
                    ServicePointManager.ServerCertificateValidationCallback += 
                        delegate
                        (
                            Object obj, 
                            X509Certificate certificate, 
                            X509Chain chain, 
                            SslPolicyErrors errors
                        )
                        {
                            return true;
                        };
                }
            }
        }
    "@
        Add-Type $certCallback
     }
    [ServerCertificateValidationCallback]::Ignore()

Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
Gowtham Balusamy
fuente
1
Esta respuesta deshabilita efectivamente la comprobación de seguridad. Si bien puede eliminar el error, abre la superficie de ataque de su dispositivo de una manera que muchos considerarían inaceptable. Nunca usaría esto en un dispositivo que poseo.
Sin reembolsos Sin devoluciones
1

Asegúrese de cambiar el SHELL primero:

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 
RUN Invoke-WebRequest -UseBasicParsing -Uri  'https://github.com/git-for-windows/git/releases/download/v2.25.1.windows.1/Git-2.25.1-64-bit.exe' -OutFile 'outfile.exe'
bits de píxel
fuente
0

No he descubierto la razón, pero la reinstalación del .pfxcertificado (tanto en el usuario actual como en la máquina local) funciona para mí.

Spencer
fuente
¿Qué .pfx reinstalaste?
Sin reembolsos Sin devoluciones
@NoRefundsNoReturns El archivo de certificado que desea utilizar para enviar la solicitud.
Spencer
Todavía no estoy claro cómo esto es aplicable a la pregunta.
Sin reembolsos Sin devoluciones
@NoRefundsNoReturns Cuando Invoke-WebRequestlocalmente, funciona al principio pero fallará más tarde. Parece que a veces ya no puede leer el certificado (no conozco el mecanismo detrás de él. Quizás sea un entorno controlado por la compañía). Pero reinstalar el certificado funciona en este caso.
Spencer
Si está perdiendo la clave privada para un certificado que ciertamente puede hacer que el certificado sea inutilizable, pero dudo que ese sea el problema aquí. Si está perdiendo la clave, debe asegurarse de guardar la clave privada y marcarla como persistente. Haga una nueva pregunta si esto es lo que está sucediendo.
Sin reembolsos Sin devoluciones