Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: self signed certificate Node 12 app on Heroku

I have an app on heroku. I upgraded its version from node 6 to node 12. After upgrading to 12 on local environment it started giving me follow error.

Error: self signed certificate

On the local environment, I ignored this error by using the following command.

NODE_TLS_REJECT_UNAUTHORIZED=0

But this is not an option for me on production environment. I am using heroku automated certificate management for my SSL needs and it is working perfectly uptill Node version 12.

Ideally it should not give that error because on the production server I have proper certificate setup by using heroku automated certificate management

My certificates are valid but I am seeing Self signed certificate error in my logs. Your help is appreciated.

Stack trace of the error is as follows.

Error: self signed certificate (Most recent call first)
at TLSSocket.onConnectSecure (_tls_wrap.js line 1501 col 33)
at TLSSocket.emit (events.js line 315 col 19)
at TLSSocket.EventEmitter.emit (domain.js line 483 col 11)
at TLSSocket._finishInit (_tls_wrap.js line 936 col 7)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js line 710 col 11)
at Socket.ondata (internal/js_stream_socket.js line 72 col 21)
at Socket.emit (events.js line 315 col 19)
at Socket.EventEmitter.emit (domain.js line 483 col 11)
at addChunk (_stream_readable.js line 295 col 11)
at readableAddChunk (_stream_readable.js line 271 col 8)
like image 766
AMBasra Avatar asked Oct 06 '20 11:10

AMBasra


1 Answers

First of all this error occurs for outbound connections, not inbound connections. And it occurred because of a code change made my node team when they released version 12. It was fine in version 11. Let me share the details. The issue is that Node.js (no longer?) sends a SNI record by default. You can work around it like this:

const options = {
  port: 993,
  host: 'imap.gmail.com',
  servername: 'imap.gmail.com',  // SNI
};
tls.connect(options, () => { /* ... */ });

It won't validate unless you pass -servername imap.gmail.com.

(GMail helpfully sends back a certificate with Issuer: OU = "No SNI provided; please fix your client.", CN = invalid2.invalid ^^)

Source for above information https://github.com/nodejs/node/issues/28167

Note : Nothing changed in OpenSSL but in node.

Node team has added a warning for it. https://github.com/nodejs/node/commit/b8ea47162d84ade96698cb45a0de5c0dd9959251

`tls.connect()` returns a [`tls.TLSSocket`][] object.

Unlike the `https` API, `tls.connect()` does not enable the
SNI (Server Name Indication) extension by default, which may cause some
servers to return an incorrect certificate or reject the connection
altogether. To enable SNI, set the `servername` option in addition
to `host`.

The following illustrates a client for the echo server example from
[`tls.createServer()`][]:
like image 110
AMBasra Avatar answered Sep 23 '22 07:09

AMBasra