QuorumDMS / ftp-srv

📮 Modern FTP Server
MIT License
387 stars 116 forks source link

Unable to find valid port #312

Open almgwary opened 2 years ago

almgwary commented 2 years ago

Hi ftp-srv team

I need your support here ASAP

we have this error messageUnable to find valid port after uploading many files,

Code


const resolverFunction = (address) => {
   const ip = address;
   const networks = getNetworks();
   for (const network in networks) {
       if (new Netmask(network).contains(ip)) {
           return networks[network];
       }
   }
   return "127.0.0.1";
}

const ftpServer = new FtpSrv({
    url: `ftp://0.0.0.0:3020`,
    pasv_url: `ftp://0.0.0.0`,
    pasv_url: resolverFunction,
    tls: false,
    pasv_min:21000,
    pasv_max:21010,
    anonymous: true,
    greeting: ["Hello", "Hello"]
}, './ftp');

 ftpServer.on('login', async(data, resolve, reject) => {
    const {username, password} = data;
        const ftpAccount = await models.user.getByUsername(username)
        if (ftpAccount.username === username && ftpAccount.password === password) {
            data.connection.on('STOR', (error, filePath) => {
              // doing other stuff here
            });
            const root =`./ftp`;
            if (!fs.existsSync(root)){
                fs.mkdirSync(root, { recursive: true });
            } 
            return resolve({ root});
        } else {
            reject({  err: 'no' });
        }

});

Error after uploading multible files server side

2022-06-08T18:01:46.385587466Z {"name":"ftp-srv", "pid":19,"id":"83589fe0-502e-4c78-b162-ed30bbaa36dd",
"ip":"***.***.***.9","directive":"PASV","level":50,
"err":{"message":"Unable to find valid port",
"name":"ConnectorError","stack":"ConnectorError: Unable to find valid port\n    at tryGetPort (/node_modules/ftp-srv/src/helpers/find-port.js:28:16)\n    at Server.<anonymous> (/node_modules/ftp-srv/src/helpers/find-port.js:37:11)\n    at Object.onceWrapper (events.js:421:26)\n    at Server.emit (events.js:314:20)\n    at emitErrorNT (net.js:1343:8)\n    at processTicksAndRejections (internal/process/task_queues.js:84:21)","code":400},
"msg":"Unable to find valid port","time":"2022-06-08T18:01:46.385Z","v":0}

Error client side

Command:    PASV
Response:   400 Unable to find valid port
Command:    PORT 192,168,0,159,50,254
Response:   500 The given address is not yours
Error:  Failed to retrieve directory listing

image

almgwary commented 2 years ago

Hi @matt-forster, @trs appreciate your support ASAP

matt-forster commented 2 years ago

@almgwary im on vacation with limited access. Have you checked port exhaustion for the PASV communication?

matt-forster commented 2 years ago

The ports aren't being closed, obviously. Have you checked your own logic to make sure they aren't being held? We've seen this before, so it could be a long running bug as well.

almgwary commented 2 years ago

Here is my code

const { FtpSrv} = require('ftp-srv');
const fs = require('fs');
const hostname = '0.0.0.0';
const ftpPort = process.env.FTP_PORT;
const { networkInterfaces } = require('os');
const { Netmask } = require('netmask');

const nets = networkInterfaces();
function getNetworks() {
   let networks = {};
   for (const name of Object.keys(nets)) {
       for (const net of nets[name]) {
           if (net.family === 'IPv4' && !net.internal) {
               networks[net.address + "/24"] = net.address
           }
       }
   }
   return networks;
}

const resolverFunction = (address) => {
   const ip = address;
   console.log(chalk.bgGreen(`FTP resolverFunction address:${address }`));
   const networks = getNetworks();
   for (const network in networks) {
       if (new Netmask(network).contains(ip)) {
           return networks[network];
       }
   }
   return "127.0.0.1";
}

const ftpServer = new FtpSrv({
    url: `ftp://${hostname}:${ftpPort}`,
   // pasv_url: `ftp://0.0.0.0`,
    pasv_url: resolverFunction,
    tls: false,
    pasv_min:21000,
    pasv_max:21010,
    anonymous: true,
    greeting: ["Hello", "hi"]
}, './ftp');

ftpServer.on('login', async(data, resolve, reject) => {

    const {username, password, connection} = data;

        if ('*****' === username && '****' === password) {

            data.connection.on('STOR', (error, filePath) => {
                // do other stuff with the file here
            });

            const root =`./ftp/sub-dir`;

            if (!fs.existsSync(root)){
                fs.mkdirSync(root, { recursive: true });
            } 

            return resolve({ root});
        } else {
            reject({  err: 'no' });
        }

});

ftpServer.on('client-error', (connection, context, error) => {
    console.log(chalk.bgGreen(`FTP connection:${connection.id} => error: `, error));
    telegram.sendAdmin(JSON.stringify(error))
});

ftpServer.on('disconnect', (connection, id) => {
    console.log(chalk.bgGreen(`FTP connection:${connection.id} => disconnected`));
});

ftpServer.listen().then(() => {
    console.log(`FTP Server running at http://${hostname}:${ftpPort}/`);
});

dockerfile

FROM node:12
COPY package.json /package.json
RUN npm install --production
COPY . /

docker-compose

version: "2.0"
services:
  app:
    image: ${CI_REGISTRY_IMAGE}:latest
    restart: always
    container_name: ${CI_PROJECT_NAME}
    command: "npm run start"
    volumes:
      - ./ftp:/ftp
    ports:
      - "${PORT}:${PORT}"
      - "${FTP_PORT}:${FTP_PORT}"
      - "21000-21190:21000-21190"
almgwary commented 2 years ago

Here is some logs

2022-06-11T19:41:28.313734910Z {"name":"ftp-srv","hostname":"71ac60d75aec","pid":19,"id":"8bafa624-9c3d-4ac9-afc7-af3b7f128b88","ip":"19*.1*2.**2.**","directive":"PASV","level":50,"err":{"message":"Unable to find valid port","name":"ConnectorError","stack":"ConnectorError: Unable to find valid port\n    at tryGetPort (/node_modules/ftp-srv/src/helpers/find-port.js:28:16)\n    at Server.<anonymous> (/node_modules/ftp-srv/src/helpers/find-port.js:37:11)\n    at Object.onceWrapper (events.js:421:26)\n    at Server.emit (events.js:314:20)\n    at emitErrorNT (net.js:1343:8)\n    at processTicksAndRejections (internal/process/task_queues.js:84:21)","code":400},"msg":"Unable to find valid port","time":"2022-06-11T19:41:28.313Z","v":0}
2022-06-11T19:41:29.022650502Z {"name":"ftp-srv","hostname":"71ac60d75aec","pid":19,"id":"8bafa624-9c3d-4ac9-afc7-af3b7f128b88","ip":"19*.1*2.**2.**","directive":"LIST","level":50,"err":{"message":"Passive server not setup","name":"ConnectorError","stack":"ConnectorError: Passive server not setup\n    at Passive.waitForConnection (/node_modules/ftp-srv/src/connector/passive.js:18:49)\n    at FtpConnection.handler (/node_modules/ftp-srv/src/commands/registration/list.js:17:27)\n    at FtpCommands.handle (/node_modules/ftp-srv/src/commands/index.js:70:28)\n    at /node_modules/ftp-srv/src/connection.js:47:67\n    at tryCatcher (/node_modules/bluebird/js/release/util.js:16:23)\n    at Object.gotValue (/node_modules/bluebird/js/release/reduce.js:166:18)\n    at Object.gotAccum (/node_modules/bluebird/js/release/reduce.js:155:25)\n    at Object.tryCatcher (/node_modules/bluebird/js/release/util.js:16:23)\n    at Promise._settlePromiseFromHandler (/node_modules/bluebird/js/release/promise.js:547:31)\n    at Promise._settlePromise (/node_modules/bluebird/js/release/promise.js:604:18)\n    at Promise._settlePromiseCtx (/node_modules/bluebird/js/release/promise.js:641:10)\n    at _drainQueueStep (/node_modules/bluebird/js/release/async.js:97:12)\n    at _drainQueue (/node_modules/bluebird/js/release/async.js:86:9)\n    at Async._drainQueues (/node_modules/bluebird/js/release/async.js:102:5)\n    at Immediate.Async.drainQueues [as _onImmediate] (/node_modules/bluebird/js/release/async.js:15:14)\n    at processImmediate (internal/timers.js:461:21)","code":400},"msg":"Passive server not setup","time":"2022-06-11T19:41:29.022Z","v":0}
2022-06-11T19:41:30.199202339Z {"name":"ftp-srv","hostname":"71ac60d75aec","pid":19,"id":"8bafa624-9c3d-4ac9-afc7-af3b7f128b88","ip":"19*.1*2.**2.**","directive":"PASV","level":50,"err":{"message":"Unable to find valid port","name":"ConnectorError","stack":"ConnectorError: Unable to find valid port\n    at tryGetPort (/node_modules/ftp-srv/src/helpers/find-port.js:28:16)\n    at Server.<anonymous> (/node_modules/ftp-srv/src/helpers/find-port.js:37:11)\n    at Object.onceWrapper (events.js:421:26)\n    at Server.emit (events.js:314:20)\n    at emitErrorNT (net.js:1343:8)\n    at processTicksAndRejections (internal/process/task_queues.js:84:21)","code":400},"msg":"Unable to find valid port","time":"2022-06-11T19:41:30.198Z","v":0}
2022-06-11T19:41:30.873089357Z {"name":"ftp-srv","hostname":"71ac60d75aec","pid":19,"id":"8bafa624-9c3d-4ac9-afc7-af3b7f128b88","ip":"19*.1*2.**2.**","directive":"SIZE","level":50,"err":{"message":"ENOENT: no such file or directory, stat '/ftp/*****","v":0}
2022-06-11T19:41:32.170739820Z {"name":"ftp-srv","hostname":"71ac60d75aec","pid":19,"id":"8bafa624-9c3d-4ac9-afc7-af3b7f128b88","ip":"19*.1*2.**2.**","directive":"PASV","level":50,"err":{"message":"Unable to find valid port","name":"ConnectorError","stack":"ConnectorError: Unable to find valid port\n    at tryGetPort (/node_modules/ftp-srv/src/helpers/find-port.js:28:16)\n    at Server.<anonymous> (/node_modules/ftp-srv/src/helpers/find-port.js:37:11)\n    at Object.onceWrapper (events.js:421:26)\n    at Server.emit (events.js:314:20)\n    at emitErrorNT (net.js:1343:8)\n    at processTicksAndRejections (internal/process/task_queues.js:84:21)","code":400},"msg":"Unable to find valid port","time":"2022-06-11T19:41:32.170Z","v":0}
matt-forster commented 2 years ago

Is there a reason you are only opening up 10 ports in the code but 190 in the image?

Are the requests concurrent or sequential?

almgwary commented 2 years ago

Yes am using concurrent ftp uploads, Also I've changed the app to use 190 ports instead of 10 so it takes longer time to fial with Unable to find valid port

almgwary commented 2 years ago

197

almgwary commented 2 years ago

https://github.com/QuorumDMS/ftp-srv/pull/109

matt-forster commented 2 years ago

111

matt-forster commented 2 years ago

I've found bluebird .finally criminally unreliable in some cases - so it may be that the previous correction is not working.

almgwary commented 2 years ago

Is there any quick fix that I can do? we currently having this as produciton issue

almgwary commented 2 years ago

@matt-forster cab we have quick fix soon ?

matt-forster commented 2 years ago

I've made some effort to reproduce this locally, and I haven't been able to with Filezilla - have you had any success reproducing this with the test file test/start.js?

almgwary commented 2 years ago

It is only happens in our produciton environment, it works fine locally. We are currently restarting the server every 2h to fix it

matt-forster commented 2 years ago

Could you please give some more info on the environment you are running into the issue in?

almgwary commented 2 years ago

@matt-forster The issue still exists on docker env FROM node:12 but when tried to run the server on ec2 without docker it works fine

almgwary commented 2 years ago

https://github.com/QuorumDMS/ftp-srv/discussions/197

almgwary commented 2 years ago

But on Docker (and therefore kubernetes) the ports don't seem to be released after use, even when closing, and exiting the client.

https://github.com/QuorumDMS/ftp-srv/discussions/197#discussioncomment-168910