การเชื่อมต่อ https โดยใช้ CURL จากบรรทัดคำสั่ง


127

ฉันยังใหม่กับโลก Curl และ Cacerts และประสบปัญหาขณะเชื่อมต่อกับเซิร์ฟเวอร์ โดยพื้นฐานแล้วฉันต้องทดสอบการเชื่อมต่อผ่าน https จากเครื่องหนึ่งไปยังอีกเครื่องหนึ่ง ฉันมี URL ที่ฉันต้องการเชื่อมต่อจากเครื่อง A (เครื่อง linux) ฉันลองสิ่งนี้ในพรอมต์คำสั่ง

cmd> curl https://[my domain or IP address]

และได้รับสิ่งต่อไปนี้:

curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

ในการอ่านบทความทางอินเทอร์เน็ตฉันทำสิ่งนี้:

openssl s_client -connect <domain name or Ip address>:443

และได้รับการตอบกลับบางอย่างรวมถึงใบรับรองเซิร์ฟเวอร์ (ภายใน-----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----)

ฉันควรทำอย่างไรต่อจากที่นี่ ฉันคิดว่าฉันจะต้องคัดลอกและวางข้อความข้างใน BEGIN CERTIFICATE & END CERTIFICATEแล้วบันทึกเป็นไฟล์ แต่ควรเป็นไฟล์ประเภทใด .pem, .crt? .. หลังจากนั้นควรทำอย่างไร?

ฉันลองทำสิ่งนี้ - คัดลอกข้อความภายในBEGIN CERTIFICATE & END CERTIFICATEและบันทึกไว้ใน.crtไฟล์ - ตั้งชื่อเป็นmy-ca.crt(ลองสิ่งเดียวกันโดยตั้งชื่อเป็นmy-ca.pemไฟล์) จากนั้นทำสิ่งนี้:

cmd>curl --cacert my-ca.crt https://[my domain or IP address]

แต่มีข้อผิดพลาดเดียวกัน


ไม่แน่ใจเกี่ยวกับวิธีแก้ปัญหาที่คุณแนะนำ แต่ฉันแค่มองหาข้อมูลที่คล้ายกันและฉันพบไซต์ที่มีประโยชน์สำหรับการใช้ curl กับ PHP unitstep.net/blog/2009/05/05/…
MauroPerez

1
คุณยังสามารถเพิ่ม--insecureเพื่อไม่สนใจข้อผิดพลาด SSL
Alexej Magura

curl เวอร์ชันใหม่กว่า (เช่น 7.64) จะไม่รู้จักการเข้ารหัสรุ่นเก่าเช่น RC4-SHA - การใช้ curl เวอร์ชันเก่า (7.46) ช่วยฉันได้serverfault.com/questions/889631/…
hello_earth

คำตอบ:


142

ฉันมีปัญหาเดียวกัน - ฉันกำลังดึงหน้าจากไซต์ของตัวเองซึ่งให้บริการผ่าน HTTPS แต่ curl ให้ข้อความ "ปัญหาใบรับรอง SSL" แบบเดียวกัน ฉันแก้ไขมันโดยการเพิ่ม-kแฟล็กในการโทรเพื่ออนุญาตการเชื่อมต่อที่ไม่ปลอดภัย

curl -k https://whatever.com/script.php

แก้ไข: ฉันค้นพบต้นตอของปัญหา ฉันใช้ใบรับรอง SSL (จาก StartSSL แต่ฉันไม่คิดว่ามันสำคัญมาก) และไม่ได้ตั้งค่าใบรับรองระดับกลางอย่างถูกต้อง หากคุณประสบปัญหาเช่นเดียวกับ user1270392 ข้างต้นอาจเป็นความคิดที่ดีที่จะทดสอบใบรับรอง SSL ของคุณและแก้ไขปัญหาใด ๆ ก่อนที่จะใช้วิธีcurl -kแก้ไข


5
-k flag เป็นทางลัดที่ดี ทำงานให้ฉัน!
tidydee

45

วิธีแก้ปัญหาง่ายๆ

นั่นคือสคริปต์ประจำวันของฉัน:

curl --insecure -v https://www.google.com 2>&1 | awk 'BEGIN { cert=0 } /^\* Server certificate:/ { cert=1 } /^\*/ { if (cert) print }'

เอาท์พุท:

* Server certificate:
*    subject: C=US; ST=California; L=Mountain View; O=Google Inc; CN=www.google.com
*    start date: 2016-01-07 11:34:33 GMT
*    expire date: 2016-04-06 00:00:00 GMT
*    issuer: C=US; O=Google Inc; CN=Google Internet Authority G2
*    SSL certificate verify ok.
* Server GFE/2.0 is not blacklisted
* Connection #0 to host www.google.com left intact

11
ดังนั้นคุณจึงอนุญาตให้--insecureเชื่อมต่อผ่าน TSL ทุกวัน ...
Brethlosze

2
@Brethlosze ขอบคุณสำหรับความคิดเห็นของคุณ แต่นั่นไม่ใช่อย่างนั้น ประเด็นคือการรับข้อมูล SSL จากใบรับรองทุกประเภท
Antonio Feitosa

30

คุณต้องจัดเตรียมห่วงโซ่ใบรับรองทั้งหมดเพื่อขดเนื่องจาก curl ไม่ได้มาพร้อมกับใบรับรอง CA ใด ๆ อีกต่อไป เนื่องจากตัวเลือก cacert สามารถใช้ได้เพียงไฟล์เดียวคุณจึงต้องต่อข้อมูลเชนแบบเต็มเป็น 1 ไฟล์

คัดลอกห่วงโซ่ใบรับรอง (จากเบราว์เซอร์ของคุณเป็นต้น) ลงใน DER ที่เข้ารหัสไบนารี x.509 (.cer) ทำสิ่งนี้สำหรับแต่ละใบรับรอง

แปลงใบรับรองเป็น PEM และเชื่อมต่อเป็นไฟล์ 1 ไฟล์

openssl x509 -inform DES -in file1.cer -out file1.pem -text
openssl x509 -inform DES -in file2.cer -out file2.pem -text
openssl x509 -inform DES -in file3.cer -out file3.pem -text

cat *.pem > certRepo

curl --cacert certRepo -u user:passwd -X GET -H 'Content-Type: application/json' "https//somesecureserver.com/rest/field"

ฉันเขียนบล็อกเกี่ยวกับการทำสิ่งนี้ที่นี่: http://javamemento.blogspot.no/2015/10/using-curl-with-ssl-cert-chain.html


1
คุณช่วยอธิบายจุดประสงค์ของการส่ง userName และ Password ได้ไหม จะเกิดอะไรขึ้นถ้าฉันเขียน Java Client ฉันต้องส่งชื่อผู้ใช้และรหัสผ่านในส่วนหัวของคำขอ GET หรือไม่ในกรณีนั้น
Shubhi224

@ Shubhi224 ไม่ใช่ถ้าเซิร์ฟเวอร์ https ของคุณไม่ต้องการการตรวจสอบสิทธิ์ง่ายๆสำหรับคำขอ GET ฉันต้องใช้การพิสูจน์ตัวตนเนื่องจากเป็นการเรียก REST ซึ่งจำเป็นต้องใช้
Somaiah Kumbera

ดังที่ได้กล่าวไว้ในคำตอบนี้ "คุณต้องจัดเตรียมห่วงโซ่ใบรับรองทั้งหมดเพื่อม้วนงอเนื่องจาก curl ไม่ได้มาพร้อมกับใบรับรอง CA ใด ๆ อีกต่อไป"
Mohamed Bana


6

ฉันมีปัญหาประเภทนี้จริง ๆ และฉันแก้ไขโดยขั้นตอนเหล่านี้:

  1. รับชุดใบรับรอง CA หลักจากที่นี่: https://curl.haxx.se/ca/cacert.pemและบันทึกลงในเครื่อง

  2. ค้นหาphp.iniไฟล์

  3. กำหนดcurl.cainfoให้เป็นเส้นทางของใบรับรอง ดังนั้นมันจะเป็นดังนี้:

curl.cainfo = /path/of/the/keys/cacert.pem



1

เมื่อประสบปัญหาอย่างสง่างามฉันสามารถใช้ไฟล์ CA เริ่มต้นของระบบที่มีอยู่บน debian6 นี่คือ:

/etc/ssl/certs/ca-certificates.crt

ในฐานะรูทสามารถทำได้ดังนี้:

echo curl.cainfo=/etc/ssl/certs/ca-certificates.crt >> /etc/php5/mods-available/curl.ini

จากนั้นเริ่มต้นเว็บเซิร์ฟเวอร์ใหม่



0

สำหรับฉันฉันแค่ต้องการทดสอบเว็บไซต์ที่มีการเปลี่ยนเส้นทาง http-> https อัตโนมัติ ฉันคิดว่าฉันติดตั้งใบรับรองไว้แล้วดังนั้นสิ่งนี้จึงใช้ได้กับฉันบน Ubuntu 16.04 ที่ทำงานอยู่curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3

curl --proto-default https <target>


-3

ด้วย curl เวอร์ชันใหม่คุณสามารถลบล้างที่อยู่ IP ที่จะเชื่อมต่อได้โดยใช้ - แก้ไขหรือ - เชื่อมต่อกับ (curl ใหม่กว่าเวอร์ชัน 7.49) สิ่งนี้ใช้ได้แม้กับ SSL / SNI รายละเอียดทั้งหมดอยู่ใน man page

ตัวอย่างเช่นในการแทนที่ DNS และเชื่อมต่อกับ www.example.com ด้วย ssl โดยใช้ที่อยู่ IP เฉพาะ: (สิ่งนี้จะแทนที่ ipv6 ด้วย)

curl --resolve www.example.com:443:192.168.42.2 https://www.example.com/

อีกตัวอย่างหนึ่งในการเชื่อมต่อกับเซิร์ฟเวอร์แบ็กเอนด์ชื่อ backend1 บนพอร์ต 8080

curl --connect-to www.example.com:80:backend1.example.com:8080 http://www.example.com/

อย่าลืมเพิ่มส่วนหัวของโฮสต์หากเซิร์ฟเวอร์ต้องการให้ตอบถูก:

-H 'Host:www.example.com' 

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