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

SSL/TLS failure with requests and EPROTO response #1323

Closed
Martii opened this issue Feb 9, 2018 · 9 comments
Closed

SSL/TLS failure with requests and EPROTO response #1323

Martii opened this issue Feb 9, 2018 · 9 comments
Labels
bug You've guessed it... this means a bug is reported. CODE Some other Code related issue and it should clearly describe what it is affecting in a comment. enhancement Something we do have implemented already but needs improvement upon to the best of knowledge. REMOTE Remote system or service. stability Important to operations.

Comments

@Martii
Copy link
Member

Martii commented Feb 9, 2018

The following error has shown up just recently and is preventing some script uploads and the online editor from accepting scripts with a server trip:

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

Error: write EPROTO 140596207068992:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:1500:SSL alert number 40
140596207068992:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:../deps/openssl/openssl/ssl/s3_pkt.c:659:

    at _errnoException (util.js:1022:11)
    at WriteWrap.afterWrite [as oncomplete] (net.js:867:14)

I'm in the process of rebuilding the current LTS node to see if that will help. That particular file is part of node and is beyond our control other than a rebuild to see if a VPS update broke the build.

  • Restored SSL keys from November 2017 (primary) to be sure file corruption had not occurred. No change.
  • Reinit project deps e.g. rm -Rf node_modules and npm install. No change
  • New temporary project clone created. No Change
  • Rolling back node to earlier version with nvm did not help.
  • Rolling back to an older project clone did not help.
  • Rebuilding node... No change
  • Remove nvm completely... pending retest of system node recompile... .bashrc is new location instead of .profile.... difference in reinstallation merits removal, perhaps permanently.
  • Test manual removal of

    OpenUserJS.org/app.js

    Lines 247 to 270 in 8d90bfa

    ciphers: [
    'ECDHE-RSA-AES128-GCM-SHA256',
    'ECDHE-ECDSA-AES128-GCM-SHA256',
    'ECDHE-RSA-AES256-GCM-SHA384',
    'ECDHE-ECDSA-AES256-GCM-SHA384',
    'DHE-RSA-AES128-GCM-SHA256',
    'ECDHE-RSA-AES128-SHA256',
    'DHE-RSA-AES128-SHA256',
    'ECDHE-RSA-AES256-SHA384',
    'DHE-RSA-AES256-SHA384',
    'ECDHE-RSA-AES256-SHA256',
    'DHE-RSA-AES256-SHA256',
    'HIGH',
    '!aNULL',
    '!eNULL',
    '!EXPORT',
    '!DES',
    '!RC4',
    '!MD5',
    '!PSK',
    '!SRP',
    '!CAMELLIA'
    ].join(':'),
    honorCipherOrder: true
    and use native node encryption handling. No change
  • Test non-secure mode... FAIL... lovely... browser issue always kicking in https. Will followup with that later.

Outside ref(s):

@Martii Martii added expedite Immediate and on the front burner. stability Important to operations. REMOTE Remote system or service. labels Feb 9, 2018
@Martii Martii self-assigned this Feb 9, 2018
@Martii
Copy link
Member Author

Martii commented Feb 9, 2018

Cause Identified: Definitely node throwing an untrapped error and dealing with TLS.

Workaround: Remove icon request since https://confluence.bredex.de/images/icons/profilepics/default.png does this consistently so far.

Target TLS/SSL session:

$ openssl s_client -connect "confluence.bredex.de:443" 
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = afdr.bredex.de
verify return:1
---
Certificate chain
 0 s:/CN=afdr.bredex.de
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE/zCCA+egAwIBAgISA4K7jQHehScWPprM5bRYQ718MA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzEyMTEwNjI3MTFaFw0x
ODAzMTEwNjI3MTFaMBkxFzAVBgNVBAMTDmFmZHIuYnJlZGV4LmRlMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArbX7qdtcb7kx+NspPjraBqQ/tn71UeSE
BqJM2sHlO1jsk1pBHvGReVER28hRK3SLfSaQXy5pQ8Dgnrc7zbgwCcw+2NrWam2M
+srntNcBDjMbohBo0SWVlygOzqfT9+QHw9H4FPsDiP9N5mMK86TvAwc+AC1gYR7J
VqvO3TMBpFVngUpPe6LneUqgNtWczMAfFWudeJbsu5rNEqqs6kqYmxg5AkNx2QoK
W+r+USX5lpickRLTb2wWj1ASaS/WA8559leQztbKuooGgFXoTyBeNn0PB45+dQ7h
ShsaXDmrBHopna1hDF2iWLWaylBsftAtJFkpFdu0zp5s5hfkGMIS1wIDAQABo4IC
DjCCAgowDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTSYq3iPsu1ohfY62spLrPeeK6S
+TAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcBAQRj
MGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlwdC5v
cmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5v
cmcvMBkGA1UdEQQSMBCCDmFmZHIuYnJlZGV4LmRlMIH+BgNVHSAEgfYwgfMwCAYG
Z4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggrBgEFBQcCARYaaHR0cDovL2Nw
cy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwICMIGeDIGbVGhpcyBDZXJ0aWZp
Y2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBieSBSZWx5aW5nIFBhcnRpZXMg
YW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBDZXJ0aWZpY2F0ZSBQb2xp
Y3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlwdC5vcmcvcmVwb3NpdG9yeS8w
DQYJKoZIhvcNAQELBQADggEBAJxS6NuOMj4Y9d1yWGecbd8ZjgEyjnNCC/rWdxnz
EOHXlX/JWcUS6seiQpXPu56lWboVNzUOjc8oaUDkRTLnVHIE04nwtW3EfFpEUf02
pF4xeDfkAwWAjaUdccAjrBiP4E/ae3lwAKIFVgHcwBMtmzYsgd++0ukl9a9nqF/P
U5dAa2h90AVmjbWrBNYxZ/qcxqe7Fx4FmbClKeMObc8U1qeKEnY2St7r3f1J5Z6I
HrmEFMfCSlzQ4IlMgcFnxddN5TOw/G8QD9BFVz6UkckU9u3NaSK6IU9MaSfkI175
jzqcXTe+m+JJXp7N1O5HSa2EgvzRZZ71dwZtjO4ki3fU4hQ=
-----END CERTIFICATE-----
subject=/CN=afdr.bredex.de
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2972 bytes and written 432 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: C7041494A8345EE28B4F015B48E782BCA85F09864F55490C24AF95B30B9FA4F5
    Session-ID-ctx: 
    Master-Key: 7021B763AB0CD1DEC596E90B6A70626AD028C35F0CC410E0DF9D245C3F8F1F972EBDC68C1397A0EB1A6B707616530233
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1518162720
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

Additional session failure using request on dev:

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

RangeError: Invalid status code: EPROTO
    at ServerResponse.writeHead (_http_server.js:190:11)
    at ServerResponse.writeHead (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse._implicitHeader (_http_server.js:181:8)
    at ServerResponse.res.write (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/express-minify/index.js:88:14)
    at MuStream.ondata (internal/streams/legacy.js:16:26)
    at emitOne (events.js:116:13)
    at MuStream.emit (events.js:211:7)
    at next (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:49:16)
    at _render (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:96:3)
    at Object.render (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:15:10)
    at Immediate._onImmediate (~/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu.js:196:16)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)

Note: Since this routine needs to take a nap for a while... If I see an @icon larger than it is supposed to be the account is eligible for termination under the TOS. Just thought I'd do a reject instead of a termination. :\

@Martii Martii added the tracking upstream Waiting, watching, wanting. label Feb 9, 2018
@Martii
Copy link
Member Author

Martii commented Feb 9, 2018

@Martii Martii changed the title SSL failure - Site offline for a bit SSL/TLS failure with requests and EPROTO response Feb 9, 2018
Martii added a commit to Martii/OpenUserJS.org that referenced this issue Feb 9, 2018
* Apparently there is a long standing issue with EPROTO and this. Will need to dive in way deep and wait until it is fixed.
* Project error trapping yielded no results
* Altered to use *request* and same issue as denoted on the issue
* Prevents the server trip from *node* builtin and other mentioned package.

Applies to OpenUserJS#1323 and post OpenUserJS#1303
Martii added a commit that referenced this issue Feb 9, 2018
#1324)

* Apparently there is a long standing issue with EPROTO and this. Will need to dive in way deep and wait until it is fixed.
* Project error trapping yielded no results
* Altered to use *request* and same issue as denoted on the issue
* Prevents the server trip from *node* builtin and other mentioned package.

Applies to #1323 and post #1303

Auto-merge
@Martii
Copy link
Member Author

Martii commented Feb 9, 2018

If anyone has any suggestions on how to trap the TLS issue it would be appreciated... otherwise I'll keep looking when I have a moment.

@sizzlemctwizzle
Copy link
Member

sizzlemctwizzle commented Feb 9, 2018

Without looking at any code, outgoing requests can fail for any number of reasons. From what the user said about requiring intranet authencation to access the icon, a failure is to be expected. The only problem was that an uncaught exception was generated as a result, and that cannot be allowed to happen under any circumstance. Any error that could possibly result from a request to an external server should be caught and logically treated as if we recieved a 404. I don't know if a TLS error requires anything more than wrapping https.get in a try-catch (guessing at the solution based on the stack trace), but a connection error is a connection error regardless of why.

EDIT: You need to use https.get(options, fn).on('error', fn)

@Martii
Copy link
Member Author

Martii commented Feb 9, 2018

You need to use https.get(options, fn).on('error', fn)

We are (were) I think at https://github.com/OpenUserJS/OpenUserJS.org/pull/1324/files#diff-b755ddbc6b2edf964c5586d742e3afdaL1488 . This didn't trap it at all.

The simple request at https://github.com/OpenUserJS/OpenUserJS.org/pull/1324/files#diff-b755ddbc6b2edf964c5586d742e3afdaL1459
The data stream at https://github.com/OpenUserJS/OpenUserJS.org/pull/1324/files#diff-b755ddbc6b2edf964c5586d742e3afdaL1461
The end stream at https://github.com/OpenUserJS/OpenUserJS.org/pull/1324/files#diff-b755ddbc6b2edf964c5586d742e3afdaL1468
The error trap at https://github.com/OpenUserJS/OpenUserJS.org/pull/1324/files#diff-b755ddbc6b2edf964c5586d742e3afdaL1488

I'm trying a tls.connect (assuming this it the right path) to see if I can trap a double call to that problematic server using a lower level class function from node... not sure if this will work and is a 2nd chore.

@Martii
Copy link
Member Author

Martii commented Feb 10, 2018

@sizzlemctwizzle

Yeah you came up with the same solution as @6-8-axnw1bom81v5xa3nh48c did now that I look into this way deep however we still get this on development:

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

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: EPROTO
    at ServerResponse.writeHead (_http_server.js:197:11)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse._implicitHeader (_http_server.js:188:8)
    at ServerResponse.res.write (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/express-minify/index.js:88:14)
    at MuStream.ondata (internal/streams/legacy.js:16:26)
    at MuStream.emit (events.js:160:13)
    at next (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:49:16)
    at _render (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:96:3)
    at Object.render (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:15:10)
    at Immediate.<anonymous> (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu.js:196:16)
    at runCallback (timers.js:756:18)
    at tryOnImmediate (timers.js:717:5)
    at processImmediate [as _immediateCallback] (timers.js:697:5)

using:

          fn = /^http:/.test(icon) ? http : https;
          fn.get(URL.parse(icon), function (aRes) {
            var chunks = [];
            aRes.on('data', function (aChunk) {
              var buf = null;
              chunks.push(aChunk);
              buf = Buffer.concat(chunks);
              if (buf.length > 3048) { // NOTE: KiB
                aRes.destroy();
              }
            }).on('end', function () {
              buffer = Buffer.concat(chunks);
              try {
                dimensions = sizeOf(buffer);
              } catch (aE) {
                aInnerCallback(new statusError({
                  message: '`@icon` ' + aE.message,
                  code: aE.code
                }));
                return;
              }

              if (!acceptedImage(dimensions)) {
                aInnerCallback(new statusError({
                  message: '`@icon` unsupported file type or dimensions are too large.',
                  code: 400
                }), null);
              } else {
                aInnerCallback(null);
              }
            }).on('error', function (aErr) { // Trap on response... also tested removed
              aInnerCallback(aErr);
            });
          }).on('error', function (aErr) { // Trap on request
              aInnerCallback(aErr);
          });

Martii added a commit to Martii/OpenUserJS.org that referenced this issue Feb 10, 2018
* Do some of the checks that don't pertain to TLS issue
* Fix with additional `on('error',...` for the request instead of response. My bad although still doesn't appear to work with native `https.get` and `https.request`.

Applies to OpenUserJS#1323
Martii added a commit that referenced this issue Feb 10, 2018
* Do some of the checks that don't pertain to TLS issue
* Fix with additional `on('error',...` for the request instead of response. My bad although still doesn't appear to work with native `https.get` and `https.request`.

Applies to #1323 

Auto-merge
@Martii
Copy link
Member Author

Martii commented Feb 10, 2018

Martii added a commit that referenced this issue Feb 10, 2018
* Double check that dimensions exist in case the dep fails
* Prevents a server trip on malformed value or missing target with no data with:

``` sh-session
RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: ERR_INDEX_OUT_OF_RANGE
```

Post #1303 and very loosely related to #1323

Auto-merge
@Martii
Copy link
Member Author

Martii commented Feb 10, 2018

Additional related error using a bogus domain with http://s33333333333333333333333.amazonaws.com/uso_ss/icon/13701/large.png :

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

RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: ENOTFOUND
    at ServerResponse.writeHead (_http_server.js:197:11)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse.writeHead (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/on-headers/index.js:55:19)
    at ServerResponse._implicitHeader (_http_server.js:188:8)
    at ServerResponse.res.write (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/express-minify/index.js:88:14)
    at MuStream.ondata (internal/streams/legacy.js:16:26)
    at MuStream.emit (events.js:160:13)
    at next (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:49:16)
    at _render (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:96:3)
    at Object.render (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu/renderer.js:15:10)
    at Immediate.<anonymous> (/home/user/repo/git/OpenUserJS.org/martii/OpenUserJS.org/node_modules/mu2/lib/mu.js:196:16)
    at runCallback (timers.js:756:18)
    at tryOnImmediate (timers.js:717:5)
    at processImmediate [as _immediateCallback] (timers.js:697:5)

This means that http as well needs to continue to be resuspended since the .on('error',... (current code point here) isn't picking up on this up either.

Martii added a commit to Martii/OpenUserJS.org that referenced this issue Feb 10, 2018
* Bogus domain causes untrapped `RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: ENOTFOUND`

Applies to OpenUserJS#1323
Martii added a commit that referenced this issue Feb 10, 2018
* Bogus domain causes untrapped `RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: ENOTFOUND`

Applies to #1323

Auto-merge
Martii added a commit to Martii/OpenUserJS.org that referenced this issue Feb 10, 2018
* `statusCode` is a string in the case of *node* failures... change `statusCodePage` code to accommodate this.
* revert suspension again... hopefully the last time

Applies to OpenUserJS#1323 and OpenUserJS#37
Martii added a commit that referenced this issue Feb 10, 2018
* `statusCode` is a string in the case of *node* failures... change `statusCodePage` code to accommodate this.
* revert suspension again... hopefully the last time

Applies to #1323 and #37

Auto-merge
@Martii
Copy link
Member Author

Martii commented Feb 10, 2018

Closing for now... will reopen if the server trips again.

@Martii Martii closed this as completed Feb 10, 2018
@Martii Martii removed their assignment Feb 10, 2018
@Martii Martii added bug You've guessed it... this means a bug is reported. enhancement Something we do have implemented already but needs improvement upon to the best of knowledge. CODE Some other Code related issue and it should clearly describe what it is affecting in a comment. and removed expedite Immediate and on the front burner. tracking upstream Waiting, watching, wanting. labels Feb 10, 2018
@OpenUserJS OpenUserJS locked as resolved and limited conversation to collaborators Apr 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug You've guessed it... this means a bug is reported. CODE Some other Code related issue and it should clearly describe what it is affecting in a comment. enhancement Something we do have implemented already but needs improvement upon to the best of knowledge. REMOTE Remote system or service. stability Important to operations.
Development

No branches or pull requests

2 participants