【问题标题】:Ignore invalid self-signed ssl certificate in node.js with https.request?使用 https.request 忽略 node.js 中无效的自签名 ssl 证书?
【发布时间】:2012-06-08 22:58:39
【问题描述】:

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

【问题讨论】:

    标签: node.js https ssl-certificate


    【解决方案1】:

    廉价且不安全的答案:

    添加

    process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
    

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

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

    【讨论】:

    • 对我来说就像一个魅力!在我将所有内容都包含在我的主应用程序 js 的最顶部之后,我立即放置了此代码。
    • 这也适用于 NodeJS 和 SailJS 组合。我在 local.js 的顶部添加了它
    • 不要在生产环境中使用这个或“rejectUnauthorized”,因为这会禁用所有类型的安全检查。
    • 我在自签名 https 节点服务器上使用 mocha 运行测试时遇到问题,并且在任何描述块使我的测试通过之前立即添加它。
    • 这仅用于测试目的。您不应该在生产中使用它。如答案所述,这不是解决问题的最安全方法
    【解决方案2】:

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

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

    【讨论】:

    • 为我工作。我使用restler,我发现它默认没有转发选项,所以我不得不修补它。
    • 为此,您需要提供自定义代理的显式实例。创建选项对象并设置代理:'options.agent = new https.Agent(options);'然后只需调用 'https.request(options)'
    • 好吧,这对我来说只需要 rejectUnauthorized 选项就可以了
    • @mcont 我确认 rejectUnauthorized 已经足够好了,其他的 ootb。在 vs 代码扩展中使用。更好的是允许 PEM 配置,我接下来会这样做...
    • requestCert 用于服务器
    【解决方案3】:

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

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

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

    如果您打开未经授权的证书,您将根本不会受到保护(因为不验证身份而暴露于 MITM),并且在没有 SSL 的情况下工作不会有太大的不同。解决方案是指定您期望的 CA 证书,如下一个 sn-p 所示。确保证书的通用名称与您在请求中调用的地址相同(在主机中指定):

    你会得到的是:

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

    请在此处阅读this article(披露:此答案作者撰写的博客文章)以了解:

    • CA 证书的工作原理
    • 如何轻松生成用于测试的 CA 证书以模拟生产环境

    【讨论】:

    • 这行得通,是解决“错误:证书链中的自签名证书”问题的正确方法。
    • 为什么要把 fs.readFileSync 放在括号内,而不是作为字符串存储?
    • Lelo:括号把它变成一个数组。 ca:需要一系列证书。这个文件应该是一个逗号分隔的证书列表,人们经常使用内部函数将 PEM 文件转换为数组。对于自签名的 cet,单个证书“应该”工作。
    【解决方案4】:

    添加以下环境变量:

    NODE_TLS_REJECT_UNAUTHORIZED=0
    

    例如export:

    export NODE_TLS_REJECT_UNAUTHORIZED=0
    

    (非常感谢 Juanra)

    【讨论】:

    • 这在尝试运行webdriver-manager update时对我有用
    • 为 windows 设置 NODE_TLS_REJECT_UNAUTHORIZED=0
    • 这对我的开发环境来说是一个很好的解决方案
    • 拯救了我的夜晚。
    【解决方案5】:

    添加到@Armand 答案:

    添加以下环境变量:

    NODE_TLS_REJECT_UNAUTHORIZED=0 例如带出口:

    导出 NODE_TLS_REJECT_UNAUTHORIZED=0(非常感谢 Juanra)

    如果您使用 Windows:

    set NODE_TLS_REJECT_UNAUTHORIZED=0
    

    Thanks to: @weagle08

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

      • 感谢这对登录到浪涌时出现的“错误:无法获得本地颁发者证书”也有很大帮助
      【解决方案7】:

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

      【讨论】:

        【解决方案8】:

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

        192.168.1.1 Linksys 
        

        接下来

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

        会起作用的。

        【讨论】:

        • 确实这可能会回答这个问题,但我认为在这种情况下下一个错误将是 DEPTH_ZERO_SELF_SIGNED_CERT。
        • 那么如何绕过 DEPTH_ZERO_SELF_SIGNED_CERT?我现在遇到了。
        • @reza:将此添加到您的选项中:rejectUnauthorized: false
        • 我知道这有点旧,但为了将来参考(为了以正确的方式执行此操作),您需要获取自签名证书的 PEM 编码并将其包含在选项中作为 CA(您显然还需要设置代理值,但这可能是错误的)。由于证书是自签名的,它充当自己的 CA,因此可以用来验证自己。但是,我也会质疑在路由器上这样做是否真的值得,因为固件可能会被下载,因此私钥很容易被泄露。
        【解决方案9】:

        所以,我的公司刚刚切换到 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

        【讨论】:

          【解决方案10】:

          试试 导出 NODE_TLS_REJECT_UNAUTHORIZED=0

          【讨论】:

            猜你喜欢
            • 2016-10-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-11
            • 2011-05-28
            • 2014-11-20
            • 2019-01-16
            • 2019-08-04
            相关资源
            最近更新 更多