dominictarr / npmd

MIT License
450 stars 37 forks source link

SELF_SIGNED_CERT_IN_CHAIN when using private hosted npm registry #78

Open dylang opened 10 years ago

dylang commented 10 years ago
/usr/local/lib/node_modules/npmd/index.js:95
    if(err) throw err
                  ^
Error: SELF_SIGNED_CERT_IN_CHAIN
    at SecurePair.<anonymous> (tls.js:1367:32)
    at SecurePair.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:979:10)
    at CleartextStream.read [as _read] (tls.js:471:13)
    at CleartextStream.Readable.read (_stream_readable.js:340:10)
    at EncryptedStream.write [as _write] (tls.js:368:25)
    at doWrite (_stream_writable.js:225:10)
    at writeOrBuffer (_stream_writable.js:215:5)
    at EncryptedStream.Writable.write (_stream_writable.js:182:11)
    at write (_stream_readable.js:601:24)

Our registry is behind a firewall so I don't have a way to provide a test case but I'm happy to try out a work in progress branch. FWIW the classic npm client works with our registry, as have tools that use the classic npm apis such as npm-check.

dominictarr commented 10 years ago

oh do you have a certificate configured for your npm? can you post the output of npm config list --long? it will block out any passwords

dylang commented 10 years ago

I've removed a couple things.

; cli configs
long = true
registry = "https://npm.aws.** removed  **/"
user-agent = "npm/1.4.21 node/v0.10.30 darwin x64"

; userconfig /Users/dgreene/.npmrc
always-auth = true
ca = ["-----BEGIN CERTIFICATE-----\r\n ** removed ** \r\n-----END CERTIFICATE-----"]
cache-min = 300
email = "dylan@** removed **"
loglevel = "warn"
min-cache = "600"
prefix = "/usr/local"
registry = "https://npm.aws.** removed  **/"
strict-ssl = true
username = "dylang"

; globalconfig /usr/local/etc/npmrc
package-config:foo = "boo"

; default values
; always-auth = false (overridden)
bin-links = true
browser = null
; ca = null (overridden)
cache = "/Users/dgreene/.npm"
cache-lock-retries = 10
cache-lock-stale = 60000
cache-lock-wait = 10000
cache-max = null
; cache-min = 10 (overridden)
cafile = undefined
cert = null
color = true
depth = null
description = true
dev = false
editor = "/usr/local/bin/subl -w"
; email = "" (overridden)
engine-strict = false
fetch-retries = 2
fetch-retry-factor = 10
fetch-retry-maxtimeout = 60000
fetch-retry-mintimeout = 10000
force = false
git = "git"
git-tag-version = true
global = false
globalconfig = "/usr/local/etc/npmrc"
globalignorefile = "/usr/local/etc/npmignore"
group = 20
heading = "npm"
https-proxy = null
ignore-scripts = false
init-module = "/Users/dgreene/.npm-init.js"
init.author.email = ""
init.author.name = ""
init.author.url = ""
init.license = "ISC"
json = false
key = null
link = false
local-address = undefined
loglevel = "warn"
; long = false (overridden)
message = "%s"
node-version = "0.10.30"
npat = false
onload-script = null
optional = true
parseable = false
prefix = "/usr/local"
production = false
proprietary-attribs = true
proxy = null
rebuild-bundle = true
; registry = "https://registry.npmjs.org/" (overridden)
rollback = true
save = false
save-bundle = false
save-dev = false
save-exact = false
save-optional = false
save-prefix = "^"
searchexclude = null
searchopts = ""
searchsort = "name"
shell = "/bin/zsh"
shrinkwrap = true
sign-git-tag = false
spin = true
strict-ssl = true
tag = "latest"
tmp = "/var/folders/hl/c611mdq92fd6q6_rf_mj33cr0000gp/T"
umask = 18
unicode = true
unsafe-perm = true
usage = false
user = 502
; user-agent = "npm/{npm-version} node/{node-version} {platform} {arch}" (overridden)
userconfig = "/Users/dgreene/.npmrc"
; username = "" (overridden)
version = false
versions = false
viewer = "man"
dominictarr commented 10 years ago

Okay cool, no problem. Aha so you have a ca configured.

So the problem is that there are a few places that npmd does http, and needs to check if it's to the registry, and then needs to use the configured CA and possibly auth. here: https://github.com/dominictarr/npmd-resolve/blob/master/online.js#L68-L70 and here: https://github.com/dominictarr/npmd-cache/blob/master/index.js#L62-L64

possibly those uses could be modularized somehow, since it's actually a little more complicated, because there are other places that npm can load modules for and sometimes they can be authed. Or it would be very useful to beable to have authed urls.

@novemberborn is also working on a PR that enables private github repos, which is related to this. https://github.com/dominictarr/npmd-resolve/pull/7

I'm thinking a pattern where you take a URL, check if it matches a certain domain, and then add whatever headers are ready to auth for that domain. hmm. I guess sometimes authing will require an async operation, such as requesting a new token, so maybe the plugin should handle the entire request? or maybe it should just callback when it's ready with the headers?

dylang commented 10 years ago

My coworker just reminded me that we are not using a self-signed cert. "We are using a cert signed by our own root (for revocation, multiple server certs, etc.)." Probably doesn't change your theories for solving this.

dominictarr commented 10 years ago

right - so putting the expected ca in the config is probably still the solution to this. Unfortunately I have a fairly thin bandwidth to work on this... if you want to put in a PR that will be very encouraging though ;)

dylang commented 10 years ago

I'm closing because we migrated off https and I no longer have this problem.

dominictarr commented 10 years ago

reopening this because the issue is not actually resolved, and someone else might have this problem

tomek-he-him commented 9 years ago

:+1:

Self-signed certificates and NPM are a real pain in the ass. We install some dependencies directly over HTTPS. The only solution that works with npm for us is npm install --strict-ssl=false.

I wanted to give npmd a try. And here’s what I get:

.../npmd/index.js:95
    if(err) throw err
                  ^
Error: DEPTH_ZERO_SELF_SIGNED_CERT
    at SecurePair.<anonymous> (tls.js:1381:32)
    at SecurePair.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:980:10)
    at CleartextStream.read [as _read] (tls.js:472:13)
    at CleartextStream.Readable.read (_stream_readable.js:341:10)
    at EncryptedStream.write [as _write] (tls.js:369:25)
    at doWrite (_stream_writable.js:226:10)
    at writeOrBuffer (_stream_writable.js:216:5)
    at EncryptedStream.Writable.write (_stream_writable.js:183:11)
    at write (_stream_readable.js:602:24)
dominictarr commented 9 years ago

Oh hmm... okay so the ideal solution would be to be able to configure a cert to use for a particular domain, right?

I would be happy to merge a PR that allowed you to set certs, and to answer any questions necessary.

tomek-he-him commented 9 years ago

to be able to configure a cert to use for a particular domain

Yeah, so we’ve tried with npm – and after a several hours’ fight we gave up – and decided to pull our HTTPS modules with the option --strict-ssl=false.

@dylang was that why you migrated off HTTPS?

How about forwarding any options to npm? So you could just do npmd install --strict-ssl=false.

dominictarr commented 9 years ago

well the strict-ssl option is actually a thing that is being passed to request. npmd doesn't depend on npm.

dylang commented 9 years ago

@tomekwi We migrated to http because of (from what we can remember) couch issues with our cert and trust store and we didn't care to spend time trying to resolve because our registry is inside our firewall.