3

I have an API running with express using https. For testing, I've been using tinycert.org for the certificates, which work fine on my machine.

I'm using docker to package up the app, and docker-machine with docker-compose to run it on a digital ocean server.

When I try to connect with Chrome, I get ERR_SSL_VERSION_OR_CIPHER_MISMATCH. When running this with curl, I get a handshake failure: curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect.

I tried to debug with Wireshark's SSL dissector, but it hasn't given me much more info: I can see the "Client Hello" and then the next frame is "Handshake Failure (40)".

I considered that maybe node on the docker container has no available ciphers, but it has a huge list, so it can't be that. I'm unsure as to what's going on and how to remedy it.

EDIT

Here's my createServer() block:

let app = express();
let httpsOpts = {
    key:  fs.readFileSync("./secure/key.pem"),
    cert: fs.readFileSync("./secure/cert.pem")
};
let port = 8080;
https.createServer(httpsOpts, app).listen(port);
GTF
  • 8,031
  • 5
  • 36
  • 59
  • Hi there! Can you paste your https.createServer() line? – mikemaccana Oct 31 '15 at 09:23
  • Incidentally, I tried running my entire setup in a VM on my laptop, and it works there too. – GTF Oct 31 '15 at 11:17
  • I wonder if it could be related to this http://stackoverflow.com/questions/21767003/ssl-handshake-fails-after-clienthello – GTF Oct 31 '15 at 11:18
  • Hey, did you ever figure this out? I am experiencing the exact same thing, thanks – Jared Wilkin Nov 11 '16 at 17:48
  • @JaredWilkin I'm afraid I did not. Not sure exactly what I did that fixed it in the end but I haven't seen this problem for a while. Sorry not to be of more use! – GTF Nov 16 '16 at 16:44
  • Has anyone figured this out by now? I get the same error with this one-liner in node v8.2.1: `require('https').createServer().listen(8097)` – Michael Hewson Sep 19 '17 at 17:36

1 Answers1

0

I've had this problem for a really long time too, there's a weird fix:

  1. Don't convert your certs to .pem; it works fine as .crt and .key files.

  2. Add ca: fs.readFileSync("path to CA bundle file") to the https options.
    It looks like your server is only sending the top certificate and the CA bundle file has the intermediate and root certificates which you'll need for non-browser use.

  3. IMPORTANT! Reinstall or update node to the latest version.
    You can use sudo apt-get upgrade if you're on Linux (it may take a while).

  4. Re-download your certificate or get a new one.

If you are acting as your own certificate authority it could be not recognizing / trusting the certificate, so try testing your site on ssllabs.com.

If you're using the http2 API try adding allowHTTP1: true to the options.

grg
  • 5,023
  • 3
  • 34
  • 50
KCGD
  • 675
  • 6
  • 10