Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't connect from ws client to ws server: TLS handshake failure #1227

Closed
1 task done
Hativ opened this issue Nov 1, 2017 · 6 comments
Closed
1 task done

Can't connect from ws client to ws server: TLS handshake failure #1227

Hativ opened this issue Nov 1, 2017 · 6 comments

Comments

@Hativ
Copy link
Contributor

Hativ commented Nov 1, 2017

  • I've searched for any related issues and avoided creating a duplicate issue.

Description

If I try to connect with the attached ws client to the attached ws server I get the following error:

events.js:193
      throw er; // Unhandled 'error' event
      ^

Error: write EPROTO 140695292278592:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:772:

    at _errnoException (util.js:1031:13)
    at WriteWrap.afterWrite [as oncomplete] (net.js:873:14)

But Chrome and Firefox can connect to the ws server, so the problem must be in the ws client.

Reproducible in:

version: 3.2.0
Node.js version(s): 9.0.0
OS version(s): elementary OS 0.4.1 Loki, based on Ubuntu 16.04.3 LTS

Steps to reproduce:

  1. Run attached websocket server
  2. Run attached websocket client

Expected result:

Connecting to websocket without error.

Actual result:

Not connecting to websocket, producing an error.

Attachments:

Debug output:

hativ@pc:~# NODE_DEBUG=net,tls,crypto node index.js 
NET 1149: pipe false null
NET 1149: connect: find host websocket.example.com
NET 1149: connect: dns options { family: undefined, hints: 32 }
NET 1149: _read
NET 1149: _read wait for connection
NET 1149: afterConnect
TLS 1149: start
NET 1149: _read
NET 1149: Socket._read readStart
NET 1149: afterWrite -71
NET 1149: write failure { Error: write EPROTO 140067809924928:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:772:

    at _errnoException (util.js:1031:13)
    at WriteWrap.afterWrite [as oncomplete] (net.js:873:14) errno: 'EPROTO', code: 'EPROTO', syscall: 'write' }
NET 1149: destroy
NET 1149: close
NET 1149: close handle
events.js:193
      throw er; // Unhandled 'error' event
      ^

Error: write EPROTO 140067809924928:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:772:

    at _errnoException (util.js:1031:13)
    at WriteWrap.afterWrite [as oncomplete] (net.js:873:14)

Websocket Server:

  const webserver = https.createServer({
    cert: fs.readFileSync('path/to/cert'),
    ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384',
    ecdhCurve: 'secp521r1:secp384r1',
    honorCipherOrder: true,
    key: fs.readFileSync('path/to/key'),
    secureProtocol: 'TLSv1_2_method',
  }).listen(443);

  const websocketServer = new ws.Server({
    server: webserver,
  });

  websocketServer.on('connection', (websocket) => {
    websocket.on('close', () => {
      // Handle close
    });

    websocket.on('message', (request) => {
      // Handle message
    });
  });

Websocket client:

const WebSocket = require('ws');

const ws = new WebSocket('wss://websocket.example.com');

ws.on('open', function open() {
  console.log('connected');
});

ws.on('message', function incoming(data) {
  console.log(data);
});

ws.on('close', function close(error) {
  console.log('closed', error);
});
@lpinca
Copy link
Member

lpinca commented Nov 1, 2017

What happens if you try to connect to your webserver using the https module? For example:

const https = require('https');

const request = https.get({
  hostname: 'websocket.example.com',
  headers: {
    upgrade: 'websocket',
    connection: 'Upgrade',
    'Sec-WebSocket-Key': 'rfeGe1izPRq2JyonWunAQw==',
    'Sec-WebSocket-Version': 13
  }
});

request.on('error', (err) => console.error(err));
request.on('upgrade', () => console.log('upgraded'));

@Hativ
Copy link
Contributor Author

Hativ commented Nov 1, 2017

Does not work too.

Debug output:

NET 4912: pipe false null
NET 4912: connect: find host websocket.example.com
NET 4912: connect: dns options { family: undefined, hints: 32 }
NET 4912: _read
NET 4912: _read wait for connection
NET 4912: afterConnect
TLS 4912: start
NET 4912: _read
NET 4912: Socket._read readStart
NET 4912: afterWrite -71
NET 4912: write failure { Error: write EPROTO 140504342898496:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:772:

    at _errnoException (util.js:1031:13)
    at WriteWrap.afterWrite [as oncomplete] (net.js:873:14) errno: 'EPROTO', code: 'EPROTO', syscall: 'write' }
NET 4912: destroy
NET 4912: close
NET 4912: close handle
{ Error: write EPROTO 140504342898496:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:772:

    at _errnoException (util.js:1031:13)
    at WriteWrap.afterWrite [as oncomplete] (net.js:873:14) errno: 'EPROTO', code: 'EPROTO', syscall: 'write' }
NET 4912: emit close

Should I open an issue at node repo or do you have an idea?

@lpinca
Copy link
Member

lpinca commented Nov 1, 2017

Yes, I think it makes sense to open an issue in the node repo.

@Hativ
Copy link
Contributor Author

Hativ commented Nov 1, 2017

I got it working with the https module:

const https = require('https');

const request = https.get({
  hostname: 'api.fortytwo.cloud.local',
  headers: {
    upgrade: 'websocket',
    connection: 'Upgrade',
    'Sec-WebSocket-Key': 'rfeGe1izPRq2JyonWunAQw==',
    'Sec-WebSocket-Version': 13
  },
  rejectUnauthorized: false, // <-- For testing with self signed certificate
  ecdhCurve: 'auto' // <-- Does the trick
});

request.on('error', (err) => console.error(err));
request.on('upgrade', () => console.log('upgraded'));

Unfortunately WebSocket does not support the ecdhCurve setting from tls.createSecureContext.

Should it be added to ws or is there another option?

Anyway ecdhCurve's default value should be auto, I will suggest this in the node repo.

@lpinca
Copy link
Member

lpinca commented Nov 1, 2017

Should it be added to ws or is there another option?

Yes, it should. Do you want to open a PR?

@Hativ
Copy link
Contributor Author

Hativ commented Nov 1, 2017

I will try to implement this.

lpinca pushed a commit that referenced this issue Nov 1, 2017
Support ecdhCurve option as discussed in #1227.
lpinca pushed a commit that referenced this issue Nov 1, 2017
Support ecdhCurve option as discussed in #1227.
@lpinca lpinca closed this as completed Nov 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants