使用https.request忽略node.js中无效的自签名ssl证书吗?

Ignore invalid self-signed ssl certificate in node.js with https.request?

我正在开发一个登录到本地无线路由器(Linksys)的小应用程序,但是我遇到了路由器的自签名ssl证书问题。

我运行wget 192.168.1.1并得到:

1
2
3
4
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'.

在节点中,捕获的错误是:

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

我当前的示例代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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"?


便宜又不安全的答案:

1
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

在代码中,在调用https.request()之前

在此问题中回答了一种更安全的方法(上述解决方案使整个节点进程不安全)


在您的请求选项中,尝试包括以下内容:

1
2
3
4
5
6
7
8
9
   var req = https.request({
      host: '192.168.1.1',
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false,
      requestCert: true,
      agent: false
    },


不要相信所有试图误导您的人。

在您的请求中,只需添加:

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

如果您打开了未经授权的证书,那么您将完全不受保护(暴露于MITM以验证身份),并且在没有SSL的情况下进行工作也不会有太大的不同。解决方案是指定您期望的CA证书,如下面的代码片段所示。确保证书的通用名称与您在请求中调用的地址相同(在主机中指定):

然后您将获得:

1
2
3
4
5
6
7
8
9
10
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证书以模拟生产环境


添加以下环境变量:

1
NODE_TLS_REJECT_UNAUTHORIZED=0

例如使用export

1
export NODE_TLS_REJECT_UNAUTHORIZED=0

(非常感谢Juanra)


添加到@Armand答案:

Add the following environment variable:

NODE_TLS_REJECT_UNAUTHORIZED=0 e.g. with export:

export NODE_TLS_REJECT_UNAUTHORIZED=0 (with great thanks to Juanra)

如果您在Windows上使用:

1
set NODE_TLS_REJECT_UNAUTHORIZED=0

感谢:@ weagle08


您还可以使用默认选项创建请求实例:

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


对于meteorJS,可以使用npmRequestOptions进行设置。

1
2
3
4
5
6
7
8
9
10
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);
});

或者您可以尝试添加本地名称解析(在大多数操作系统中的目录etc中找到hosts文件,细节有所不同),如下所示:

1
192.168.1.1 Linksys

接下来

1
2
3
4
5
6
var req = https.request({
    host: 'Linksys',
    port: 443,
    path: '/',
    method: 'GET'
...

将工作。