Skip to main content

Node.js FTP Server

Shenzhen, China

I want to use the nodeftp package to set up an FTP server for my IP camera.


Create a folder /opt/ftpd and initialize your project:

mkdir -p /opt/ftpd/ftproot && cd /opt/ftpd
npm init


Then install the following dependencies:

npm install dotenv
npm install fs
npm install ftpd
npm install path

Environment Variables

Now we need a few environment variables to define our server parameter and user authentication credentials:

nano .env

Add the following variables - make sure to change the host IP to the IP address of your server:

IP = ''
PORT = 9876
USER = ftpuser
PWD = password

Server Script

Now to the server itself - create a file index.js:

const ftpd = require('ftpd')
const fs = require('fs')
const path = require('path')


var keyFile
var certFile
var server

// use the IP and PORT from the .env file or default to localhost:21
var options = {
  host: process.env.IP || '',
  port: process.env.PORT || 21,
  tls: null,

// Check if SSL KEY / CERT are provided ELSE start without SSL support
if (process.env.KEY_FILE && process.env.CERT_FILE) {
  console.log('Running as FTPS server')
  if (process.env.KEY_FILE.charAt(0) !== '/') {
    keyFile = path.join(__dirname, process.env.KEY_FILE)
  if (process.env.CERT_FILE.charAt(0) !== '/') {
    certFile = path.join(__dirname, process.env.CERT_FILE)
  options.tls = {
    key: fs.readFileSync(keyFile),
    cert: fs.readFileSync(certFile),
    ca: !process.env.CA_FILES
      ? null
      : process.env.CA_FILES.split(':').map(function (f) {
          return fs.readFileSync(f)
} else {
  console.log('###### To run as FTPS server, #####')
  console.log('### set "KEY_FILE", "CERT_FILE" ###')
  console.log('###### or "CA_FILES" env vars. ####')

// get ftp root directory listing
server = new ftpd.FtpServer(, {
  getInitialCwd: function () {
    return '/ftproot'
  getRoot: function () {
    return process.cwd()
  pasvPortRangeStart: 1025,
  pasvPortRangeEnd: 1050,
  tlsOptions: options.tls,
  allowUnauthorizedTls: true,
  useWriteFile: false,
  useReadFile: false,
  uploadMaxSlurpSize: 7000, // N/A unless 'useWriteFile' is true.
  allowedCommands: [

server.on('error', function (error) {
  console.log('FTP Server error:', error)

// verify user and password from .env file
server.on('client:connected', function (connection) {
  var username = null

  console.log('client connected: ' + connection.remoteAddress)

  connection.on('command:user', function (user, success, failure) {
    if (user) {
      username = process.env.USER
    } else {

  connection.on('command:pass', function (pass, success, failure) {
    if (process.env.PWD) {
    } else {

server.debugging = 4
console.log('Listening on port ' + options.port)

Run your Server

You can start the server with node index.js or by creating an npm start script and connect to your server using an FTP Client like Filezilla:

ftpd Nodejs FTP Server

Adding Encryption /doesn't work

mkdir certs && cd certs
openssl req -new -x509 -sha256 -newkey rsa:2048 -nodes -keyout key.pem -days 365 -out cert.pem

Add the following variables - make sure to change the host IP to the IP address of your server:

IP = ''
PORT = 9876
USER = ftpuser
PWD = password
CERT_FILE = './certs/cert.pem'
KEY_FILE = './certs/key.pem'

I am getting deprecation warnings and could not get my client to connect:

npm start

> node-file-server@1.0.0 start /opt/ftpd
> node index.js

Running as FTPS server
Listening on port 9876
client connected: undefined
Accepted a new client connection
<::ffff:> >> 220 FTP server (nodeftpd) ready
<::ffff:> << AUTH TLS
<::ffff:> FTP command: AUTH TLS
<::ffff:> >> 234 Honored
<::ffff:> Establishing secure connection...
(node:44550) [DEP0064] DeprecationWarning: tls.createSecurePair() is deprecated. Please use tls.TLSSocket instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
    var verifyError = (pair._ssl || pair.ssl).verifyError();

TypeError: Cannot read property 'verifyError' of undefined
    at SecurePair.<anonymous> (/opt/ftpd/node_modules/ftpd/lib/starttls.js:62:47)
    at SecurePair.emit (events.js:315:20)
    at TLSSocket.<anonymous> (tls.js:322:46)
    at Object.onceWrapper (events.js:421:28)
    at TLSSocket.emit (events.js:315:20)
    at TLSSocket._finishInit (_tls_wrap.js:932:8)
    at TLSWrap.onhandshakedone (_tls_wrap.js:149:9)
    at DuplexSocket.ondata (internal/js_stream_socket.js:77:22)
    at DuplexSocket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
npm ERR! errno 1
npm ERR! node-file-server@1.0.0 start: `node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the node-file-server@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2021-02-03T10_59_40_679Z-debug.log