Socket.io + SSL + self-signed CA certificate gives error when connecting
Asked Answered
D

4

12

I am running an https server using a certificate which was created using a self-signed CA certificate.

Now I want to connect Socket.io client to the Socket.io server that is attached to the https server. Unfortunately, I get an error, telling me:

Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE
    at SecurePair.<anonymous> (tls.js:1271:32)
    at SecurePair.EventEmitter.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:883:10)
    at CleartextStream.read [as _read] (tls.js:421:15)
    at CleartextStream.Readable.read (_stream_readable.js:293:10)
    at EncryptedStream.write [as _write] (tls.js:330:25)
    at doWrite (_stream_writable.js:211:10)
    at writeOrBuffer (_stream_writable.js:201:5)
    at EncryptedStream.Writable.write (_stream_writable.js:172:11)
    at write (_stream_readable.js:547:24)
    at flow (_stream_readable.js:556:7)

Basically, this error tells me that the certificate could not be verified successfully. This is due to the fact the the according CA certificate is self-signed. When using a https request, I can specify CAs whom I trust.

How can I make Socket.io connect in this case?

PS: I am running Node.js 0.10.0 and Socket.io 0.9.13.

Depute answered 12/3, 2013 at 15:48 Comment(0)
A
-17

Don’t use self signed certificates. Just don’t, some browsers give you no way of accepting them when using WebSockets. And you look like a cheap d*ck for not buying a proper cert.

From They see me pollin, they hatin (p. 23). A presentation by Arnout Kazemier (3rdEden), core team member of Socket.IO.

Autumnautumnal answered 13/3, 2013 at 14:28 Comment(7)
Okay, this answers the question of why it is not supported. Thanks for pointing this out! (Although I think his view is a bit narrow here)Depute
so how does this solve development / staging cases? Am I supposed to buy a cert for all my staging servers, Vagrant VMs and productions servers?Cotangent
Node.js 0.10 has been configured to automatically reject SSL certificates that are self signed. You can "undo" this for development by adding the following ENV variable: NODE_TLS_REJECT_UNAUTHORIZED=0 Also, yes I have a narrow view when it comes to SSL ;) But as you might have experienced, self signed certificates cause a lot of issues that can be prevented with a proper cert. As for development/staging, buy a wildcard ssl cert or edit your /etc/hosts ? ;)Ana
@Ana that's a bit strange isn't it? "To automatically reject SSL certificates that are self signed" ... I mean when someone adds a self-signed certificate to options:{ca : [self-signed.pem]} ... shouldn't that pass the check rather than failing it? From the perspective of a nodejs request being made from the client side, that is.Cymophane
Using self signed certificates can be very important in certain scenarios. It is not a given that you even access socket.io from a browser. If you want to make automated tests you should not use the real production site keys, and anyone should be able to run the tests.Baptistery
@hg — exactly! Saying "just don't use self-signed certs" seems very narrow-minded. My use case is Swift <-> nodejs+socket.io. Anyone know if things have changed on this topic in the last two years?Auraaural
I just wonder, is it that socket.io guys are too lazy, or inept to put some dev/production switch and put an end to this .. well, I'm not going to use this word here ;))Rayford
I
32

four years later but for any finding this post like me if you need to force client socket to not reject a self-signed server cert you need rejectUnauthorized: false as in const socket = require('socket.io-client')('https://192.168.0.31', { transports: ['websocket'], rejectUnauthorized: false }) from https://github.com/socketio/engine.io-client#methods

also there is now a good source for free certs so now you don't even have to be "cheap d*ck" https://letsencrypt.org/

Inwardly answered 1/11, 2017 at 20:26 Comment(3)
Just found that rejectUnauthorized by myself... Works with any websocket, not only socket.io. Wii solve issues with others certificates too (if you don't really need high protection with your ssl connection)Tutor
This slightly modified version works for me: const socket = io('https://192.168.0.31:3000', { transports: ['websocket'], rejectUnauthorized: false });Fujimoto
Would I add this piece of coding server-side or client-side on the html website?Stoddart
T
3

For socket.io 1.0 (not sure about 0.9), there are details of how to get the node client to connect to an invalid cert here: https://stackoverflow.com/a/24235426. (Thanks to @3rdEden's comment above.) I find that self-signed SSL certs can be convenient for development servers.

Trainer answered 16/6, 2014 at 1:2 Comment(0)
Y
-1

Check here on how to use self-signed certificates for Certificate Signing Request. You must specify the following to allow connections using self signed certificates:

  1. key: A string or Buffer containing the private key of the client in PEM format.
  2. cert: A string or Buffer containing the certificate key of the client in PEM format.
  3. ca: An array of strings or Buffers of trusted certificates. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

To create a self-signed certificate with the CSR, do this:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

In the client the socket should be used as

var socket = io.connect('https://localhost', {secure: true});
Yarvis answered 12/3, 2013 at 19:6 Comment(3)
This is exactly what I did, but it does not work. I always get an UNABLE_TO_VERIFY_LEAF_SIGNATURE error (I am trying to connect using socket.io-client from within Node.js, not from the browser). What I'd need was a possibility to tell Socket.io programmatically which CA certificates are fine. As it seems, such a possibility is missing. SockJS behaves the same way, and this possibility is missing there as well :-(Depute
This answer does not answer the question of how to get a valid self-signed cert to work correctly in NodeJS.Tetrasyllable
this isn't answer to the question, this is how to create self-signed certificateColston
A
-17

Don’t use self signed certificates. Just don’t, some browsers give you no way of accepting them when using WebSockets. And you look like a cheap d*ck for not buying a proper cert.

From They see me pollin, they hatin (p. 23). A presentation by Arnout Kazemier (3rdEden), core team member of Socket.IO.

Autumnautumnal answered 13/3, 2013 at 14:28 Comment(7)
Okay, this answers the question of why it is not supported. Thanks for pointing this out! (Although I think his view is a bit narrow here)Depute
so how does this solve development / staging cases? Am I supposed to buy a cert for all my staging servers, Vagrant VMs and productions servers?Cotangent
Node.js 0.10 has been configured to automatically reject SSL certificates that are self signed. You can "undo" this for development by adding the following ENV variable: NODE_TLS_REJECT_UNAUTHORIZED=0 Also, yes I have a narrow view when it comes to SSL ;) But as you might have experienced, self signed certificates cause a lot of issues that can be prevented with a proper cert. As for development/staging, buy a wildcard ssl cert or edit your /etc/hosts ? ;)Ana
@Ana that's a bit strange isn't it? "To automatically reject SSL certificates that are self signed" ... I mean when someone adds a self-signed certificate to options:{ca : [self-signed.pem]} ... shouldn't that pass the check rather than failing it? From the perspective of a nodejs request being made from the client side, that is.Cymophane
Using self signed certificates can be very important in certain scenarios. It is not a given that you even access socket.io from a browser. If you want to make automated tests you should not use the real production site keys, and anyone should be able to run the tests.Baptistery
@hg — exactly! Saying "just don't use self-signed certs" seems very narrow-minded. My use case is Swift <-> nodejs+socket.io. Anyone know if things have changed on this topic in the last two years?Auraaural
I just wonder, is it that socket.io guys are too lazy, or inept to put some dev/production switch and put an end to this .. well, I'm not going to use this word here ;))Rayford

© 2022 - 2024 — McMap. All rights reserved.