gpt4 book ai didi

node.js - 如何正确配置 node.js 以使用自签名根证书?

转载 作者:行者123 更新时间:2023-12-04 22:39:59 28 4
gpt4 key购买 nike

因此,在绝望的道路上,我想知道是否有人在某个地方可以帮助我配置 nodejs 以接受根 CA 自签名。我需要它来通过带有 TLS 的 Node 获取访问开发中的自定义 API。
环境

  • 操作系统:Ubuntu 20.04 作为虚拟机中的 guest 。 Windows 10 主机。
  • Nodejs v15.12.0
  • Apache2.4服务器

  • 我正在处理的 API 是一个 PHP 脚本,它允许我的 nodejs 后端查询一些数据。
    自签名根证书和 API 证书是使用 openssl 生成的,并且非常好,因为我可以使用 HTTPS 从浏览器查询 API,没有任何问题。
    错误
    尝试从 nodejs 后端查询 API 时,出现此错误:
    FetchError: request to https://myapi.dev.local failed, reason: self signed certificate
    at ClientRequest.<anonymous> (./node_modules/node-fetch/lib/index.js:1461:11)
    at ClientRequest.emit (node:events:369:20)
    at TLSSocket.socketErrorListener (node:_http_client:462:9)
    at TLSSocket.emit (node:events:369:20)
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:81:21)"
    尝试与失败
    首先,我尝试使用 dpkg-reconfigure ca-certificates 在 ubuntu 上安装证书,但后来我发现 nodejs 使用了硬编码列表。
    所以,既然我不想使用 env变量 NODE_TLS_REJECT_UNAUTHORIZED=0为了安全起见,我尝试使用 NODE_EXTRA_CA_CERTS=pathToMycert.pem en 变量,但它不会改变任何东西,我找不到任何信息来知道发生了什么。
    在我的 nodejs 后端,如果我执行 console.log(process.env.NODE_EXTRA_CA_CERTS) ,它打印出好的路径。
    我尝试通过此检查将我的 CA 与 tls.rootCertificates 匹配:

    const tls = require('tls');
    const fs = require('fs');

    const ca = await fs.readFileSync(process.env.NODE_EXTRA_CA_CERTS, 'utf8');
    console.log(ca); //successfully print the CA, so it exists.
    const inList = tls.rootCertificates.some( cert =>{
    console.log('testing ca : \n',cert);
    return cert == ca;
    });
    console.log(`CA is ${ !inList ? 'not' : '' } in rootCertificates list...`);

    它打印“CA 不在 rootCertificates 列表中”。并不意外。
    因此,我尝试对 tls secureContext 进行猴子补丁以包含我的证书:

    const tls = require('tls');
    const fs = require('fs');

    const origCreateSecureContext = tls.createSecureContext;

    tls.createSecureContext = options => {
    const context = origCreateSecureContext(options);

    const list = (process.env.NODE_EXTRA_CA_CERTS || '').split(',');
    list.forEach(extraCert => {
    const pem = fs.readFileSync(extraCert, { encoding : 'utf8' }).replace(/\r\n/g, "\n");
    const certs = pem.match(/-----BEGIN CERTIFICATE-----\n[\s\S]+?\n-----END CERTIFICATE-----/g);
    if(!certs) throw new Error(
    `SelfSignedCertSupport : Invalid extra certificate ${extraCert}`
    );
    certs.forEach(cert => context.context.addCACert(cert.trim()));
    });

    return context;
    };

    不工作。
    我试过(在这个问题之后: https://github.com/nodejs/node/issues/27079)这样做:

    const tls = require('tls');
    const fs = require('fs');

    const additionalCerts = [];
    const list = (process.env.NODE_EXTRA_CA_CERTS || '').split(',');
    list.forEach(extraCert => {
    const pem = fs.readFileSync(extraCert, { encoding : 'utf8' }).replace(/\r\n/g, "\n");
    const certs = pem.match(/-----BEGIN CERTIFICATE-----\n[\s\S]+?\n-----END CERTIFICATE-----/g);
    if(!certs) throw new Error(
    `SelfSignedCertSupport : Invalid extra certificate ${extraCert}`
    );
    additionalCerts.push(...certs);
    });

    tls.rootCertificates = [
    ...tls.rootCertificates,
    ...additionalCerts
    ];

    没有任何运气。
    我究竟做错了什么 ?

    最佳答案

    我弄清楚发生了什么事。这是两个问题的结合。
    首先,我生成了我的 CA 证书和其他自签名证书 同CN .它适用于所有浏览器和网络服务器,但不适用于 node。对于 Node ,请确保您的所有 CN 都有 不同的名字 (如 this answer 中所述)。
    第二个问题是环境变量 NODE_EXTRA_CA_CERTS在我的环境中由于某种原因无法正常工作。像我一样尝试猴子补丁可以工作,但很难看,因为 addCACert不是公共(public) nodejs API 的一部分。它不应该被使用。​​​
    由于我使用 fetch依赖于 https 的 API包,我在我的后端 nodejs 应用程序的顶部创建了一个我需要的小模块:


    if(!process.env.NODE_EXTRA_CA_CERTS) return;

    const https = require('https');
    const tls = require('tls');
    const fs = require('fs');

    const list = (process.env.NODE_EXTRA_CA_CERTS || '').split(',');
    const additionalCerts = list.map(extraCert => fs.readFileSync(extraCert, 'utf8'));

    https.globalAgent.options.ca = [
    ...tls.rootCertificates,
    ...additionalCerts
    ];

    这样,所有使用 https 的请求并且不会重新定义 ca options 将从 globalAgent 读取 ca 列表而且您不必使用特定于 ca 的代码污染您的代码库。就我而言,我不希望我的开发环境生成必须在生产中删除的代码。
    所以,现在它对我有用,即使我不知道 NODE_EXTRA_CA_CERTS 是怎么回事不做它的工作的环境变量。

    关于node.js - 如何正确配置 node.js 以使用自签名根证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68896243/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com