New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nodejs 4 introduces UNABLE_TO_GET_ISSUER_CERT_LOCALLY error for users behind company firewalls #3742

Closed
greenmountains opened this Issue Nov 10, 2015 · 25 comments

Comments

Projects
None yet
@greenmountains
Copy link

greenmountains commented Nov 10, 2015

Nodejs 4 appears to introduce an UNABLE_TO_GET_ISSUER_CERT_LOCALLY error for users behind a company firewall.

Npm install & other commands no longer work after update from Nodejs 0.12 to Nodejs 4 or 5. After discussion on the npm forums, current thought is that this may be an issue in Node rather than Npm.

See npm/npm#9580.
Also
npm/npm#10125
npm/npm#9906

This issue is preventing our team from upgrading to Nodejs 4 or 5. Any suggestions welcome.

Thanks

@bricss

This comment has been minimized.

Copy link

bricss commented Nov 10, 2015

npm config set strict-ssl false

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented Nov 10, 2015

If you get that error, it's most likely an issue with your proxy. The error itself just means that a TLS certificate in the chain is signed by an unknown CA, presumably the cert your proxy uses.

v4.x and v5.x are more strict than v0.12 is but most people would consider that a good thing.

@greenmountains

This comment has been minimized.

Copy link

greenmountains commented Nov 10, 2015

@bricss, Yup, tried that & also always-auth=false. Doesn't help but thanks for the suggestion.

@mscdex mscdex added the tls label Nov 10, 2015

@greenmountains

This comment has been minimized.

Copy link

greenmountains commented Nov 11, 2015

@bnoordhius, yes, starting in v4.x my understanding is that we'll need to configure the cafile to include our company certificate chain. I've done that using npm like this:

npm config set cafile="C:\\mycacert.pem" 

mycacert.pem is a file containing multiple PEM formated X509 certificates in this form:

-----BEGIN CERTIFICATE-----
MIIEczCCA1ugAwIBAgIBADANBgkqhkiG9w0BAQQFAD..AkGA1UEBhMCR0Ix
EzARBgNVBAgTClNvbWUtU3RhdGUxFDASBgNVBAoTC0..0EgTHRkMTcwNQYD
etc...
It8una2gY4l2O//on88r5IWJlm1L0oA8e4fR2yrBHX..adsGeFKkyNrwGi/
7vQMfXdGsRrXNGRGnX+vWDZ3/zWI0joDtCkNnqEpVn..HoX
-----END CERTIFICATE-----

I also tried setting an array of CAs following the documentation here: https://docs.npmjs.com/misc/config.

With the log level turned up to silly level.

npm install -ddd

this is the first error I get

gyp verb created nodedir C:\Users\myname\.node-gyp\4.2.2
gyp http GET https://nodejs.org/download/release/v4.2.2/node-v4.2.2-headers.tar.gz
gyp WARN install got an error, rolling back install
gyp verb command remove [ '4.2.2' ]
gyp verb remove using node-gyp dir: C:\Users\myname\.node-gyp
gyp verb remove removing target version: 4.2.2
gyp verb remove removing development files for version: 4.2.2
gyp ERR! configure error 
gyp ERR! stack Error: unable to get local issuer certificate
gyp ERR! stack     at Error (native)
gyp ERR! stack     at TLSSocket.<anonymous> (_tls_wrap.js:1003:38)
gyp ERR! stack     at emitNone (events.js:67:13)
gyp ERR! stack     at TLSSocket.emit (events.js:166:7)
gyp ERR! stack     at TLSSocket._finishInit (_tls_wrap.js:570:8)
gyp ERR! System Windows_NT 6.1.7601
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"

My guess is that either our root or intermediate certificate isn't getting passed to openSSL. I don't see any errors about a load failing or invalid format. I modified npm\lib\config\load-cafile.js to confirm it was being called & loading my cafile. beyond that I haven't dug into the code.

More error output would helpful. Is there a way to view debug statements from the openssl module being used by node?

Thanks

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented Nov 11, 2015

gyp http GET https://nodejs.org/download/release/v4.2.2/node-v4.2.2-headers.tar.gz

That's because node-gyp doesn't use npm's proxy settings, or at least not the cafile settings. A pull request to node-gyp honoring process.env.npm_config_cafile will probably get accepted.

Alternatively, if you accept the risks, env NODE_TLS_REJECT_UNAUTHORIZED npm whatever will sidestep CA verification altogether.

@greenmountains

This comment has been minimized.

Copy link

greenmountains commented Nov 11, 2015

@bnoordhuis thanks for the info! We are talking through our options.

@voltagex

This comment has been minimized.

Copy link

voltagex commented Dec 8, 2015

process.env.npm_config_cafile

@bnoordhuis do you know if this was ever raised?

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented Dec 8, 2015

@voltagex I don't believe so.

@greenmountains

This comment has been minimized.

Copy link

greenmountains commented Dec 8, 2015

we are still interested in a fix for this. We are still using Nodejs v0.12

@mschnee

This comment has been minimized.

Copy link

mschnee commented Dec 15, 2015

PR to node-gyp: nodejs/node-gyp#844

Mentioning the below for all the people trying to 'npm install' other things and getting similar errors, and google is turning this issue as a result:

FYI, depending on what you're trying to install, it's possible that a module itself is being bad about ssl/cafiles. electron-prebuilt is a great example. It has an install.js script that sets up a download of a file, and then it doesn't check for any configuration. Even worse, electron-download checks for a "strictSSL" option, but electrion-prebuilt doesn't pass one.

TLDR: your problems with self-signed certificates may not be related to npm or node-gyp: but using npm may be how you experience that error.

@drmcclelland

This comment has been minimized.

Copy link

drmcclelland commented Feb 22, 2016

Thank you @bricss! Worked like a charm

@jasnell

This comment has been minimized.

Copy link
Member

jasnell commented Apr 4, 2016

is there reason to keep this one open?

@tristian2

This comment has been minimized.

Copy link

tristian2 commented Apr 4, 2016

@bricss, yes that work for me as well.. cheers

@superbob

This comment has been minimized.

Copy link

superbob commented Apr 6, 2016

I'm behind a corporate HTTPS proxy.
I have the issue even when I add the corporate root CA certificates to the system (in /etc/pki/tls/certs/ca-bundle.crt on Fedora 23).

npm update -g
npm ERR! Linux 3.16.7-35-default
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "update" "-g"
npm ERR! node v4.4.2
npm ERR! npm  v2.15.0
npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY

npm ERR! unable to get local issuer certificate
npm ERR! 
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /npm-debug.log

To pass behond this issue I have to set configuration to use the cafile
npm config set cafile=/etc/pki/tls/certs/ca-bundle.crt -g
After that, the UNABLE_TO_GET_ISSUER_CERT_LOCALLY vanishes, but I have another problem:

npm update -g
npm ERR! Linux 3.16.7-35-default
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "update" "-g"
npm ERR! node v4.4.2
npm ERR! npm  v2.15.0

npm ERR! Hostname/IP doesn't match certificate's altnames: "Host: registry.npmjs.org. is not in the cert's altnames: DNS:a.sni.fastly.net, DNS:a.sni.global-ssl.fastly.net"
npm ERR! 
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /npm-debug.log

The only workaround is strict-ssl=false. But that's not a pretty solution...

  1. I'm not sure cafile configuration resolved the first issue or added another one.
    If it solved the first issue, it means that npm doesn't read root certificates installed in the system. Maybe it should be changed. wget and curl read these certificates just fine.
  2. The second issue is really strange, I googled only one similar issue, and there is no solution proposed.
@parky128

This comment has been minimized.

Copy link

parky128 commented Apr 14, 2016

Just adding my experiences with this issue.

I was hitting this problem when trying to install the dependencies for the angular2 quickstart. I am also behind a proxy and started by trying to set the proxy settings and strict-ssl=false in my .npmrc file but with no success after doing so.

The error I saw was being generated during a postinstall 'typings install` command:

> typings install

typings ERR! message Unable to read typings for "es6-shim". You should check the
 entry paths in "es6-shim.d.ts" are up to date
typings ERR! caused by Unable to connect to "https://raw.githubusercontent.com/D
efinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/es6-shim
/es6-shim.d.ts"
typings ERR! caused by unable to get local issuer certificate

I ended up having to add .typingsrc file at the same location as my .npmrc file with the following lines added:

proxy=http://proxy.address:proxy.port
rejectUnauthorized=false

This got me past the unable to get local issuer certificate error and continued with the install fine.

This may not be relevant, but thought I'd add here as it may be of use to someone, took me a few days to figure out!

@bnoordhuis

This comment has been minimized.

Copy link
Member

bnoordhuis commented Apr 28, 2016

Closing, this should be fixed by the new --cafile flag to node-gyp that was released in node.js v4.4.3 and v5.10.0. If you set cafile in your .npmrc, node-gyp should automatically pick it up when invoked through npm.

@bnoordhuis bnoordhuis closed this Apr 28, 2016

@oscarryz

This comment has been minimized.

Copy link

oscarryz commented Jun 14, 2016

Just adding a remark here, to set the cafile use:

npm config set cafile=/Path/to/your/file.pem

Where the .pem file content is similar to this (plain text with BEGIN/END certificate marks and base64 content)

To generate the .pem file from a valid .crt file the following can be used:

openssl x509 -inform der -in /Path/to/the.crt -out /Path/to/the/file.pem

I spend a fair amount of time figuring out that.

@RogerGMartins

This comment has been minimized.

Copy link

RogerGMartins commented Jul 28, 2016

npm config set cafile="C:\mycacert.pem"
worked for me, thanks @greenmountains

We use artificatory, so my proxy looks like :
proxy=null
https-proxy=proxy url
http-prox= same proxy url
strict-ssl=false
registry=artifactory url

this would time me out so i changed them to:
proxy=proxy url
https-proxy=proxy url
http-prox= same proxy url
strict-ssl=false
cafile=C:\cafile.pem

hence, going through normal regestry, adding a normal proxy and certificate file.
Not the best since, i should be going through the private registry but at least i was able to install the package i wanted.

@cmacdonnacha

This comment has been minimized.

Copy link

cmacdonnacha commented Oct 26, 2016

This also works: npm config set registry http://registry.npmjs.org/

@gazzadownunder

This comment has been minimized.

Copy link

gazzadownunder commented Oct 9, 2017

We have a secure internet gateway that performs SSL inspection, using the option below to specify the root certificate used by the secure gateway resolved the issue

npm config set ca=

@cltsao

This comment has been minimized.

Copy link

cltsao commented Nov 7, 2017

Node.js 7.3.0 added NODE_EXTRA_CA_CERTS environment variable for you to pass the CA certificate file. It is safer than disabling certificate verification using NODE_TLS_REJECT_UNAUTHORIZED.

$ export NODE_EXTRA_CA_CERTS=[your CA certificate file path]

This solution works with me for node-gyp. npm config set cafile does not work.

@tcjcodes

This comment has been minimized.

Copy link

tcjcodes commented Feb 23, 2018

I'm still seeing this because of a node-gyp dependency and my company uses self-signed certificates.

My .npmrc file:

strict-ssl=false
cafile=C:/Tools/mycerts.pem
registry=https://registry.npmjs.org/
proxy=companyproxy
http-proxy=companyproxy
https-proxy=companyproxy
NODE_TLS_REJECT_UNAUTHORIZED=0

I've also tried various permutations with these, with npm and with yarn:
ca= vs NODE_EXTRA_CA_CERTS=C:/Tools/mycerts.pem vs cafile=C:/Tools/mycerts.pem
with and without NODE_TLS_REJECT_UNAUTHORIZED

Below magically worked once with yarn and then I removed 1 npm package later and it started failing again and I haven't gotten it to work since (maybe an update by the network team???)

strict-ssl=false
NODE_EXTRA_CA_CERTS=C:/Tools/mycerts.pem
registry=https://registry.npmjs.org/
proxy=companyproxy
http-proxy=companyproxy
https-proxy=companyproxy

Info:

  • Win 10 x64
  • node v8.9.1
  • npm 5.5.1
  • yarn 1.3.2
  • Using nvm and node_modules is stored under C:\Tools

Below is my stack trace if anyone can help...

error C:\Development\projects\myproject\node_modules\sharp: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments:
Directory: C:\Development\projects\myproject\node_modules\sharp
Output:
C:\Development\projects\myproject\node_modules\sharp>if not defined npm_config_node_gyp (node "C:\Tools\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild )  else (node "" rebuild

 )
gyp info it worked if it ends with ok
gyp info using node-gyp@3.6.2
gyp info using node@8.9.1 | win32 | x64
gyp info spawn C:\Users\username\.windows-build-tools\python27\python.exe
gyp info spawn args [ 'C:\\Tools\\nvm\\v8.9.1\\node_modules\\npm\\node_modules\\node-gyp\\gyp\\gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'msvs',
gyp info spawn args   '-G',
gyp info spawn args   'msvs_version=2015',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Development\\projects\\myproject\\node_modules\\sharp\\build\\config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Tools\\nvm\\v8.9.1\\node_modules\\npm\\node_modules\\node-gyp\\addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\username\\.node-gyp\\8.9.1\\include\\node\\common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=C:\\Users\\username\\.node-gyp\\8.9.1',
gyp info spawn args   '-Dnode_gyp_dir=C:\\Tools\\nvm\\v8.9.1\\node_modules\\npm\\node_modules\\node-gyp',
gyp info spawn args   '-Dnode_lib_file=C:\\Users\\username\\.node-gyp\\8.9.1\\<(target_arch)\\node.lib',
gyp info spawn args   '-Dmodule_root_dir=C:\\Development\\projects\\myproject\\node_modules\\sharp',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'C:\\Development\\projects\\myproject\\node_modules\\sharp\\build',
gyp info spawn args   '-Goutput_dir=.' ]
sharp: https://github.com/lovell/sharp-libvips/releases/download/v8.6.1/libvips-8.6.1-win32-x64.tar.gz download failed: unable to get local issuer certificate
gyp: Call to 'node -e "require('./binding').download_vips()"' returned exit status 1 while in binding.gyp. while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (C:\Tools\nvm\v8.9.1\node_modules\npm\node_modules\node-gyp\lib\configure.js:336:16)
gyp ERR! stack     at emitTwo (events.js:126:13)
gyp ERR! stack     at ChildProcess.emit (events.js:214:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
gyp ERR! System Windows_NT 10.0.15063
gyp ERR! command "C:\\Tools\\nodejs\\node.exe" "C:\\Tools\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Development\projects\myproject\node_modules\sharp

I've also tried downloading that package's source code into my company's internal GitLab and configuring my env to look there, but that still fails with the same unable to get local issuer certificate error :(

@ronaldomoreira

This comment has been minimized.

Copy link

ronaldomoreira commented May 21, 2018

I had the same problem on windows 10.

open windows powerShell and enter the following command:
npm config set registry http://registry.npmjs.org/

Then you can use: npm install [your package] normally.

@ygizhitsa

This comment has been minimized.

Copy link

ygizhitsa commented Dec 4, 2018

I use following on Windows
SET NODE_TLS_REJECT_UNAUTHORIZED=0
Could not figure out why cafile doesn't work

@03vishalrawal

This comment has been minimized.

Copy link

03vishalrawal commented Jan 16, 2019

I have found a solution as "npm config set registry http://registry.npmjs.org/ "

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment