简体   繁体   English

nodejs - 证书链中的错误自签名证书

[英]nodejs - error self signed certificate in certificate chain

I am facing a problem with client side https requests.我面临客户端 https 请求的问题。

A snippet can look like this:一个片段可能如下所示:

var fs = require('fs');
var https = require('https');

var options = {
    hostname: 'someHostName.com',
    port: 443,
    path: '/path',
    method: 'GET',
    key: fs.readFileSync('key.key'),
    cert: fs.readFileSync('certificate.crt')
}

var requestGet = https.request(options, function(res){
    console.log('resObj', res);
}

What I get is Error: self signed certificate in certificate chain.我得到的是错误:证书链中的自签名证书。

When I use Postman I can import the client certificate and key and use it without any problem.当我使用 Postman 时,我可以导入客户端证书和密钥并毫无问题地使用它。 Is there any solution available??有什么解决办法吗?? I would also like to be given some lights on how postman handles the certificates and works.我还想了解邮递员如何处理证书和工作。

Option 1: Disable the warning (useful for dev)选项 1:禁用警告(对开发人员有用)

From your question I'm guessing you are doing this in development as you are using a self signed certificate for SSL communication.根据您的问题,我猜您正在开发中这样做,因为您正在使用自签名证书进行 SSL 通信。

If that's the case, add as an environment variable wherever you are running node如果是这种情况,请在运行节点的任何地方添加为环境变量

export NODE_TLS_REJECT_UNAUTHORIZED='0'
node app.js

or running node directly with或直接运行节点

NODE_TLS_REJECT_UNAUTHORIZED='0' node app.js

This instructs Node to allow untrusted certificates (untrusted = not verified by a certificate authority)这指示 Node 允许不受信任的证书(不受信任 = 未经证书颁发机构验证)

If you don't want to set an environment variable or need to do this for multiple applications npm has a strict-ssl config you set to false如果您不想设置环境变量或需要为多个应用程序执行此操作,npm 有一个strict-ssl配置,您设置为false

npm config set strict-ssl=false

Option 2: Load in CA cert, like postman (useful for testing with TLS)选项 2:加载 CA 证书,如邮递员(用于 TLS 测试)

If you have a CA cert already like the poster @kDoyle mentioned then you can configure in each request (thanks @nic ferrier).如果您已经拥有像 @kDoyle 提到的海报那样的 CA 证书,那么您可以在每个请求中进行配置(感谢 @nic ferrier)。

 let opts = {
    method: 'GET',
    hostname: "localhost",
    port: listener.address().port,
    path: '/',
    ca: fs.readFileSync("cacert.pem")
  };

  https.request(opts, (response) => { }).end();

Option 3: Use a proper SSL Cert from a trusted source (useful for production)选项 3:使用来自可信来源的适当 SSL 证书(对生产有用)

letsencrypt.org is free, easy to set up and the keys can be automatically rotated. letsencrypt.org 是免费的,易于设置,并且可以自动轮换密钥。 https://letsencrypt.org/docs/ https://letsencrypt.org/docs/

You can fix this issue using NODE_TLS_REJECT_UNAUTHORIZED=0 in the terminal or inserting the following line within the JS file.您可以在终端中使用NODE_TLS_REJECT_UNAUTHORIZED=0或在 JS 文件中插入以下行来解决此问题。

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;

Beware that this a hack and it should not be used in production.请注意,这是一个 hack,不应在生产中使用。

If you are using windows then run the following command in the command prompt:如果您使用的是 windows,请在命令提示符下运行以下命令:

set NODE_TLS_REJECT_UNAUTHORIZED=0 

After that, npm install <my-package> will work.之后, npm install <my-package>将起作用。

您可以编写命令npm config set strict-ssl false

for Nodemailer:对于 Nodemailer:

adding添加

tls: {
  rejectUnauthorized: false
}

solved my problem.解决了我的问题。

Overall code looks liek this:整体代码看起来像这样:

nodemailer.createTransport({
    host: process.env.MAIL_SERVER,
    secure: false,
    port: 587,
    auth: {
      user: process.env.MAIL_USERNAME,
      pass: process.env.MAIL_PASSWORD
    },
    tls: {
      rejectUnauthorized: false
    }
  }

you just add at the start of your code this line:您只需在代码的开头添加这一行:

process.env.NODE_TLS_REJECT_UNAUTHORIZED='0'

And everything solved, but in any case it is not recommendable, I am investigating the solution of https://letsencrypt.org/一切都解决了,但无论如何都不推荐,我正在研究https://letsencrypt.org/的解决方案

Turning off verification is quite a dangerous thing to do.关闭验证是一件非常危险的事情。 Much better to verify the certificate.更好地验证证书。

You can pull the Certificate Authority certificate into the request with the ca key of the options object, like this:您可以使用选项对象的ca密钥将证书颁发机构证书拉入请求中,如下所示:

let opts = {
    method: 'GET',
    hostname: "localhost",
    port: listener.address().port,
    path: '/',
    ca: await fs.promises.readFile("cacert.pem")
  };

https.request(opts, (response) => { }).end();

I put a whole demo together of this so you can see how to construct SSL tests.我将整个演示放在一起,以便您了解如何构建 SSL 测试。

It's here .它在这里

The node application needs to have the CA certificate added to the existing CA (Mozilla) certificates.节点应用程序需要将 CA 证书添加到现有 CA (Mozilla) 证书中。

We start node using a service, and add the environment variable, NODE_EXTRA_CA_CERTS我们使用服务启动节点,并添加环境变量 NODE_EXTRA_CA_CERTS

[Service]
Restart=always
User=<...>
Group=<...>
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
Environment=NODE_EXTRA_CA_CERTS=/<...>/.ssl/extra_certs.pem
WorkingDirectory=/<...>

ExecStart=/usr/bin/node -r dotenv/config /<.....>/server.js dotenv_config_path=/<....>/.env

This way we can use the same application to call services using popular CAs or our own self signed certs, and we don't have to turn off SSL checking.这样我们就可以使用同一个应用程序来调用使用流行的 CA 或我们自己的自签名证书的服务,并且我们不必关闭 SSL 检查。

In linux there is an easy way to get the certificate, use this post: Use self signed certificate with cURL?在 linux 中有一种简单的方法来获取证书,请使用这篇文章: 使用 cURL 使用自签名证书?

You create your certificate using:您使用以下方法创建证书:

$ echo quit | openssl s_client -showcerts -servername server -connect server:443 > cacert.pem

then copy that .pem file as the extra_cert.pem.然后将该 .pem 文件复制为 extra_cert.pem。 You can only have one pem file, but you can append multiple pem files into one file.您只能拥有一个 pem 文件,但您可以将多个 pem 文件附加到一个文件中。

I hope this helps someone, it took me a while to find the different parts to make this work.我希望这对某人有所帮助,我花了一段时间才找到不同的部分来完成这项工作。

For what it's worth, after spending a day and a half trying to track this one down it turned out the error was caused by a setting on my company's firewall that IT had to disable.值得一提的是,在花了一天半的时间试图追踪这个错误之后,结果发现这个错误是由我公司防火墙上的一个设置引起的,IT 必须禁用它。 Nothing anywhere on the internet did anything to fix this.互联网上的任何地方都没有做任何事情来解决这个问题。

Do:做:

Better use this if running a node script for standalone purpose,如果为独立目的运行节点脚本,最好使用它,

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;

Don't:不:

instead of changing all default request process.而不是更改所有默认请求过程。

npm config set strict-ssl=false

ie, don't alter your node config, else it will apply to all your requests, by making it default config.即,不要更改您的节点配置,否则它将应用于您的所有请求,方法是使其成为默认配置。 So just use it where necessary.因此,只需在必要时使用它。

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0; process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0; Even though its not worked ...尽管它没有工作...

Not Able to Install Cypress:无法安装赛普拉斯:

SC:\Cypress> export NODE_TLS_REJECT_UNAUTHORIZED='0' node app.js export : The term 'export' is not recognized as the name of a cmdlet, function, script file, or operable program. SC:\Cypress> export NODE_TLS_REJECT_UNAUTHORIZED='0' node app.js export : 术语“export”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。 Check the spelling of the name, or if a path was included,检查名称的拼写,或者是否包含路径,
verify that the path is correct and try again.验证路径是否正确,然后重试。 At line:1 char:1在行:1 字符:1

  • export NODE_TLS_REJECT_UNAUTHORIZED='0' node app.js导出 NODE_TLS_REJECT_UNAUTHORIZED='0' 节点 app.js
  •  + CategoryInfo : ObjectNotFound: (export:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM