GregSantulli GregSantulli - 10 months ago 113
iOS Question

iOS Safari fails to connect to secure websocket, but works on desktop

I have a node.js https server using non-self-signed certificates. I believe they are from godaddy, not sure though. My employer only provided me with key and cert files.


var fs = require('fs')
, server = require('https').createServer({
key: fs.readFileSync( __dirname + "/key.pem" ),
cert: fs.readFileSync(__dirname + "/cert.pem" )
, WebSocketServer = require('ws').Server
, webSocketServer = new WebSocketServer({
server: server,
, port = 8080;

server.listen(port, function(){ console.log('Listening on ' + server.address().port) });


var webSocket = new WebSocket('wss://');

This code works as expected on desktop chrome, safari, and firefox. The client is able to connect to the the secure websocket. However, trying it on iOS 9.3.1 Safari gives me the following error:

The operation couldn't be completed.(OSStatus error -9807.)

OSStatus showed me that this is caused by an invalid certificate chain. Unfortunately, here is where my knowledge of SSL begins to fade. After some additional googling, I tried multiple combinations of the following options accepted by

secureProtocol: "SSLv3_method",
rejectUnauthorized: false,
honorCipherOrder: true,
requestCert: false

None of them have worked thus far. I have also seen the
option (certificate authority) but not only do I not know where I would find this file, all examples online suggest that this is only used with self-signed certs?

Any help is greatly appreciated, thanks!

Answer Source

Somehow putting nginx in front of the node app seemed to fix the issue. I was able to get the following configuration working pretty quickly (taken from this tutorial):

server {

    listen 443;
    server_name *;
    ssl    on;
    ssl_certificate    /etc/ssl/cert.pem;
    ssl_certificate_key    /etc/ssl/key.pem;

    location / {
        proxy_pass https://pr.iv.ate.ip:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;

Still a big ¯\_(ツ)_/¯ as to why it doesn't work with just node, but then again my knowledge of ssl (and sometimes server configuration in general) is still somewhat limited.