Public | Automated Build

Last pushed: 5 months ago
Short Description
Command line to start proftp or pure-ftpd without being root.
Full Description


Generate a proftpd config for the current non-root user.

Run it to server some virtual users and their home directories.


Macos: proftpd installed by homebrew
Linux: proftpd on the PATH

Optional: ftpasswd to generate password hashes.

Disclaimer: not for public facing FTP servers.

We are not boostrapping proftpd as root and we will not be able to use chroot.

We are using a white list of IP addresses for the allowed client connections.

We are restricting access to the home directories served for each users.
But users will be able to escape to other user's home directories once they know the path.

Some basic care is taken to prevent operations outside of the home directories
but there are certainly ways to escape them given enough symbolic links and other setups.

Between setup simplicity and security we are choosing simplicity.

Suggestions and contributions in this scope are welcome.

CLI Usage

Example: serve the current directory with: ftp://$USER:$USER@localhost:2121

proftpd-runner -home=.

Example: serve 2 directories with 2 different users on port 2123:

proftpd-runner -port=2123 -d \
  -users=joe,acme \
  -hashes=$1gg6GM8e1.YM,$1j8AdJchhwvs \

proftpd-runner -bind= -d -users=tank -passwds=stoic -homes=/apps/resources -user=stoic

proftpd-runner -bind= -d -users=tank -passwds=stoic -homes=/usr/share -user=stoic

Embed Usage


const config = {
  ServerName: 'A cozy FTP not run as root',
  Port      : 2121,
  FtpUsers  : [ 'user1', 'user2' ],
  FtpHomes  : [ '/ftphomes/user1', '/ftphomes/user2' ],
  FtpHashes : [ 'user1_1_hash_from_ftpasswd', 'user1_1_hash_from_ftpasswd' ],
  TrustedPeers : [ '', '' ]
  EtcDir    : '/path/to/ftpd/conf/directory',
  VarDir    : '/path/to/var/directory'


Passwords and Hashes

The hashes can be generated by ftpasswd --hash
One can also directly provide the passwords in clear and the utility will invoke ftpasswd

FtpPasswds : [ 'user1_pass_in_clear', 'user2_pass_in_clear' ],

On the cli: -passwds

If one has precomputed some hashes they can be passed:

ComputedHashes : {
  passwd1: 'hash1',
  passwd2: 'hash2',

Daemon/Foreground and Reload

By default the server is run in the foreground. It will still produce a pid file.
To daemonize it:

Daemonize: true

On the cli: -d

Before we start the server we check if the pid file exists already.

If it does we send a SIGUP to the process to tell it to reload its configuration.

To force a restart:

Restart: true

On the cli: -restart

FTP URLs - Experimental

A shortcut to configure a user consists of providing the host name and one or more URLs
with the home in the query string:

Hostname: 'host1',
FtpUrls: [

The URLs for which the host and port match the current ftp server config
will be parsed to add the corresponding user and its home directory.

The password used will be either the one provided for this user in FtpHashes, or FtpPasswds
or the one provided in the URL.

The one found in FtpHashes for that user has precedence on FtpPasswds and
itself precedes the one extracted in the URL.

Docker Pull Command
Source Repository