docker-node icon indicating copy to clipboard operation
docker-node copied to clipboard

EPROTO Error when connecting to a server using https

Open milad2golnia opened this issue 3 years ago • 0 comments

Environment

  • Platform:
$ uname -a
Linux vote 5.4.0-26-generic #30-Ubuntu SMP Mon Apr 20 16:58:30 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
  • Docker Version:
$ docker --version
Docker version 20.10.7, build 20.10.7-0ubuntu5~20.04.2
  • Node.js Version:
node --version
v10.19.0
  • Image Tag: I tested all node:alpine, node:stretch, node:slim and node:17

Expected Behavior

I developed a Node.js program which works fine on my system but behaves strange inside docker container! In this program I'm trying to connect to a server using https. On my system It always connects successfully but inside docker container it just can connect first time and then exits with error.

NOTE: Inside docker container, If it was never connecting then it made sense but now it's really strange that it can connect one time but not more.

The expected output should looks like to what I see on my system:

$ npm run development

> [email protected] development /home/sysadmin/test
> export NODE_ENV=development; export DEBUG=app:*; node server.js

  app::main-Interface Server started listening on port : 8086 +0ms
  app::main-Interface Data received! +5s
  app::main-Interface First operation succeed +3ms
  app::main-Interface Data received! +6s
  app::main-Interface First operation succeed +1ms
  app::main-Interface Data received! +11s
  app::main-Interface First operation succeed +0ms
^C

As you can see it connects to the server three times without any problem and works fine.

Current Behavior

It just connects one time and then it throws an error:

> [email protected] development
> export NODE_ENV=development; export DEBUG=app:*; node server.js

2022-02-26T05:58:48.550Z app::main-Interface Server started listening on port : 3000
2022-02-26T05:58:49.818Z app::main-Interface Data received!
2022-02-26T05:58:49.824Z app::main-Interface First operation succeed
node:events:498
      throw er; // Unhandled 'error' event
      ^

Error: write EPROTO 80B9D562707F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:../deps/openssl/openssl/ssl/statem/extensions.c:907:

    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:94:16)
Emitted 'error' event on ClientRequest instance at:
    at TLSSocket.socketErrorListener (node:_http_client:442:9)
    at TLSSocket.emit (node:events:520:28)
    at emitErrorNT (node:internal/streams/destroy:164:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -71,
  code: 'EPROTO',
  syscall: 'write'
}

Node.js v17.4.0

Steps to Reproduce

I simplified the code as below(content of server.js):

const express = require('express');
const debug = require('debug');
const https = require('https')
const log = debug('app::main-Interface');
const args = process.argv.slice(2);
const app = express(); 
const port = args[0] || process.env.port || 3000;


function sleep(toSleep){
    return new Promise((resolve, reject)=>{
        setTimeout(() => {
            resolve(true)
        }, toSleep);
    })
}

async function initializeRemotely(lengthOfOrder = 4096){
    return new Promise((resolve, reject)=>{

    https.get(`https://2ton.com.au/getprimes/random/${lengthOfOrder}`, 
                (res)=>{
                    res.on('data', async (data)=>{
                        log('Data received!')
                        resolve(true);
                    })
                }
    )
    })
}

async function DEBUG(){
    let breakTime = 5000;
    while(true){
        await initializeRemotely()
        log('First operation succeed')
        await sleep(breakTime);
        breakTime *= 2;
    }
}

app.listen(port, async () => {
    log(`Server started listening on port : ${port}`);
    //schedulerPool.MSRulesWatcher(config.get('Times.schedulers'));
    DEBUG()
});

To run this program you need to install following packages:

npm i debug express

After installing those, you can run the program as below to see Expected Behavior:

$ DEBUG=app::* node server.js

Then create the ./deploy/Dockerfile as below:

FROM node:alpine

EXPOSE 3000
WORKDIR /interface

COPY package.json .
RUN npm install

COPY . .

And also create the docker-compose.yml file with following contents:

version: "3"

services:
  interface:
    image: interface
    container_name: interface
    build:
      context: .
      dockerfile: ./deploy/Dockerfile
    entrypoint: ["npm", "run", "development"]

Also the development script inside package.json file is:

...
"scripts": {
    "development": "export NODE_ENV=development; export DEBUG=app:*; node server.js"
  },
...

Now to reproduce error, just build and run the container:

$ sudo docker-compose build
Building interface
Step 1/6 : FROM node:alpine
 ---> 025c3cbb849f
Step 2/6 : EXPOSE 3000
 ---> Using cache
 ---> 01c2a8f41688
Step 3/6 : WORKDIR /interface
 ---> Using cache
 ---> a8323f19dd04
Step 4/6 : COPY package.json .
 ---> Using cache
 ---> bccbb39147bd
Step 5/6 : RUN npm install
 ---> Using cache
 ---> 573aa7b45092
Step 6/6 : COPY . .
 ---> Using cache
 ---> a2f41c692811
Successfully built a2f41c692811
Successfully tagged interface:latest

$ sudo docker-compose up -d
Starting interface ... done

Finally if you look at logs, you can see the problem:

$ sudo docker logs interface
> [email protected] development
> export NODE_ENV=development; export DEBUG=app:*; node server.js

2022-02-26T05:58:48.550Z app::main-Interface Server started listening on port : 3000
2022-02-26T05:58:49.818Z app::main-Interface Data received!
2022-02-26T05:58:49.824Z app::main-Interface First operation succeed
node:events:498
      throw er; // Unhandled 'error' event
      ^

Error: write EPROTO 80B9D562707F0000:error:0A000152:SSL routines:final_renegotiate:unsafe legacy renegotiation disabled:../deps/openssl/openssl/ssl/statem/extensions.c:907:

    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:94:16)
Emitted 'error' event on ClientRequest instance at:
    at TLSSocket.socketErrorListener (node:_http_client:442:9)
    at TLSSocket.emit (node:events:520:28)
    at emitErrorNT (node:internal/streams/destroy:164:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -71,
  code: 'EPROTO',
  syscall: 'write'
}

Node.js v17.4.0

milad2golnia avatar Feb 26 '22 08:02 milad2golnia