Bỏ qua chứng chỉ ssl tự ký không hợp lệ trong node.js với https.request?


309

Tôi đang làm việc trên một ứng dụng nhỏ đăng nhập vào bộ định tuyến không dây cục bộ (Linksys) nhưng tôi gặp vấn đề với chứng chỉ ssl tự ký của bộ định tuyến.

Tôi đã chạy wget 192.168.1.1 và nhận được:

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'.

Trong nút, lỗi bị bắt là:

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

Mã mẫu hiện tại của tôi là:

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

Làm cách nào tôi có thể nhận được node.js để thực hiện tương đương với "--no-check-cert"?

Câu trả lời:


600

Câu trả lời rẻ và không an toàn:

Thêm vào

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

trong mã, trước khi gọi https.request()

Một cách an toàn hơn (giải pháp trên làm cho toàn bộ quá trình nút không an toàn) được trả lời trong câu hỏi này


2
Làm việc như một cơ duyên cho tôi! Tôi đã đặt mã này ngay sau khi tôi đưa mọi thứ vào đầu js ứng dụng chính của mình.
Xedecimal

Điều này cũng làm việc cho combo NodeJS & sailJS. Tôi đã thêm nó ở đầu trang local.js
Michael Kork.

38
Không sử dụng cái này hoặc "từ chốiUnauthorized" trong môi trường sản xuất, vì điều này vô hiệu hóa tất cả các loại kiểm tra bảo mật.
Jason Walton

3
Tôi đã gặp sự cố với việc chạy thử nghiệm bằng mocha trên máy chủ nút https tự ký của mình và thêm nó ngay lập tức trước khi bất kỳ khối mô tả nào khiến thử nghiệm của tôi vượt qua.
artis3n

Đây có lẽ không phải là cách an toàn nhất để khắc phục vấn đề. Xem stackoverflow.com/questions/20433287/ Mạnh
Matt Pennington

166

Trong tùy chọn yêu cầu của bạn, hãy thử bao gồm những điều sau đây:

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

Đã làm cho tôi. Tôi sử dụng restler và tôi thấy nó không chuyển tiếp các tùy chọn theo mặc định nên tôi phải vá nó.
Olivier Amblet

2
Để làm việc này, bạn cần cung cấp một phiên bản rõ ràng của một Tác nhân tùy chỉnh. Tạo đối tượng tùy chọn và đặt tác nhân: 'Options.agent = new https.Agent (tùy chọn);' Sau đó, chỉ cần gọi 'https.request (tùy chọn)'
Tối đa

14
Chà, điều này hiệu quả với tôi chỉ với rejectUnauthorizedtùy chọn và không có gì khác
mcont

@mcont tôi xác nhận chỉ rejectUnauthorizedlà đủ tốt mọi thứ khác ootb. Sử dụng trong phần mở rộng vs mã. Tốt hơn nữa là cho phép cấu hình PEM, tôi sẽ làm điều đó tiếp theo ...
esc-llc

61

Đừng tin tất cả những người cố gắng đánh lừa bạn.

Trong yêu cầu của bạn, chỉ cần thêm:

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

Nếu bạn bật chứng chỉ trái phép, bạn sẽ không được bảo vệ (tiếp xúc với MITM vì không xác thực danh tính) và làm việc mà không có SSL sẽ không phải là một sự khác biệt lớn. Giải pháp là chỉ định chứng chỉ CA mà bạn mong đợi như được hiển thị trong đoạn mã tiếp theo. Đảm bảo rằng tên chung của chứng chỉ giống với địa chỉ bạn đã gọi trong yêu cầu (Như được chỉ định trong máy chủ lưu trữ):

Những gì bạn sẽ nhận được sau đó là:

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
    },

Vui lòng đọc bài viết này (tiết lộ: bài đăng trên blog được viết bởi tác giả của câu trả lời này) tại đây để hiểu:

  • Chứng chỉ CA hoạt động như thế nào
  • Cách tạo CA Certs để kiểm tra dễ dàng nhằm mô phỏng môi trường sản xuất

7
Điều này hoạt động và là cách đúng đắn để khắc phục sự cố "Lỗi: chứng chỉ tự ký trong chuỗi chứng chỉ."
RohanRasane

1
Tại sao bạn đặt fs.readFileSync trong ngoặc, thay vì lưu trữ dưới dạng chuỗi?
Lelo

Lelo: ngoặc biến nó thành một mảng. ca: mong đợi một loạt các certs. Tệp này phải là một danh sách các certs được phân tách bằng dấu phẩy, thường mọi người sử dụng hàm bên trong để biến tệp PEM thành một mảng. Đối với một người tự ký cet, một chứng chỉ "nên" hoạt động.
JohnDavid

53

Thêm biến môi trường sau:

NODE_TLS_REJECT_UNAUTHORIZED=0

ví dụ với export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(rất cảm ơn Juanra)


Điều này làm việc cho tôi khi cố gắng chạywebdriver-manager update
Ashley

3
đặt NODE_TLS_RE DỰ_UNAUTHORIZED = 0 cho các cửa sổ
Felipe SS

Đây là một giải pháp tuyệt vời cho môi trường dev của tôi
David

14

Thêm vào câu trả lời @Armand:

Thêm biến môi trường sau:

NODE_TLS_RE DỰ_UNAUTHORIZED = 0, ví dụ như với xuất:

xuất NODE_TLS_RE DỰ_UNAUTHORIZED = 0 (rất cảm ơn Juanra)

Nếu bạn sử dụng windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Cảm ơn: @ weagle08


12

Bạn cũng có thể tạo một cá thể yêu cầu với các tùy chọn mặc định:

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

3

Đối với metsengJS, bạn có thể đặt với 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

Hoặc bạn có thể thử thêm độ phân giải tên cục bộ ( hoststệp được tìm thấy trong thư mục etctrong hầu hết các hệ điều hành, chi tiết khác nhau) đại loại như thế này:

192.168.1.1 Linksys 

và tiếp theo

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

sẽ làm việc.


3
đúng là điều này có thể trả lời câu hỏi nhưng tôi nghĩ lỗi tiếp theo sẽ là DEPTH_ZERO_SELF_SIGNED_CERT trong trường hợp này.
Olivier Amblet

1
vậy làm thế nào để một người có được khoảng DEPTH_ZERO_SELF_SIGNED_CERT? Tôi đang chạy vào đó bây giờ.
reza

3
@reza: thêm phần này vào tùy chọn của bạn:rejectUnauthorized: false
Obay 20/03/2016

1
Tôi biết điều này hơi cũ nhưng để tham khảo trong tương lai (để thực hiện đúng cách), bạn cần lấy mã hóa PEM của chứng chỉ tự ký và đưa nó vào các tùy chọn dưới dạng CA (bạn rõ ràng cũng cần để đặt giá trị tác nhân nhưng điều đó có thể sai). Vì chứng chỉ là tự ký, nó hoạt động như một CA riêng và do đó có thể được sử dụng để tự xác minh. Tuy nhiên tôi cũng sẽ đặt câu hỏi liệu nó có thực sự đáng để thực hiện trên bộ định tuyến hay không vì phần sụn có thể được tải xuống và do đó khóa riêng có thể dễ dàng bị xâm phạm.
Jonathan Gray
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.