372

我正在开发一个登录本地无线路由器(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”的事情?

4

11 回答 11

733

便宜且不安全的答案:

添加

process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

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

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

于 2014-02-22T21:45:27.470 回答
192

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

   var req = https.request({ 
      host: '192.168.1.1', 
      port: 443,
      path: '/',
      method: 'GET',
      rejectUnauthorized: false,
      requestCert: true,
      agent: false
    },
于 2012-06-14T23:37:51.803 回答
73

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

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

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 证书以进行测试以模拟生产环境
于 2016-08-23T10:51:04.713 回答
64

添加以下环境变量:

NODE_TLS_REJECT_UNAUTHORIZED=0

例如export

export NODE_TLS_REJECT_UNAUTHORIZED=0

(非常感谢胡安拉)

于 2015-05-25T12:17:16.143 回答
18

添加到@Armand 答案:

添加以下环境变量:

NODE_TLS_REJECT_UNAUTHORIZED=0 例如导出:

export NODE_TLS_REJECT_UNAUTHORIZED=0(非常感谢 Juanra)

如果您在 Windows 上使用:

set NODE_TLS_REJECT_UNAUTHORIZED=0

感谢:@weagle08

于 2016-08-23T06:26:52.940 回答
16

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

require('request').defaults({ rejectUnauthorized: false })
于 2018-05-23T17:16:35.043 回答
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);
});
于 2016-01-04T07:08:13.367 回答
1

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

192.168.1.1 Linksys 

接下来

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

将工作。

于 2012-10-10T18:29:00.700 回答
1

所以,我的公司刚刚切换到 Node.js v12.x。我正在使用NODE_TLS_REJECT_UNAUTHORIZED,它停止工作。经过一番挖掘,我开始使用NODE_EXTRA_CA_CERTS=A_FILE_IN_OUR_PROJECT具有我们自签名证书的 PEM 格式,并且我的所有脚本都可以再次运行。

所以,如果你的项目有自签名证书,也许这个 env var 会对你有所帮助。

参考:https ://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file

于 2020-11-17T23:51:30.130 回答
0

尝试导出 NODE_TLS_REJECT_UNAUTHORIZED=0

于 2020-10-07T18:07:10.127 回答
0

当您无法控制请求创建时

使用包时,您有时无法在request调用中设置正确的设置,包也没有为您提供注入request.

但是,您可能仍希望避免不安全NODE_TLS_REJECT_UNAUTHORIZED=0并选择仅与指定目标建立不安全的连接。

这就是我解决问题的方法:

// check if host and port fit your application
function isSelf(host, port) {
  return host === myHost && port === myPort;
}

// get the built in tls module and overwrite the default connect behavior 
const tls = require("tls");
const _connect = tls.connect;
function wrappedConnect(options, secureConnectListener) {
  if (isSelf(options.host, options.port)) {
    options.rejectUnauthorized = false;
  }
  return _connect(options, secureConnectListener);
}
tls.connect = wrappedConnect;
于 2022-02-25T16:00:10.307 回答