Abaikan sertifikat ssl yang ditandatangani sendiri yang tidak valid di node.js dengan https.request?

309

Saya sedang mengerjakan aplikasi kecil yang masuk ke router nirkabel lokal saya (Linksys) tetapi saya mengalami masalah dengan sertifikat ssl yang ditandatangani sendiri oleh router.

Saya berlari wget 192.168.1.1 dan mendapatkan:

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/[email protected]':
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'.

Dalam node, kesalahan yang ditangkap adalah:

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

Kode sampel saya saat ini adalah:

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

Bagaimana saya bisa mendapatkan node.js untuk melakukan yang setara dengan "--tidak-periksa-sertifikat"?

Geuis
sumber

Jawaban:

601

Jawaban murah dan tidak aman:

Menambahkan

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

dalam kode, sebelum memanggil https.request()

Cara yang lebih aman (solusi di atas membuat seluruh proses node tidak aman) dijawab dalam pertanyaan ini

Juanra
sumber
2
Bekerja seperti pesona bagi saya! Saya menempatkan kode ini tepat setelah saya memasukkan semuanya di bagian paling atas js aplikasi utama saya.
Xedecimal
Ini juga berfungsi untuk kombo NodeJS & SailJS. Saya menambahkannya di bagian atas local.js
Michael Kork.
38
Jangan gunakan ini atau "tolak otorisasi" di lingkungan produksi, karena ini menonaktifkan semua jenis pemeriksaan keamanan.
Jason Walton
3
Saya mengalami masalah dengan menjalankan tes menggunakan moka pada server simpul https yang saya tandatangani sendiri, dan menambahkan ini segera sebelum setiap blok yang dijelaskan membuat tes saya lulus.
artis3n
Ini mungkin bukan cara paling aman untuk memperbaiki masalah. Lihat stackoverflow.com/questions/20433287/…
Matt Pennington
166

Dalam opsi permintaan Anda, coba sertakan yang berikut:

   var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false,
      requestCert: true,
      agent: false
    },
Meg Sharkey
sumber
Bekerja untukku. Saya menggunakan restler dan saya melihatnya tidak meneruskan opsi secara default jadi saya harus menambalnya.
Olivier Amblet
2
Agar ini berfungsi, Anda perlu memberikan contoh eksplisit Agen khusus. Buat objek opsi dan atur agen: 'options.agent = new https.Agent (options);' Kemudian panggil saja 'https.request (options)'
Max
14
Yah, ini bekerja untuk saya hanya dengan rejectUnauthorizedopsi dan tidak ada yang lain
mcont
@mcont saya mengkonfirmasi hanya rejectUnauthorizedcukup baik semuanya ootb. Menggunakan ekstensi kode dalam vs. Lebih baik lagi mengizinkan konfigurasi PEM, saya akan melakukannya nanti ...
escape-llc
61

Jangan percaya semua orang yang mencoba menyesatkan Anda.

Dalam permintaan Anda, tambahkan saja:

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

Jika Anda mengaktifkan sertifikat yang tidak sah, Anda tidak akan dilindungi sama sekali (terkena MITM karena tidak memvalidasi identitas), dan bekerja tanpa SSL tidak akan ada perbedaan besar. Solusinya adalah menentukan sertifikat CA yang Anda harapkan seperti yang ditunjukkan pada cuplikan berikutnya. Pastikan bahwa nama umum sertifikat identik dengan alamat yang Anda panggil dalam permintaan (Sebagaimana ditentukan dalam host):

Apa yang akan Anda dapatkan adalah:

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

Silakan baca artikel ini (pengungkapan: posting blog yang ditulis oleh penulis jawaban ini) di sini untuk memahami:

  • Bagaimana Sertifikat CA bekerja
  • Cara menghasilkan CA Certs untuk pengujian dengan mudah untuk mensimulasikan lingkungan produksi
Hesham Yassin
sumber
7
Ini berfungsi dan merupakan cara yang tepat untuk memperbaiki masalah "Kesalahan: sertifikat yang ditandatangani sendiri dalam rantai sertifikat."
RohanRasane
1
mengapa Anda memasukkan fs.readFileSync di dalam kurung, alih-alih menyimpannya sebagai string?
Lelo
Lelo: kurung mengubahnya menjadi array. ca: mengharapkan berbagai sertifikat. File ini harus berupa daftar sertifikat yang dipisahkan koma, sering kali orang menggunakan fungsi dalam untuk mengubah file PEM menjadi sebuah array. Untuk kontrak yang ditandatangani sendiri, satu sertifikat "harus" berfungsi.
JohnDavid
53

Tambahkan variabel lingkungan berikut:

NODE_TLS_REJECT_UNAUTHORIZED=0

misalnya dengan export:

export NODE_TLS_REJECT_UNAUTHORIZED=0

(dengan penuh terima kasih kepada Juanra)

Armand
sumber
Ini bekerja untuk saya ketika mencoba menjalankanwebdriver-manager update
Ashley
3
set NODE_TLS_REJECT_UNAUTHORIZED = 0 untuk windows
Felipe SS
Ini adalah solusi yang bagus untuk lingkungan dev saya
David
14

Menambahkan ke @Armand jawab:

Tambahkan variabel lingkungan berikut:

NODE_TLS_REJECT_UNAUTHORIZED = 0 misalnya dengan ekspor:

export NODE_TLS_REJECT_UNAUTHORIZED = 0 (terima kasih banyak kepada Juanra)

Jika Anda menggunakan Windows:

set NODE_TLS_REJECT_UNAUTHORIZED=0

Terima kasih kepada: @ weagle08

IamStalker
sumber
12

Anda juga dapat membuat contoh permintaan dengan opsi default:

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

Untuk meteorJS Anda dapat mengatur dengan 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);
});
digz6666
sumber
1

Atau Anda dapat mencoba menambahkan resolusi nama lokal ( hostsfile ditemukan di direktori etcdi sebagian besar sistem operasi, detail berbeda) sesuatu seperti ini:

192.168.1.1 Linksys 

dan selanjutnya

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

akan bekerja.

piaf
sumber
3
benar bahwa ini mungkin menjawab pertanyaan tapi saya pikir kesalahan selanjutnya adalah DEPTH_ZERO_SELF_SIGNED_CERT dalam kasus ini.
Olivier Amblet
1
jadi bagaimana caranya menyiasati DEPTH_ZERO_SELF_SIGNED_CERT? Saya mengalami itu sekarang.
reza
3
@reza: tambahkan ini ke opsi Anda:rejectUnauthorized: false
Obay
1
Saya tahu ini agak lama tetapi untuk referensi di masa mendatang (untuk melakukan ini dengan cara yang benar), Anda perlu mendapatkan PEM-encoding dari sertifikat yang ditandatangani sendiri dan memasukkannya dalam opsi sebagai CA (Anda tampaknya juga perlu untuk menetapkan nilai agen tetapi itu bisa salah). Karena sertifikat ditandatangani sendiri, sertifikat tersebut bertindak sebagai CA sendiri dan oleh karena itu dapat digunakan untuk memverifikasi sendiri. Namun saya juga akan mempertanyakan apakah itu benar-benar layak untuk dilakukan pada router karena firmware mungkin dapat diunduh dan karenanya kunci pribadi dapat dengan mudah dikompromikan.
Jonathan Gray