nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
108.04k stars 29.82k forks source link

[Bug] Node 10.1.0 TLS issue with ldap: Client network socket disconnected before secure TLS connection was established #21088

Closed kopax closed 6 years ago

kopax commented 6 years ago

We are experiencing issue while login to ldap in paralele.

The service we use is verdaccio v3.0.2 with an Alpine linux docker container.

We use verdaccio-ldap module for the ldap authentication part.

We are experiencing issue due to multiple transactions to the LDAP through TLS.

This happens after upgrade to node 10.1.0.

Error: Client network socket disconnected before secure TLS connection was established
    at TLSSocket.onConnectEnd (_tls_wrap.js:1092:19)
    at Object.onceWrapper (events.js:273:13)
    at TLSSocket.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1086:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
mscdex commented 6 years ago

Do you have a minimal code example (preferrably free of third party modules) that reproduces the error?

kopax commented 6 years ago

Unfortunately no, because the specs for reproducing are super computers :

Each host has 32GB RAM, 8CPU. The local bandwidth is 10GPB/S. We are not able to reproduce the bug without as much power, but if you got so, it is verry easy.

If you have that, you can use https://github.com/vesse/node-ldapauth-fork to authenticate using node to a secure OpenLap. Do that in parrallele and you'll get your error.

bnoordhuis commented 6 years ago

I'm sorry, but this bug report is not actionable if there is no way to reproduce or establish it's a bug in Node.js core (since it could be a bug in one of the modules you're using.)

I'll close this out, let me know if you have a test case that doesn't depend on third-party components.

ihabZhaika commented 6 years ago

Hey, i get the same error, i am running on node v10.1.0 and OS is linux 16.04 x64 i tried requests and axios and the native https and the first two fall on the same error and the https request never returns to reproduce try the following:

npm install axios

const axios = require('axios');

axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
  .then(response => {
    console.log(response.data.url);
    console.log(response.data.explanation);
  })
  .catch(error => {
    console.log(error);
  });

or with the https:


const https = require('https');
        https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', (resp) => {
            let data = '';

            // A chunk of data has been recieved.
            resp.on('data', (chunk) => {
                data += chunk;
            });

            // The whole response has been received. Print out the result.
            resp.on('end', () => {
                console.log(JSON.parse(data).explanation);
            });

        }).on("error", (err) => {
            console.log("Error: " + err.message);
        });
tosbaha commented 6 years ago

I also experience this issue with couple of URLs with Node v10.4.1 on macOS High Sierra Here is sample code to test.

const https = require('https');

https.get('https://supplychain.2go.com.ph', (resp) => {
    let data = '';

    resp.on('data', (chunk) => {
        data += chunk;
    });

    resp.on('end', () => {
        console.log(data);
    });

}).on("error", (err) => {
    console.log("Error: " + err.message);
});
bnoordhuis commented 6 years ago

@tosbaha That's unrelated. You can verify with curl or openssl s_client that it's an issue with that host, not Node.js. It simply closes the connection right away.

tosbaha commented 6 years ago

@bnoordhuis This web site works on Firefox,Safari,curl without any warning. It is using TLS 1.0 Is there a anyway for me to connect TLS 1.0 sites or it just won't work.

jor3l commented 6 years ago

Any way to solve this?

tosbaha commented 6 years ago

@jor3l Here are the ways to solve this

  1. Use old version of NodeJS
  2. Use other ways to connect to web site such as Puppeteer if you are doing crawling.

NodeJS thinks that it is not their responsibility to support outdated sites. There is no workaround.

birksy89 commented 6 years ago

I can't believe there isn't a way to turn off this level of strictness...

Please let me know if I'm missing something obvious

I am trying to do a simple Http GET request to a site which is using TLS 1.0

Node: v10.9.0

I get the response:

Client network socket disconnected before secure TLS connection was established

I appreciate that this is out-dated technology, but I have no power over the site I'm trying to connect to.

To people who stumble across this message, I'd suggest you check the security settings of the site you're attempting to connect to:

In Chrome capture

At time of writing @tosbaha example code (above), yields the same error: https://github.com/nodejs/node/issues/21088#issuecomment-399782127

sam-github commented 6 years ago

secure protocol to use is configurable by command line switch (only in recent master), and by secureProtocol option, see https://nodejs.org/api/all.html#https_https_request_url_options_callback, it mentions secureProtocol, and links to the docs.

birksy89 commented 6 years ago

Hi @sam-github

Thanks for the reply - Forgive my ignorance, I'm not very familiar with the platform.

I have updated my copy of Node to run v11.2.0 and using the links you provided, I came up with this - But it's still throwing the error:

const https = require('https');

const options = {
  hostname: 'https://supplychain.2go.com.ph',
  port: 443,
  path: '/',
  method: 'GET',
  secureProtocol: 'TLSv1_method'
};

const req = https.request(options, (res) => {
  console.log('statusCode:', res.statusCode);
  console.log('headers:', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });
});

req.on('error', (e) => {
  console.error(e);
});
req.end();

Please can you let me know where I'm going wrong?

Thanks again -Andrew

sam-github commented 6 years ago

That server only allows insecure TLS 1.0 protocols that have been removed in OpenSSL in node 10.x and higher. You need to set the cipher list, and you need to use a version of openssl prior to 1.1.0, which means node 8.x. Browsers are very, very lenient wrt. insecure ciphers, apparently. Chrome and Lynx connect to that website, but wget and curl do not.

Try this: nvm i 8 && node --tls-cipher-list=DES-CBC3-SHA -e "require('https').get('https://supplychain.2go.com.ph', function(res) {res.pipe(process.stdout)});"

birksy89 commented 6 years ago

Thanks again for getting back to me.

I believe the current project has dependencies which require Node v 10+

I may have to shell this bit of responsibility off to it's own environment to pursue.

Thanks again for taking the time to respond. -Andrew

qiulang commented 5 years ago

@sam-github I am using node 10 and I also keep running into this error when request to www.googleapis.com, e.g. https://www.googleapis.com/blogger/v3/blogs/2399953?key=...

But I found it won't happen to https://samples.openweathermap.org, e.g. https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22

But they both use TLS 1.2 not TLS 1.0 as @birksy89 said. Why openweathermap won't complain ?

szmarczak commented 5 years ago

I believe this may be related to the servername option:

// throws
tls.connect({host: 'httpbin.org', port: 443});

// doesn't throw
tls.connect({host: 'httpbin.org', port: 443, servername: 'httpbin.org'}); 

Maybe it throws due to incorrect servername?

Slauta commented 5 years ago

Hi,

TLS1.0 is depricated protocol. You must configure the server to work with the TLS1.2 protocol on all virtual hosts.

opensas commented 5 years ago
1. Use old version of NodeJS

can anybody tell me what is the latest node version supportin tls 1.0???

I have to access a server I cannot control, so I really need some way to connect to it.

Thanks a lot

bnoordhuis commented 5 years ago

@opensas They all do, it's just disabled by default. Start node like this: node --tls-min-v1.0 app.js

stetsmando commented 5 years ago

@bnoordhuis It appears that only v11 of node supports the --tls-min-v1.0 flag. See the docs for v11 and for v10

bnoordhuis commented 5 years ago

Sorry, I should have said: They all do, it's just disabled by default in some versions. I asked about back-porting the switches in #27432.

saurabh14nov commented 5 years ago

hi @bnoordhuis / @sam-github , when will this fix be released and as part of which node version?

sam-github commented 5 years ago

There are no bugs here to fix. TLS1.0 is supported even in master, check the unit tests: https://github.com/nodejs/node/blob/master/test/parallel/test-tls-min-max-version.js#L99

It is also supported in older versions. how to enable it depends on the version, more recent node has CLI options to change the defaults, older node has to use explicit TLS config, see the tests. EDIT: or docs for the relevant version

freedom19920918 commented 4 years ago

I just use axios instead of Http to send the request. That resolved my problem.

freedom19920918 commented 4 years ago

I can't believe there isn't a way to turn off this level of strictness...

Please let me know if I'm missing something obvious

I am trying to do a simple Http GET request to a site which is using TLS 1.0

Node: v10.9.0

I get the response:

Client network socket disconnected before secure TLS connection was established

I appreciate that this is out-dated technology, but I have no power over the site I'm trying to connect to.

To people who stumble across this message, I'd suggest you check the security settings of the site you're attempting to connect to:

In Chrome capture

At time of writing @tosbaha example code (above), yields the same error: #21088 (comment)

use axios instead of http to send the request can reolve this problem

sam-github commented 4 years ago

Its not particularly secure, but if absolutely required, --tls-min-v1.0 (and other related options, see docs) can be used to enable insecure TLS features.