O PowerShell Invoke-WebRequest falha com o canal seguro SSL / TLS

254

Estou tentando executar este comando powershell

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

e eu recebo esse erro. "Invoke-WebRequest: a solicitação foi abortada: não foi possível criar o canal seguro SSL / TLS." As solicitações https parecem funcionar (" https://google.com "), mas não esta em questão. Como posso fazer isso funcionar ou usar outro comando do PowerShell para ler o conteúdo da página?

pedra calcária
fonte
2
Consulte também Protocolo de segurança padrão no .NET 4.5 .
Franklin Yu

Respostas:

537

tente usar este

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://apod.nasa.gov/apod/
Chandan Rai
fonte
48
Por usos PowerShell padrão TLS 1.0 a segurança do site requer TLS 1.2
Chandan Rai
3
Awh, como você determinou a versão TLS do site?
precisa saber é
16
Tente SSLLabs para determinar informações: SSL Relatório apod.nasa.gov mostra TLS1.1 e TLS1.2
Christopher G. Lewis
1
Existe uma maneira de fazer isso que é um pouco mais permanente? Isso funciona, mas parece ser redefinido a cada janela do console.
Brandon
3
@Brandon Altere $env:Profileou, melhor ainda, edite a tabela de registro .
Franklin Yu
166

Em uma tentativa descarada de roubar alguns votos, SecurityProtocolé um Enumcom o [Flags]atributo Então você pode fazer isso:

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

Ou como esse é o PowerShell, você pode permitir que ele analise uma sequência para você:

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

Tecnicamente, você não precisa conhecer a versão do TLS.

Copiei e colei isso a partir de um script criado depois de ler esta resposta, porque não queria percorrer todos os protocolos disponíveis para encontrar um que funcionasse. Claro, você poderia fazer isso se quisesse.

Nota final - Eu tenho a declaração original (menos edições de SO) no meu perfil do PowerShell, portanto está em todas as sessões que eu inicio agora. Não é totalmente infalível, pois ainda existem sites que simplesmente falham, mas eu certamente vejo a mensagem em questão com muito menos frequência.

Sem Reembolsos Sem Devoluções
fonte
7
Se você precisar acessar um site que usa SSLv3, precisará [Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11, Tls, Ssl3". Lembre-se de que o SSLv3 e o TLSv1.0 foram descontinuados devido a POODLE, portanto, use por seu próprio risco.
Jordanbtucker # 1/18
Não existe uma maneira de usar a reflexão para permitir apenas todos os tipos Net.SecurityProtocolType? tem que haver
red888
Por que você deseja permitir o acesso a protocolos com falhas conhecidas por padrão? Independentemente disso, acredito que o lançamento iminente (no momento em que este artigo foi escrito) do PowerShell V7 resolverá esse problema de uma vez por todas e essa pergunta desaparecerá lentamente em seu esquecimento legítimo e merecido.
Nenhum reembolso Não há retornos
2

Se, como eu, nenhuma das opções acima funcionar, pode valer a pena tentar também especificamente uma versão TLS inferior. Eu tinha tentado o seguinte, mas não parecia resolver o meu problema:

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

No final, foi somente quando eu direcionei o TLS 1.0 (remova especificamente 1.1 e 1.2 no código) que funcionou:

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

O servidor local (em que isso estava sendo tentado) funciona bem com o TLS 1.2, embora o servidor remoto (anteriormente "confirmado" como bom para o TLS 1.2 por terceiros) pareça não estar.

Espero que isso ajude alguém.

Mark-DG1
fonte
1

Funciona para mim...

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
fonte
1
Esta resposta desabilita efetivamente a verificação de segurança. Embora possa eliminar o erro, abre a superfície de ataque do dispositivo de maneiras que muitos considerariam inaceitáveis. Eu nunca usaria isso em um dispositivo que possuo.
Nenhum reembolso Não há devoluções
1

Certifique-se de trocar o SHELL primeiro:

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'
pixelbits
fonte
0

Não descobri o motivo, mas reinstalar o .pfxcertificado (no usuário atual e na máquina local) funciona para mim.

Spencer
fonte
qual arquivo .pfx você reinstalou?
Sem reembolsos Sem devoluções
@NoRefundsNoReturns O arquivo de certificado que você deseja usar para enviar a solicitação.
Spencer #
Ainda não estou claro como isso se aplica à questão.
Sem reembolsos Sem devoluções
@NoRefundsNoReturns Quando Invoke-WebRequestlocalmente, ele funciona primeiro, mas falha mais tarde. Parece que, às vezes, ele não consegue mais ler o certificado (não conheço o mecanismo por trás dele. Talvez seja uma configuração controlada pela empresa). Mas a reinstalação do certificado funciona nesse caso.
Spencer
Se você está perdendo a chave privada de um certificado que certamente pode tornar o certificado inutilizável, mas duvido que esse seja o problema aqui. Se você estiver perdendo a chave, precisará salvar a chave privada e marcá-la como persistente. Faça uma nova pergunta se é isso que está acontecendo.
Sem reembolsos Sem devoluções