Lỗi HTTPS Powershell v3 Invoke-WebRequest


126

Sử dụng Invoke-WebRequest và Invoke-RestMethod của Powershell v3 Tôi đã sử dụng thành công phương thức POST để đăng tệp json lên trang web https.

Lệnh tôi đang sử dụng là

 $cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("cert.crt")
 Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert -Body $json -ContentType application/json -Method POST

Tuy nhiên, khi tôi cố gắng sử dụng phương thức GET như:

 Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert -Method GET

Lỗi sau được trả về

 Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
 At line:8 char:11
 + $output = Invoke-RestMethod -Uri https://IPADDRESS/resource -Credential $cred
 +           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest)      [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Tôi đã cố gắng sử dụng mã sau để bỏ qua chứng chỉ SSL, nhưng tôi không chắc liệu nó có thực sự hoạt động hay không.

 [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Ai đó có thể cung cấp một số hướng dẫn về những gì có thể xảy ra ở đây và cách khắc phục nó không?

Cảm ơn


Vậy bạn đang sử dụng cái nào? Invoke-RestMethodhoặc Invoke-WebRequest?
svick

Gọi-WebRequest. Tôi sử dụng nó vì nó trả về các tiêu đề request / resposne không giống như Invoke-RestMethod. Tuy nhiên, tôi đã thử Invoke-RestMethod có các thông số giống hệt nhau.
floyd,

Đối với những gì nó đáng giá, điều ServerValidationCallback gần như chắc chắn là một con cá trích đỏ, vì lỗi bạn sẽ gặp phải khi gặp sự cố xác thực SSL nên NÓI rằng: Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. Bạn có thể thử khám phá $ Error [0] .Exception.InnerException để biết thêm thông tin .. .
Jaykul

Câu trả lời:


179

Công việc xung quanh này phù hợp với tôi: http://connect.microsoft.com/PowerShell/feedback/details/419466/new-webserviceproxy-needs-force-parameter-to-ignore-ssl-errors

Về cơ bản, trong tập lệnh PowerShell của bạn:

add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$result = Invoke-WebRequest -Uri "https://IpAddress/resource"

9
Lưu ý, câu trả lời này là đúng; tuy nhiên, điểm được đưa ra trên một câu trả lời khác ( stackoverflow.com/a/25163476/68432 ) cũng hợp lệ. Giải pháp này sẽ không hoạt động nếu bạn đã thực hiện trước "[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = {$ true}".
Paul Suart

Bạn cần phải thêm việc kiểm tra Loại điều kiện theo Arthur Strutzenberg câu trả lời dưới đây hoặc bạn sẽ nhận được một lỗi nói rằng loại đã tồn tại
Ralph Willgoss

Có rủi ro bảo mật khi sử dụng cái này trong sản xuất không?
Amjad

13
5 năm sau, đó vẫn là giải pháp cho PowerShell 5.1 (.NET Framework đầy đủ). Đối với PowerShell Core hiện có -SkipCertificateCheck.
evilSnobu

MS đã gỡ xuống Connect, liên kết đó không hợp lệ. Có một liên kết khác?
Mark Heath

71

Câu trả lời của Lee rất tuyệt, nhưng tôi cũng gặp vấn đề với các giao thức mà máy chủ web hỗ trợ.
Sau khi thêm các dòng sau, tôi có thể nhận được yêu cầu https. Như đã chỉ ra trong câu trả lời này https://stackoverflow.com/a/36266735

$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols

Giải pháp đầy đủ của tôi với mã của Lee.

add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

bạn đã tìm ra giải pháp tốt hơn chưa, nếu bạn có 40 tập lệnh thì bạn phải thêm nó vào mỗi tập lệnh ?. Có vẻ không có ý nghĩa gì. Btw, cảm ơn vì câu trả lời
Ender

1
Câu trả lời của Lee không phù hợp với tôi. Tôi đã phải thêm các bit mà bạn đã tham chiếu và NÓ ĐÃ HOẠT ĐỘNG!
Pat K

Cảm ơn bạn rất nhiều, việc chỉ định các giao thức đã giúp giải quyết vấn đề
Alex

1
Cảm ơn bạn cảm ơn bạn cảm ơn bạn đã chỉ cho tôi SecurityProtocoltài sản tĩnh toàn cầu. Chúa ơi, tôi vừa mất DAYS khi kiểm tra chứng chỉ, độ tin cậy, mạng, tuyến đường, quyền và khối lượng của những thứ khác khi cố gắng giải quyết endpoint does not respondlỗi mơ hồ khi truy cập một máy chủ cụ thể qua https (tất cả những thứ khác đều hoạt động), chỉ vì cái powerhell 5.1 chết tiệt đó mặc định thành SSL3, TLS và nó CHỈ KHỐI GODDAMN TLS11 và TLS12 BỞI thần DEFAULT tôi ghét cái thứ tào lao này đến mức nào, lẽ ra tôi nên viết script đó bằng C # / Ruby / C ++, hoặc bất cứ thứ gì khác không phải là powershell
quetzalcoatl

1
@StanTastic: Tôi nghĩ rằng không thể thay đổi vĩnh viễn các giá trị mặc định. Tôi nghĩ rằng nó được mã hóa cứng trong mã nguồn ServicePointManager. Tôi chưa bao giờ kiểm tra mặc dù, vì vậy có thể có một số cách.
quetzalcoatl

10

Bạn đã thử sử dụng System.Net.WebClient?

$url = 'https://IPADDRESS/resource'
$wc = New-Object System.Net.WebClient
$wc.Credentials = New-Object System.Net.NetworkCredential("username","password")
$wc.DownloadString($url)

Sunny, tôi nhận được thông báo sau khi sử dụng mã đó: Ngoại lệ gọi "DownloadString" với (các) đối số "1": "Máy chủ từ xa trả lại lỗi: (406) Không thể chấp nhận." Tại dòng: 4 char: 1 + $ wc.DownloadString ($ url) + ~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [ ], MethodInvocationException + FullyQualifiedErrorId: WebException
Floyd

Dựa trên những tài liệu API của im dịch vụ REST sử dụng 406 chỉ "mà chấp nhận tiêu đề có trong yêu cầu không cho phép một XML hoặc JSON phản ứng"
Floyd

Những loại phản hồi nào được phép nếu phản hồi XML / JSON không được phép?
Sunny Chakraborty,

Đây có phải là dịch vụ web tùy chỉnh mà bạn đang sử dụng không? Có bất kỳ tài liệu công khai nào cho REST API không?
Sunny Chakraborty,

Đó là một hệ thống bán vé được gọi là EM7 Tôi không tin rằng họ có tài liệu công khai. Dịch vụ không chấp nhận phản hồi JSON / XML (hoạt động tốt nếu tôi sử dụng cURL) Tôi tin rằng lỗi chỉ ra rằng System.Net.WebClient không?
floyd,

10

Một triển khai thay thế thuần túy (không có Add-Type của nguồn):

#requires -Version 5
#requires -PSEdition Desktop

class TrustAllCertsPolicy : System.Net.ICertificatePolicy {
    [bool] CheckValidationResult([System.Net.ServicePoint] $a,
                                 [System.Security.Cryptography.X509Certificates.X509Certificate] $b,
                                 [System.Net.WebRequest] $c,
                                 [int] $d) {
        return $true
    }
}
[System.Net.ServicePointManager]::CertificatePolicy = [TrustAllCertsPolicy]::new()

7

Cách sau phù hợp với tôi (và sử dụng phương tiện mới nhất không được dùng để tương tác với SSL Certs / chức năng gọi lại) và không cố gắng tải cùng một mã nhiều lần trong cùng một phiên powershell:

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();

Điều này được điều chỉnh từ bài viết sau https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/


5

Tôi thấy rằng khi tôi sử dụng chức năng gọi lại này để bỏ qua chứng chỉ SSL [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Tôi luôn nhận được thông báo lỗi Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.giống như kết quả bạn đang gặp phải.

Tôi tìm thấy bài đăng trên diễn đàn này dẫn tôi đến chức năng bên dưới. Tôi chạy điều này một lần trong phạm vi mã khác của tôi và nó phù hợp với tôi.

function Ignore-SSLCertificates
{
    $Provider = New-Object Microsoft.CSharp.CSharpCodeProvider
    $Compiler = $Provider.CreateCompiler()
    $Params = New-Object System.CodeDom.Compiler.CompilerParameters
    $Params.GenerateExecutable = $false
    $Params.GenerateInMemory = $true
    $Params.IncludeDebugInformation = $false
    $Params.ReferencedAssemblies.Add("System.DLL") > $null
    $TASource=@'
        namespace Local.ToolkitExtensions.Net.CertificatePolicy
        {
            public class TrustAll : System.Net.ICertificatePolicy
            {
                public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem)
                {
                    return true;
                }
            }
        }
'@ 
    $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
    $TAAssembly=$TAResults.CompiledAssembly
    ## We create an instance of TrustAll and attach it to the ServicePointManager
    $TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
    [System.Net.ServicePointManager]::CertificatePolicy = $TrustAll
}


1

Tôi đã thử tìm kiếm tài liệu về API REST EM7 OpenSource. Không có may mắn cho đến nay.

http://blog.sciencelogic.com/sciencelogic-em7-the-next-generation/05/2011

Có rất nhiều cuộc thảo luận về API REST của OpenSource, nhưng không có liên kết nào đến API thực tế hoặc bất kỳ tài liệu nào. Có lẽ tôi đã thiếu kiên nhẫn.

Dưới đây là một số điều bạn có thể thử

$a = Invoke-RestMethod -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert 
$a.Results | ConvertFrom-Json

Hãy thử điều này để xem liệu bạn có thể lọc ra các cột mà bạn đang nhận được từ API hay không

$a.Results | ft

hoặc, bạn cũng có thể thử sử dụng cái này

$b = Invoke-WebRequest -Uri https://IPADDRESS/resource -Credential $cred -certificate $cert 
$b.Content | ConvertFrom-Json

Tiêu đề kiểu xoăn

$b.Headers

Tôi đã thử nghiệm IRM / IWR với api twitter JSON.

$a = Invoke-RestMethod http://search.twitter.com/search.json?q=PowerShell 

Hi vọng điêu nay co ich.


Cảm ơn vì sự hỗ trợ của bạn. Tuy nhiên, lệnh đầu tiên $ a = Invoke-RestMethod (...) là lệnh hiện không hoạt động đối với tôi. Hoạt động tốt cho một trang web HTTP nhưng khi bạn giới thiệu HTTPS mà EM7 thực hiện thì nó trả về lỗi được mô tả. Đó là cho Invoke-RestMethod và Invoke-WebRequest. Tôi đang trong quá trình chỉ sử dụng lệnh ghép ngắn Invoke-Command và chạy curl.
floyd

1

Gọi-WebRequest "Tên miền" -SkipCertificateCheck

Bạn có thể sử dụng -SkipCertificateCheck Parameter để đạt được điều này dưới dạng lệnh một lớp (THÔNG SỐ NÀY CHỈ ĐƯỢC HỖ TRỢ TRÊN CORE PSEDITION)


0
  1. Chạy lệnh này

Chứng chỉ tự động mới -certstorelocation cert: \ localmachine \ my -dnsname {your-site-hostname}

trong powershell bằng cách sử dụng quyền quản trị , Điều này sẽ tạo tất cả các chứng chỉ trong thư mục Cá nhân

  1. Để loại bỏ lỗi Bảo mật, hãy chọn các chứng chỉ này, nhấp chuột phải → Sao chép. Và dán vào Tổ chức / Chứng chỉ Chứng nhận gốc đáng tin cậy.
  2. Bước cuối cùng là chọn các ràng buộc chính xác trong IIS. Truy cập trang web IIS, chọn Bindings, Chọn hộp kiểm SNI và đặt các chứng chỉ riêng cho từng trang web.

Đảm bảo tên máy chủ trang web và tên dns-name chứng chỉ phải khớp chính xác


0

Các cài đặt đăng ký này ảnh hưởng đến .NET Framework 4+ và do đó là PowerShell. Đặt chúng và khởi động lại bất kỳ phiên PowerShell nào để sử dụng TLS mới nhất, không cần khởi động lại.

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

Xem https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls#schusestrongcrypto


Đối với bất kỳ ai khác nhìn thấy câu trả lời này, kinh nghiệm của chúng tôi là bản vá đăng ký này, trên thực tế, yêu cầu khởi động lại để đảm bảo chức năng phù hợp. Khi cố gắng đảm bảo kết nối TLS 1.2 giữa hộp Windows chạy ứng dụng .NET, SSL 3 được hiển thị qua dấu vết mạng để được sử dụng với giá trị đăng ký này tại chỗ, nhưng trước khi khởi động lại; TLS 1.2 chỉ được gọi sau khi khởi động lại.
David W

-1

Nếu bạn chạy điều này với tư cách quản trị viên, lỗi đó sẽ biến mất

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.