Install from private repo fails using cafile and strict-ssl when encountering repository dependency


(Christoph Werner) #1

What I Wanted to Do

I wanted to configure a project via .npmrc so it installs dependencies from a private repository instead of the public npm registry.

In order to do so, i added a few lines of configuration to my .npmrc:

_auth = *********
registry = https://internal/artifactory/api/npm/npm/
cafile = /path/to/cert-path.pem
always-auth = true
strict-ssl = true

The private artifactory instance has an npm feed/repository, which is available at https://internal/artifactory/api/npm/npm/. It also has an SSL certificate provided by GlobalSign. In order to get strict-ssl = true working, i had to export all certificates on the certification path up to the GlobalSign CA root certificate as .pem files, concatenate them to a single file the order from leaf to root and use that as the cafile.

Now, when running npm install without any repository dependencies in my dependency tree, everything is splendid. However, once npm install encounters a repository dependency, things break.

What Happened Instead

When encountering a repository dependency in the dependency tree, npm install fails.

In our case, https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update from the lint-staged@8.0.4 dependencies is the culprit. When running npm i with this in the dependency tree, install fails:

npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm ERR! errno UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm ERR! request to https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update failed, reason: unable to get local issuer certificate

logfile shows this:

7093 verbose stack FetchError: request to https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update failed, reason: unable to get local issuer certificate
7093 verbose stack     at ClientRequest.req.on.err (/usr/lib/node_modules/npm/node_modules/node-fetch-npm/src/index.js:68:14)
7093 verbose stack     at ClientRequest.emit (events.js:182:13)
7093 verbose stack     at TLSSocket.socketErrorListener (_http_client.js:382:9)
7093 verbose stack     at TLSSocket.emit (events.js:182:13)
7093 verbose stack     at emitErrorNT (internal/streams/destroy.js:82:8)
7093 verbose stack     at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
7093 verbose stack     at process._tickCallback (internal/process/next_tick.js:63:19)
7094 verbose cwd /path/to/website
7095 verbose Linux 4.4.0-43-Microsoft
7096 verbose argv "/usr/bin/node" "/usr/bin/npm" "i"
7097 verbose node v10.2.1
7098 verbose npm  v6.2.0
7099 error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
7100 error errno UNABLE_TO_GET_ISSUER_CERT_LOCALLY
7101 error request to https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update failed, reason: unable to get local issuer certificate
7102 verbose exit [ 1, true ]

Reproduction Steps

Have a private feed, point npm to it via .npmrc, set strict-ssl to true, provide the certificate chain as cafile, run npm i with repository dependencies (in our case: from GitHub) in the dependency tree.

Platform Info

$ npm --versions
{ 'paderbornjs-website': '1.0.0',
  npm: '6.2.0',
  ares: '1.14.0',
  cldr: '33.0',
  http_parser: '2.8.0',
  icu: '61.1',
  modules: '64',
  napi: '3',
  nghttp2: '1.29.0',
  node: '10.2.1',
  openssl: '1.1.0h',
  tz: '2018c',
  unicode: '10.0',
  uv: '1.20.3',
  v8: '6.6.346.32-node.8',
  zlib: '1.2.11' }
$ node -p process.platform
linux