8

On our testing environment we are connecting to another server with SSL signed by our company. Every time connection is made nodejs throws UNABLE_TO_VERIFY_LEAF_SIGNATURE. I have found workarounds by setting rejectUnauthorized: false, but this is not aplicable in our case.

The certificates are added to /etc/ssl/certs and tested with the environment variable SSL_CERT_DIR to be either /etc/ssl anb /etc/ssl/certs, but no result.

Also, it is not preferable to add somewhere in our files the certificate and add it to every request.

tshepang
  • 12,111
  • 21
  • 91
  • 136
viktorstaikov
  • 103
  • 1
  • 7
  • Does the user running node have permission to access the certs directory? Its usually always the simple things.. – srquinn Dec 18 '13 at 13:58
  • This occures event when the user who runs NodeJS is ROOT and have all the permissions needed. – viktorstaikov Dec 18 '13 at 14:54
  • Have you seen this article? http://blog.gaeremynck.com/fixing-unable_to_verify_leaf_signature/ – srquinn Dec 18 '13 at 15:08
  • The intermediate CA certificate is also added to /etc/ssl/certs. Actualy I'm not sure NodeJS reads the certificates from the proper directory. – viktorstaikov Dec 18 '13 at 15:33

3 Answers3

6

This is because node does not use your system's CA configuration; it includes its own built-in list of acceptable CAs.

If you want a node SSL client to accept a custom CA, you have to pass the CA's certificate in the ca option.

// do something like this when your app starts up:
fs.readFile('/path/to/ca.pem', function(err, cert) {
    if (err) ...
    else certBuffer = cert;
});

// then when you make requests...
https.request({
    hostname: 'example.com',
    port: 443,
    path: '/',
    method: 'GET',
    ca: certBuffer
}, ...);
josh3736
  • 139,160
  • 33
  • 216
  • 263
3

And if you do not want to rely on node.js built-in list, and rather use your debian/ubuntu's list :

var CAs = fs.readFileSync('/etc/ssl/certs/ca-certificates.crt').toString().split(/(?=-----BEGIN CERTIFICATE-----)/);

// then when you make requests...
https.request({ ..., ca: CAs}, ...);
1

You can also add a path to your certificates in PEM file format using the NODE_EXTRA_CA_CERTS environment variable starting with node v7.3.0

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

This has the benefit of not requiring any code changes, just change the environment of your node process. Hope this helps!

Edit:

Also check out --use-openssl-ca https://nodejs.org/api/cli.html#cli_use_openssl_ca_use_bundled_ca

That's what I ended up using to solve my problem. I copied my .crt files to /usr/local/share/ca-certificates then ran sudo update-ca-certificates and then run node with --use-openssl-ca and now node finds my certificates properly.

tonyg
  • 197
  • 2
  • 13