เพิกเฉยใบรับรอง SSL ที่ลงชื่อด้วยตนเองที่ไม่ถูกต้องใน node.js ด้วย https.request หรือไม่


309

ฉันกำลังทำงานกับแอพเล็ก ๆ ที่ลงชื่อเข้าใช้เราเตอร์ไร้สายในพื้นที่ของฉัน (Linksys) แต่ฉันพบปัญหากับใบรับรอง SSL ที่ลงชื่อด้วยตนเองของเราเตอร์

ฉันวิ่ง wget 192.168.1.1 และรับ:

ERROR: cannot verify 192.168.1.1's certificate, issued by `/C=US/ST=California/L=Irvine/O=Cisco-Linksys, LLC/OU=Division/CN=Linksys/emailAddress=support@linksys.com':
Self-signed certificate encountered.
ERROR: certificate common name `Linksys' doesn't match requested host name `192.168.1.1'.
To connect to 192.168.1.1 insecurely, use `--no-check-certificate'.

ในโหนดข้อผิดพลาดที่ถูกจับได้คือ:

{ [Error: socket hang up] code: 'ECONNRESET' }

รหัสตัวอย่างปัจจุบันของฉันคือ:

var req = https.request({ 
    host: '192.168.1.1', 
    port: 443,
    path: '/',
    method: 'GET'

}, function(res){

    var body = [];
    res.on('data', function(data){
        body.push(data);
    });

    res.on('end', function(){
        console.log( body.join('') );
    });

});
req.end();

req.on('error', function(err){
    console.log(err);
});

ฉันจะไปเกี่ยวกับการรับ node.js เพื่อทำเทียบเท่า "- no-check-certificate"?

คำตอบ:


600

คำตอบที่ประหยัดและไม่ปลอดภัย:

เพิ่ม

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

ในรหัสก่อนโทร https.request()

วิธีที่ปลอดภัยยิ่งขึ้น (การแก้ปัญหาด้านบนทำให้ทั้งกระบวนการไม่ปลอดภัยทั้งโหนด) ได้รับคำตอบในคำถามนี้


2
ทำงานเหมือนเสน่ห์สำหรับฉัน! ฉันวางรหัสนี้ทันทีหลังจากรวมทุกอย่างไว้ในส่วนบนสุดของแอปพลิเคชันหลักของฉัน js
Xedecimal

สิ่งนี้ใช้ได้กับคอมโบของ NodeJS & SailJS ด้วย ฉันเพิ่มที่ด้านบนของ local.js
Michael Kork

38
อย่าใช้สิ่งนี้หรือ "ปฏิเสธไม่ได้รับอนุญาต" ในสภาพแวดล้อมการใช้งานจริงเนื่องจากจะปิดใช้งานการตรวจสอบความปลอดภัยทุกประเภท
Jason Walton

3
ฉันมีปัญหาในการรันการทดสอบโดยใช้มอคค่าบนเซิร์ฟเวอร์โหนด https ของตนเองที่ลงนามและเพิ่มสิ่งนี้ทันทีก่อนที่บล็อกอธิบายใด ๆ ที่ทำให้การทดสอบของฉันผ่าน
artis3n

นี่อาจไม่ใช่วิธีที่ปลอดภัยที่สุดในการแก้ไขปัญหา ดูstackoverflow.com/questions/20433287/…
แมตต์เพนนิงตัน

166

ในตัวเลือกคำขอของคุณลองรวมต่อไปนี้:

   var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false,
      requestCert: true,
      agent: false
    },

ทำงานให้ฉัน ฉันใช้ restler และฉันเห็นว่าไม่ได้ส่งต่อตัวเลือกตามค่าเริ่มต้นดังนั้นฉันจึงต้องแก้ไขมัน
Olivier Amblet

2
เพื่อให้สามารถใช้งานได้คุณจะต้องระบุอินสแตนซ์ที่ชัดเจนของตัวแทนที่กำหนดเอง สร้างวัตถุตัวเลือกและตั้งค่าตัวแทน: 'options.agent = new https.Agent (ตัวเลือก);' จากนั้นเพียงโทร 'https.request (ตัวเลือก)'
สูงสุด

14
ดีนี้ทำงานให้ฉันด้วยเพียงrejectUnauthorizedตัวเลือกและไม่มีอะไรอื่น
mcont

@ ฉันจะยืนยันว่าrejectUnauthorizedดีพอทุกอย่างอื่น ootb ใช้ภายในกับนามสกุลรหัส ดีกว่า แต่อนุญาตการตั้งค่า PEM ฉันจะทำต่อไป ...
escape-llc

61

อย่าเชื่อทุกคนที่พยายามหลอกลวงคุณ

ในคำขอของคุณเพียงเพิ่ม:

ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})]

หากคุณเปิดใช้ใบรับรองที่ไม่ได้รับอนุญาตคุณจะไม่ได้รับการคุ้มครองเลย (สัมผัสกับ MITM สำหรับการไม่ตรวจสอบข้อมูลประจำตัว) และการทำงานโดยไม่มี SSL จะไม่แตกต่างกันมาก วิธีแก้ไขคือการระบุใบรับรอง CA ที่คุณคาดหวังตามที่แสดงในตัวอย่างถัดไป ตรวจสอบให้แน่ใจว่าชื่อสามัญของใบรับรองเหมือนกับที่อยู่ที่คุณโทรในคำขอ (ตามที่ระบุในโฮสต์):

สิ่งที่คุณจะได้รับคือ:

var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      ca: [fs.readFileSync([certificate path], {encoding: 'utf-8'})],
      method: 'GET',
      rejectUnauthorized: true,
      requestCert: true,
      agent: false
    },

โปรดอ่านบทความนี้ (การเปิดเผย: บล็อกโพสต์ที่เขียนโดยผู้เขียนคำตอบนี้) ที่นี่เพื่อทำความเข้าใจ:

  • ใบรับรอง CA ทำงานอย่างไร
  • วิธีสร้าง CA Certs สำหรับการทดสอบอย่างง่ายดายเพื่อจำลองสภาพแวดล้อมการผลิต

7
วิธีนี้ใช้งานได้และเป็นวิธีที่ถูกต้องในการแก้ไขปัญหา "ข้อผิดพลาด: ใบรับรองที่ลงชื่อด้วยตนเองในห่วงโซ่ใบรับรอง"
RohanRasane

1
ทำไมคุณถึงใส่ fs.readFileSync ไว้ในวงเล็บแทนที่จะเก็บไว้เป็นสตริง?
Lelo

Lelo: วงเล็บเปลี่ยนเป็นอาร์เรย์ ca: คาดว่าอาร์เรย์ของ certs ไฟล์นี้ควรเป็นรายการที่คั่นด้วยเครื่องหมายจุลภาคบ่อยครั้งที่ผู้คนใช้ฟังก์ชั่นภายในเพื่อเปลี่ยนไฟล์ PEM ให้เป็นอาร์เรย์ สำหรับ cet ที่เซ็นชื่อด้วยตนเองใบรับรองเดียว "ควร" ทำงาน
JohnDavid

53

เพิ่มตัวแปรสภาพแวดล้อมต่อไปนี้:

NODE_TLS_REJECT_UNAUTHORIZED=0

เช่นกับexport:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(ด้วยความขอบคุณอย่างยิ่งต่อ Juanra)


สิ่งนี้ใช้ได้สำหรับฉันเมื่อพยายามวิ่งwebdriver-manager update
แอชลีย์

3
ตั้ง NODE_TLS_REJECT_UNAUTHORIZED = 0 สำหรับ windows
Felipe SS

นี่เป็นทางออกที่ดีสำหรับสภาพแวดล้อมการพัฒนาของฉัน
David

14

การเพิ่ม @Armand คำตอบ:

เพิ่มตัวแปรสภาพแวดล้อมต่อไปนี้:

NODE_TLS_REJECT_UNAUTHORIZED = 0 เช่นด้วยการส่งออก:

ส่งออก NODE_TLS_REJECT_UNAUTHORIZED = 0 (ด้วยความขอบคุณอย่างยิ่งสำหรับ Juanra)

หากคุณใช้งาน windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

ขอบคุณที่: @ weagle08


12

นอกจากนี้คุณยังสามารถสร้างตัวอย่างคำขอพร้อมตัวเลือกเริ่มต้น:

require('request').defaults({ rejectUnauthorized: false })

3

สำหรับ meteorJS คุณสามารถตั้งค่าด้วย npmRequestOptions

HTTP.post(url, {
    npmRequestOptions: {
        rejectUnauthorized: false // TODO remove when deploy
    },
    timeout: 30000, // 30s
    data: xml
}, function(error, result) {
    console.log('error: ' + error);
    console.log('resultXml: ' + result);
});

1

หรือคุณสามารถลองเพิ่มการจำแนกชื่อโลคัล ( hostsไฟล์ที่พบในไดเรกทอรีetcในระบบปฏิบัติการส่วนใหญ่มีรายละเอียดต่างกัน) ดังนี้:

192.168.1.1 Linksys 

และต่อไป

var req = https.request({ 
    host: 'Linksys', 
    port: 443,
    path: '/',
    method: 'GET'
...

จะทำงาน.


3
จริงว่านี่อาจตอบคำถาม แต่ฉันคิดว่าข้อผิดพลาดถัดไปจะเป็น DEPTH_ZERO_SELF_SIGNED_CERT ในกรณีนี้
Olivier Amblet

1
แล้วเราจะไปถึง DEPTH_ZERO_SELF_SIGNED_CERT ได้อย่างไร ตอนนี้ฉันกำลังวิ่งเข้าไป
reza

3
@reza: เพิ่มไปยังตัวเลือกของคุณ:rejectUnauthorized: false
Obay

1
ฉันรู้ว่านี่เก่าไปหน่อย แต่สำหรับการอ้างอิงในอนาคต (เพื่อที่จะทำวิธีที่ถูกต้อง) คุณต้องได้รับการเข้ารหัส PEM ของใบรับรองที่ลงนามด้วยตนเองและรวมไว้ในตัวเลือกในฐานะ CA (เห็นได้ชัดว่าคุณต้องการ เพื่อตั้งค่าตัวแทน แต่สามารถเป็นเท็จได้) เนื่องจากใบรับรองเป็นแบบลงนามด้วยตนเองจึงทำหน้าที่เป็น CA ของตัวเองและสามารถใช้ในการตรวจสอบตัวเองได้ อย่างไรก็ตามฉันจะถามด้วยว่ามันคุ้มค่าที่จะทำกับเราเตอร์หรือไม่เพราะอาจดาวน์โหลดเฟิร์มแวร์และคีย์ส่วนตัวอาจถูกบุกรุกได้ง่าย
Jonathan Gray
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.