How to setup FTP server on Ubuntu 16.04 with virtual users

Sometimes you need set up an FTP for your project. In this article, I’ll show how you can setup FTP on your Ubuntu server. First of all, install vsftpd and PAM:

$ sudo apt-get update
$ sudo apt-get install vsftpd libpam-pwdfile

Save the old configuration file. Now we can work with blank configuration.

$ sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak

Open the configuration and replace the file content with follows:

anonymous_enable=NO
local_enable=YES
chroot_local_user=YES
user_config_dir=/etc/vsftpd/vsftpd-virtual-user/
virtual_use_local_privs=YES
dual_log_enable=YES
connect_from_port_20=YES
listen=YES
pam_service_name=ftp
tcp_wrappers=YES
allow_writeable_chroot=YES

Restart vsftpd service:

$ sudo service vsftpd restart

Then create a new directory for file with virtual users:

$ sudo mkdir -p /etc/vsftpd/vsftpd-virtual-user/

And create a blank file where we will add users with passwords a bit later:

$ sudo touch /etc/vsftpd/vsftpd-virtual-user/vsftpd_user

Copy yet another configuration file:

$ sudo cp /etc/pam.d/vsftpd /etc/pam.d/vsftpd.bak

And replace its content by the next one:

session optional        pam_keyinit.so  force   revoke
auth   required        pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
auth   required        pam_shells.so
auth    include system-auth
account include system-auth
session include system-auth
session required pam_loginuid.so

Now we can create a new system user. It user will have an own separate home directory but will not allow to login via ssh. Replace USERNAME with something you want, like ftp-myproject for example.

$ sudo useradd --home /home/USERNAME --gid nogroup -m --shell /bin/false USERNAME

Then setup a password for newly created user:

$ echo USERNAME:PASSWORD|sudo chpasswd

Now we have to add the name of new user to the vsftpd_user file:

$ sudo nano /etc/vsftpd/vsftpd-virtual-user/vsftpd_user

Just add the name of the user to this file as a separate line.

Create the separate file for our user in the directory /etc/vsftpd/vsftpd-virtual-user

$ sudo nano /etc/vsftpd/vsftpd-virtual-user/USERNAME

And put the next content inside it:

local_root=/home/USERNAME
cmds_allowed=USER,PASS,SYST,FEAT,OPTS,PWD,TYPE,PASV,LIST,STOR,CWD,MKD,SIZE,MDTM,CDUP,RETR,RNFR,RNTO,QUIT
local_umask=022
write_enable=YES

If you want to give a permission for deleting files to your new user than just add DELE to the argument cmds_allowed.

That’s all. Now you can use your FTP client to connect with corresponding user and password. The root of your FTP is /home/USERNAME. You also can use mount command to share any directory to your FTP root. Like that:

$ sudo mkdir -p /home/USERNAME/DESTINATION
$ sudo mount --bind SOURCE /home/USERNAME/DESTINATION
Filezilla window with the FTP opened

Filezilla window with the FTP opened