Pact-js: Unable to publish to a pact broker that uses as self-signed cert

Created on 20 Jul 2018  路  11Comments  路  Source: pact-foundation/pact-js

Software versions

Expected behaviour

When the pact broker uses a self-signed certificate, I should still be able to call it by setting

export NODE_TLS_REJECT_UNAUTHORIZED=0

or

export NODE_EXTRA_CA_CERTS=pactbroker.crt

where pactbroker.crt contains the certificate used by the pact broker.

Actual behaviour

By setting either of those environment variables I can call the pact broker using request-promise but when I call publishPacts I get

Error: Error making request - OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=error: certificate verify failed

Steps to reproduce

  • Have some pact files available to publish.
  • Set the options of publishPacts to use those files.
  • Set the pactBroker option of publishPacts to any site with a self-signed certificate, such as https://self-signed.badssl.com/.
  • Call publishPacts.
Awaiting feedback Triage

Most helpful comment

What worked for me:

To publish with pact-node or pact-js do the following:

Download your certificate chain that your broker is using. If pulled right out of chrome you will most likely have .cer files.

For example:

  • root.cer
  • intermediate.cer
  • ssl_certificate.cer

Convert those .cer files to .crt files by doing:

  • $ openssl x509 -inform DER -in root.cer -out root.crt
  • $ openssl x509 -inform DER -in intermediate.cer -out intermediate.crt
  • $ openssl x509 -inform DER -in ssl_certificate.cer -out ssl_certificate.crt

Then for ruby to recognize it properly it must be a bundle, so let's bundle these together similar to the ca-bundle.crt

  • $ cat root.crt intermediate.crt ssl_certificate.crt > ca-bundle.crt

Now within your javascript you must set the SSL_CERT_FILE that the standalone mentions. Make sure the certPath variable resolves to the correct path:

const path = require("path");
const publisher = require("@pact-foundation/pact-node");

const certPath = path.resolve(__dirname, "../ca-bundle.crt");
console.log(certPath);
process.env.SSL_CERT_FILE = certPath;

const opts = {
  providerBaseUrl: "/",
  pactFilesOrDirs: [path.resolve(process.cwd(), "pacts")],
  pactBroker: "<your_https_broker_url>",
  consumerVersion: "1.0.0"
};

publisher.publishPacts(opts).then(() => console.log("Pacts successfully published"));

All 11 comments

Thanks for the report.

Check out this thread: https://github.com/pact-foundation/pact-node/issues/93

We spawn a Ruby process under the hood which also needs to know about this.

If the trick there works for you, I'll get it added to our docs

This should be fixed soon, when we move the pact fetching code into the ruby. Or at least, you'll only have to specify one of the cert vars. Maybe the js code can set the appropriate ruby env vars if the node ones are set?

@chriswatrous did you manage to get it work?

I've got the same issue using the latest version of pact

  • "@pact-foundation/pact": "~6.0.1"

You'll need to set the appropriate environment variables for publishing https://github.com/pact-foundation/pact-ruby-standalone/releases#pact-broker-client

@rev42 have you tried any of the approaches in this thread: pact-foundation/pact-node#93 ? What have you tried so far?

Yeah, I read pact-foundation/pact-node#93 and it gave us some hints.

We came to an ugly solution but it works and it's fine with us for now.

First we disabled SSL from node side:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

Then we had to comment 2 lines related to SSL_CERT_FILE from node_modules/@pact-foundation/pact-node/standalone/linux-x64-1.54.3/lib/bin/ruby_environment file in order to bypass the message "certificate verify failed" from http.rb

That's clearly not what the best way to handle it. The easy way would have been to get a valid certificate but our partner didn't want to make the move.

You should be able to just download the certificate from the server and set it as the trusted cert. https://superuser.com/questions/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

What worked for me:

To publish with pact-node or pact-js do the following:

Download your certificate chain that your broker is using. If pulled right out of chrome you will most likely have .cer files.

For example:

  • root.cer
  • intermediate.cer
  • ssl_certificate.cer

Convert those .cer files to .crt files by doing:

  • $ openssl x509 -inform DER -in root.cer -out root.crt
  • $ openssl x509 -inform DER -in intermediate.cer -out intermediate.crt
  • $ openssl x509 -inform DER -in ssl_certificate.cer -out ssl_certificate.crt

Then for ruby to recognize it properly it must be a bundle, so let's bundle these together similar to the ca-bundle.crt

  • $ cat root.crt intermediate.crt ssl_certificate.crt > ca-bundle.crt

Now within your javascript you must set the SSL_CERT_FILE that the standalone mentions. Make sure the certPath variable resolves to the correct path:

const path = require("path");
const publisher = require("@pact-foundation/pact-node");

const certPath = path.resolve(__dirname, "../ca-bundle.crt");
console.log(certPath);
process.env.SSL_CERT_FILE = certPath;

const opts = {
  providerBaseUrl: "/",
  pactFilesOrDirs: [path.resolve(process.cwd(), "pacts")],
  pactBroker: "<your_https_broker_url>",
  consumerVersion: "1.0.0"
};

publisher.publishPacts(opts).then(() => console.log("Pacts successfully published"));

Thanks @mstelz. As you've discovered, the hard work is always extracting and prepping the full certificate chain. Appreciate your response here though!

@mstelz thank you for the solution it worked for me locally in my js project but when i tried publishing the pact files onto the pact broker as a part of the build it is again failing for me
Error making request - OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=error: certificate verify failed
do you have any idea related to this..

Was this page helpful?
0 / 5 - 0 ratings