Skip to content

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

Description

@Hativ
  • 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);
});

Activity

  1. lpinca commented on Nov 1, 2017

    @lpinca
    Member

    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'));
  2. Hativ commented on Nov 1, 2017

    @Hativ
    ContributorAuthor

    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?

  3. lpinca commented on Nov 1, 2017

    @lpinca
    Member

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

  4. Hativ commented on Nov 1, 2017

    @Hativ
    ContributorAuthor

    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.

  5. lpinca commented on Nov 1, 2017

    @lpinca
    Member

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

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

  6. Hativ commented on Nov 1, 2017

    @Hativ
    ContributorAuthor

    I will try to implement this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions