Page MenuHomePhabricator

HTTPS request to the MW API fails: "unable to get local issuer certificate"
Closed, ResolvedPublic

Description

As noted in https://github.com/wikimedia/service-template-node/pull/120, when the node.js service template is running in a Docker container created from the production variant of the following Blubberfile, external HTTPS requests fail with an SSL error.

version: v3
base: docker-registry.wikimedia.org/nodejs-slim
lives:
  in: /srv/service
runs:
  environment: { APP_BASE_PATH: /srv/service }

variants:
  build:
    base: docker-registry.wikimedia.org/nodejs-devel
    apt: { packages: [git, build-essential, python-pkgconfig] }
    node: { requirements: [package.json] }
    runs: { environment: { LINK: g++ } }
  development:
    includes: [build]
    entrypoint: [node, server.js]
  test:
    includes: [build]
    entrypoint: [npm, test]
  prep:
    includes: [build]
    node: { env: production }
  production:
    copies: prep
    node: { env: production }
    entrypoint: [node, server.js]

Here is the full trace:

Error: unable to get local issuer certificate
    at Error (native)
    at TLSSocket.<anonymous> (_tls_wrap.js:1092:38)
    at emitNone (events.js:86:13)
    at TLSSocket.emit (events.js:185:7)
    at TLSSocket._finishInit (_tls_wrap.js:610:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:440:38)

Interestingly, if the curl or wget package is installed, the error does not occur.

Event Timeline

This corresponds to the openssl error X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY.

X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate
the issuer certificate of a locally looked up certificate could not be found. This normally means the list of trusted certificates is not complete.

https://github.com/nodejs/node/blob/8c9aaacb333a0223243eda9b3551dbf26fdb260a/deps/openssl/openssl/doc/man3/X509_STORE_CTX_get_error.pod

I am guessing this does not occur with curl or wget because both packages include ca-certificates. So depending on how we want to play it, we could either include that where we want to be able to make external HTTPS requests, or just give the base image the cert(s) it needs to connect to WMF-controlled domains.

Yup, this is due to the missing ca-cetrificates package. It really depends on a per-service basis: if and only if the service is meant to communicate with external sources, then the package should be installed. In the case of the service template, I think we should install it only for the development and test images, but not the production one in an effort to lock down services using the blubber file as a template.

Mholloway claimed this task.