ข้อผิดพลาด Powershell v3 Invoke-WebRequest HTTPS


126

การใช้ Invoke-WebRequest และ Invoke-RestMethod ของ Powershell v3 ฉันใช้วิธี POST เพื่อโพสต์ไฟล์ json ไปยังเว็บไซต์ https

คำสั่งที่ฉันใช้คือ

 $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

อย่างไรก็ตามเมื่อฉันพยายามใช้เมธอด GET เช่น:

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

ข้อผิดพลาดต่อไปนี้จะถูกส่งกลับ

 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

ฉันพยายามใช้รหัสต่อไปนี้เพื่อละเว้นใบรับรอง SSL แต่ฉันไม่แน่ใจว่ามันทำอะไรได้จริงหรือเปล่า

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

ใครช่วยให้คำแนะนำเกี่ยวกับสิ่งที่อาจเกิดขึ้นที่นี่และจะแก้ไขได้อย่างไร

ขอบคุณ


คุณใช้อันไหน Invoke-RestMethodหรือInvoke-WebRequest?
svick

วิงวอน-WebRequest ฉันใช้มันเนื่องจากส่งคืนส่วนหัว request / resposne ซึ่งแตกต่างจาก Invoke-RestMethod อย่างไรก็ตามฉันได้ลอง Invoke-RestMethod ซึ่งใช้พารามิเตอร์ที่เหมือนกันเช่นกัน
floyd

สำหรับสิ่งที่คุ้มค่าสิ่งที่ ServerValidationCallback เกือบจะเป็นปลาเฮอริ่งสีแดงเนื่องจากข้อผิดพลาดที่คุณควรได้รับเมื่อคุณมีปัญหาการตรวจสอบ SSL shoudl กล่าวว่า: Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. คุณสามารถลองสำรวจ $ Error [0] .Exception.InnerException สำหรับข้อมูลเพิ่มเติม .. .
Jaykul

คำตอบ:


179

วิธีแก้ปัญหานี้ใช้ได้ผลสำหรับฉัน: http://connect.microsoft.com/PowerShell/feedback/details/419466/new-webserviceproxy-needs-force-parameter-to-ignore-ssl-errors

โดยทั่วไปในสคริปต์ PowerShell ของคุณ:

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
หมายเหตุคำตอบนี้ถูกต้อง อย่างไรก็ตามประเด็นในคำตอบอื่น ( stackoverflow.com/a/25163476/68432 ) ก็ใช้ได้เช่นกัน วิธีนี้จะใช้ไม่ได้ถ้าคุณทำ "[System.Net.ServicePointManager] :: ServerCertificateValidationCallback = {$ true}" ไว้ก่อน
Paul Suart

คุณต้องเพิ่มการตรวจสอบเงื่อนไขประเภทตามคำตอบของ Arthur Strutzenberg ด้านล่างมิฉะนั้นคุณจะได้รับข้อผิดพลาดว่ามีประเภทนี้อยู่แล้ว
Ralph Willgoss

การใช้สิ่งนี้ในการผลิตมีความเสี่ยงด้านความปลอดภัยหรือไม่?
Amjad

13
5 ปีต่อมานั่นยังคงเป็นโซลูชันสำหรับ PowerShell 5.1 (.NET Framework เต็มรูปแบบ) สำหรับ PowerShell Core มีอยู่ใน-SkipCertificateCheckขณะนี้
evilSnobu

MS ได้ลบ Connect แล้วลิงก์นั้นไม่ถูกต้อง มีลิงค์อื่นอีกไหม
Mark Heath

71

คำตอบของลีดีมาก แต่ฉันก็มีปัญหาเกี่ยวกับโปรโตคอลที่เว็บเซิร์ฟเวอร์รองรับ
หลังจากเพิ่มบรรทัดต่อไปนี้ฉันสามารถขอ https ได้ผ่าน ตามที่ระบุไว้ในคำตอบนี้https://stackoverflow.com/a/36266735

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

โซลูชันเต็มรูปแบบของฉันด้วยรหัสของลี

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

คุณพบทางออกที่ดีกว่าแล้วหรือยังเพราะถ้าคุณมี 40 สคริปต์คุณต้องเพิ่มเข้าไปในแต่ละสคริปต์หรือไม่? ดูเหมือนจะไม่สมเหตุสมผลเลย Btw ขอขอบคุณสำหรับคำตอบ
พลิก

1
คำตอบของลีไม่ได้ผลสำหรับฉัน ฉันต้องเพิ่มบิตที่คุณอ้างถึงและมันใช้งานได้!
Pat K

ขอบคุณมากการระบุโปรโตคอลช่วยในการแก้ปัญหา
Alex

1
ขอบคุณขอบคุณขอบคุณที่แสดงให้ฉันเห็นSecurityProtocolคุณสมบัติคงที่ทั่วโลก พระคริสต์ฉันเพิ่งสูญเสียวันในการตรวจสอบใบรับรองความน่าเชื่อถือเครือข่ายเส้นทางการอนุญาตและสิ่งอื่น ๆ ที่พยายามแก้ไขendpoint does not respondข้อผิดพลาดที่คลุมเครือเมื่อเข้าถึงเซิร์ฟเวอร์เฉพาะผ่าน https (อื่น ๆ ทั้งหมดทำงานได้) เพียงเพราะ powershell 5.1 ที่น่ารังเกียจ ค่าเริ่มต้นเป็น SSL3, TLS และเป็นเพียงบล็อก GODDAMN TLS11 และ TLS12 โดยค่าเริ่มต้นพระเจ้าฉันเกลียดอึนี้มากแค่ไหนฉันควรเขียนสคริปต์นั้นใน C # / Ruby / C ++ หรืออย่างอื่นที่ไม่ใช่ powershell
quetzalcoatl

1
@StanTastic: ฉันคิดว่ามันเป็นไปไม่ได้ที่จะเปลี่ยนค่าเริ่มต้นอย่างถาวร ฉันคิดว่ามันเข้ารหัสในซอร์สโค้ด ServicePointManager ฉันไม่เคยตรวจสอบเลยอาจจะมีบางวิธี
quetzalcoatl

10

คุณลองใช้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)

ซันนี่ฉันได้รับสิ่งต่อไปนี้เมื่อใช้รหัสนั้น: ข้อยกเว้นที่เรียก "DownloadString" โดยมีอาร์กิวเมนต์ "1": "เซิร์ฟเวอร์ระยะไกลส่งคืนข้อผิดพลาด: (406) ไม่สามารถยอมรับได้" ที่บรรทัด: 4 ถ่าน: 1 + $ wcDownloadString ($ url) + ~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo: NotSpecified: (:) [ ], MethodInvocationException + FullyQualifiedErrorId: WebException
floyd

จากเอกสาร API ของบริการ REST im ที่ใช้ 406 ระบุว่า "ส่วนหัวการยอมรับที่รวมอยู่ในคำขอไม่อนุญาตให้มีการตอบกลับ XML หรือ JSON"
floyd

ประเภทการตอบกลับใดที่ได้รับอนุญาตหากไม่อนุญาตการตอบกลับ XML / JSON
Sunny Chakraborty

นี่คือบริการเว็บแบบกำหนดเองที่คุณใช้อยู่ใช่ไหม มีเอกสารที่เปิดเผยต่อสาธารณะสำหรับ REST API หรือไม่
Sunny Chakraborty

เป็นระบบการออกตั๋วที่เรียกว่า EM7 ฉันไม่เชื่อว่ามีเอกสารสาธารณะ บริการยอมรับการตอบสนอง JSON / XML (ใช้งานได้ดีถ้าฉันใช้ cURL) ฉันเชื่อว่าข้อผิดพลาดนี้บ่งชี้ว่า System.Net.WebClient ไม่ใช่?
floyd

10

การใช้งานทางเลือกที่บริสุทธิ์ (โดยไม่ต้อง Add-Typeของ แหล่งที่มา):

#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

สิ่งต่อไปนี้ใช้ได้ผลสำหรับฉัน (และใช้วิธีล่าสุดที่ไม่เลิกใช้เพื่อโต้ตอบกับ SSL Certs / ฟังก์ชันการเรียกกลับ) และไม่พยายามโหลดรหัสเดียวกันหลาย ๆ ครั้งภายในเซสชัน 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();

สิ่งนี้ดัดแปลงมาจากบทความต่อไปนี้ https://d-fens.ch/2013/12/20/nobrainer-ssl-connection-error-when-using-powershell/


5

ฉันพบว่าเมื่อฉันใช้ฟังก์ชันเรียกกลับนี้เพื่อละเว้นใบรับรอง SSL [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

ฉันมักจะได้รับข้อความแสดงข้อผิดพลาดInvoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.ซึ่งดูเหมือนผลลัพธ์ที่คุณมี

ฉันพบโพสต์ในฟอรัมนี้ซึ่งนำฉันไปสู่ฟังก์ชันด้านล่าง ฉันเรียกใช้สิ่งนี้ครั้งเดียวภายในขอบเขตของรหัสอื่นของฉันและมันก็ใช้ได้สำหรับฉัน

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
}


2

เรียกใช้ WebRequest "DomainName" -SkipCertificateCheck

คุณสามารถใช้-SkipCertificateCheckพารามิเตอร์เพื่อให้บรรลุสิ่งนี้เป็นคำสั่งหนึ่งซับ (พารามิเตอร์นี้ได้รับการสนับสนุนบน PSEDITION หลักเท่านั้น)


1

ฉันพยายามค้นหาเอกสารใน EM7 OpenSource REST API ยังไม่มีโชค

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

มีการพูดคุยมากมายเกี่ยวกับ OpenSource REST API แต่ไม่มีลิงก์ไปยัง API จริงหรือเอกสารใด ๆ บางทีฉันอาจจะใจร้อน

คุณสามารถลองทำสิ่งต่อไปนี้ได้

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

ลองใช้วิธีนี้เพื่อดูว่าคุณสามารถกรองคอลัมน์ที่ได้รับจาก API ได้หรือไม่

$a.Results | ft

หรือคุณสามารถลองใช้สิ่งนี้ได้เช่นกัน

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

ส่วนหัวของ Curl Style

$b.Headers

ฉันทดสอบ IRM / IWR ด้วย twitter JSON api

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

หวังว่านี่จะช่วยได้


ขอขอบคุณสำหรับความช่วยเหลือของคุณ อย่างไรก็ตามคำสั่งแรก $ a = Invoke-RestMethod (... ) เป็นคำสั่งที่ใช้ไม่ได้สำหรับฉันในขณะนี้ ทำงานได้ดีสำหรับไซต์ HTTP แต่เมื่อคุณแนะนำ HTTPS ซึ่ง EM7 จะส่งกลับข้อผิดพลาดที่อธิบายไว้ นั่นคือสำหรับ Invoke-RestMethod และ Invoke-WebRequest ฉันอยู่ในขั้นตอนการใช้ Invoke-Command cmdlet และใช้ curl
floyd

0
  1. รันคำสั่งนี้

New-SelfSignedCertificate -certstorelocation ใบรับรอง: \ localmachine \ my -dnsname {your-site-hostname}

ใน powershell โดยใช้สิทธิ์ของผู้ดูแลระบบสิ่งนี้จะสร้างใบรับรองทั้งหมดในไดเรกทอรีส่วนบุคคล

  1. ในการกำจัดข้อผิดพลาดความเป็นส่วนตัวให้เลือกใบรับรองเหล่านี้คลิกขวา→คัดลอก และวางใน Trusted Root Certification Authority / Certificates
  2. ขั้นตอนสุดท้ายคือการเลือกการผูกที่ถูกต้องใน IIS ไปที่เว็บไซต์ IIS เลือกการเชื่อมโยงเลือกช่องทำเครื่องหมาย SNI และตั้งค่าใบรับรองส่วนบุคคลสำหรับแต่ละเว็บไซต์

ตรวจสอบว่าชื่อโฮสต์เว็บไซต์และชื่อ DNS ของใบรับรองควรตรงกันทุกประการ


0

การตั้งค่ารีจิสทรีเหล่านี้มีผลต่อ. NET Framework 4+ และดังนั้น PowerShell ตั้งค่าและรีสตาร์ทเซสชัน PowerShell เพื่อใช้ TLS ล่าสุดโดยไม่จำเป็นต้องรีบูต

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 

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


สำหรับใครก็ตามที่เห็นคำตอบนี้ประสบการณ์ของเราคือแพตช์รีจิสทรีนี้ต้องมีการรีบูตเพื่อรับประกันการทำงานที่เหมาะสม เมื่อพยายามตรวจสอบให้แน่ใจว่ามีการเชื่อมต่อ TLS 1.2 ระหว่างกล่อง Windows ที่เรียกใช้แอป. NET SSL 3 จะแสดงผ่านการติดตามเครือข่ายเพื่อใช้กับค่ารีจิสทรีนี้ แต่ก่อนที่จะรีบูต TLS 1.2 ถูกเรียกใช้หลังจากรีบูตเท่านั้น
David W

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.