I wanted to install an FTP server on my servers, I check online and it turned up that VSFTPD is the most secure one so I started installing it.
I’ve been through many tutorials and I couldn’t find any fully detailled ones so I decided to write mine. I have to explain, I set up VSFTPD on my personal server, wrote the tutorial step by step then followed my own tutorial to deploy VSFTPD on my production dedicated server.
What we will do
- Install vsftpd and a PAM library
- Edit /etc/vsftpd.conf and /etc/pam.d/vsftpd
- Create user accouts with custom directories (in /var/www/ for example)
- Set directories with the correct chmod and chown
- Create a admin user with full access to the server
- Troubleshoot
1. Install vsftpd (Very Secure FTP Deamon) and libpam-pwdfile to create virtual users
I wanted to create FTP users but I didn’t want to add local unix users (no shell access, no home directory and so on). A PAM (Pluggable Authentication Modules) will help us creating virtual users.
sudo apt-get install vsftpd libpam-pwdfile
2. Edit vsftpd.conf
First we need to back up the original file
sudo mv /etc/vsftpd.conf /etc/vsftpd.conf.bak
Then create a new one
sudo vim /etc/vsftpd.conf
Copy and paste the following lines. The file should contains ONLY theses lines:
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
nopriv_user=vsftpd
virtual_use_local_privs=YES
guest_enable=YES
user_sub_token=$USER
local_root=/var/www/$USER
chroot_local_user=YES
hide_ids=YES
guest_username=vsftpd
3. Register virtual users
To register user we use htpasswd so I assume you have apache2 working on your server. Create a vsftpd folder, we’ll put configuration files in it.
sudo mkdir /etc/vsftpd
then
sudo htpasswd -cd /etc/vsftpd/ftpd.passwd user1
- -c means that we’ll create the file if it’s not existing yet
- -d forces MD5, you need it on ubuntu 12.04, just use it always
If you want to add new users afterwards:
sudo htpasswd -d /etc/vsftpd/ftpd.passwd user2
4. Configure PAM in /etc/pam.d/vsftpd
Again, we need to back up the orignal file
sudo mv /etc/pam.d/vsftpd /etc/pam.d/vsftpd.bak
and create a new one
sudo vim /etc/pam.d/vsftpd
Copy and paste these 2 lines (this should be the only content). I insist, I wasted a lot of time because I kept orignal lines and just added these.
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd
account required pam_permit.so
5. Create a local user without shell access
sudo useradd --home /home/vsftpd --gid nogroup -m --shell /bin/false vsftpd
You can check that it has been created with the id command: id vsftpd. We define the user with the /bin/false shell because of the check_shell parameter (even if we don’t use it).
6. Restart vsftpd
The common way is using init.d like all deamon
sudo /etc/init.d/vsftpd restart
In Ubuntu 12.04 there is something new with services. It worked on my 12.04 but not on my 10.04 one. To be honest I’m not a Linux expert (yet) so I can’t explain why. Something to do with Upstart I think.
sudo service vsftpd restart
7. Create directories
According to our configuration all users will be placed into there folder: /var/www/user1.
You need to create them with particular rights: the root folder cannot be writable!
- / [root = /var/www/user1] => 555
- www [ /var/www/user1/www ] => 755
- docs [ /var/www/user1/docs ] => 755
In vsftpd.conf we have chroot_local_user=YES so the user can’t see anything outside his folder. To him the server looks like this:
Anyway, just run these commands:
mkdir /var/www/user1
chmod -w /var/www/user1
mkdir www/user1/www
chmod -R 755 /var/www/user1/www
chown -R vsftpd:nogroup /var/www/user1
The /var/www/user1 folder HAS TO exist or connection will fail.
Right now you can try to connect with your FTP client and it will succeed! If it doesn’t you can check the troubleshooting part.
8. Create an Admin user to access the entire server
To create an admin user we need to register a new user with htpasswd.
Before we do so, I’ll advice you to check into the /etc/ftpusers file that define certain users that are not allow to connect with ftp. I think it’s only for local users and not virtual users but just in case don’t choose a name contained into this file. Let’s be honest, vsftpd is complicated enough! ^^
sudo htpasswd -d /etc/vsftpd/ftpd.passwd theadmin
Now we need to add a new line into /etc/vsftpd.conf
chroot_list_enable=YES
This means that your user will be placed into their folder (as a jail) EXCEPT users into the /etc/vsftpd.chroot_list
Let’s create this file and add our user, the file is a simple line containing “theadmin”. Add one user per line. That means we DON’T need to create a /var/www/theadmin folder, the user will login placed into /home/vsftpd.
Restart the server and you are done !
Troubleshooting
Here are some errors I had.
500 OOPS: vsftpd: refusing to run with writable root inside chroot ()
Your root directory is writable, this is not allowed. Check part 7 for more information, you need to create a 555 root and 755 subfolders
500 OOPS: cannot change directory:/var/www/theadmin if the folder doesnt exist
The /var/www/$USER folder doesn’t exist, create it with the correct rights (not writable) or add the user into the /etc/vsftpd.chroot_list (see part 8). Don’t forget to restart the server.
htpasswd: cannot create file /etc/vsftpd/ftpd.passwd
The /etc/vsftpd/ folder has to be existing, htpasswd won’t create it.
vsftpd restart or stop error: “restart: Unknown instance“
This means you can’t start the deamon even if you have success message with /etc/init.d/vsftpd start. It doesn’t start because your configuration is wrong. Start over this tutorial
Sources
Here are some websites that helped me
- My favorite one: http://www.debiantutorials.com/installing-vsftpd-using-text-file-for-virtual-users/
- The man page: https://security.appspot.com/vsftpd/vsftpd_conf.html
- this one says something about allow_writeable_chroot but it’s not in the man page: http://www.benscobie.com/fixing-500-oops-vsftpd-refusing-to-run-with-writable-root-inside-chroot/
- http://ubuntuforums.org/showthread.php?t=518293
http://backdrift.org/how-to-use-bind-mounts-in-linux

[...] déjà publié un article en anglais sur l’installation et la configuration de vsftpd. L’article est orienté serveur web, c’est-à-dire qu’on prend l’exemple [...]
The -d option uses the crypt function which has max 8 digits.
I tried using MD5 for my password crypting but when trying to connect with FileZilla I get an error saying that I have not entered the good password for my user.
Any suggestions ?
I just read that the htpassword md5 encryption uses Apaches very own MD5 encryption which is not compatible with the PAM … that’s why is is failing.
Thanks a lot
Hi Julien, This is a very great Article. it actually works for EC2.
One Question from me, if i change user1 folder permission to 755, i can’t login.
chmod 755 /var/www/user1 > cannot login
chmod -w /var/www/user1 > able to login
I want to make user1 to be able to do something to his root. Any Clue how to fix this?
“Note: the user cannot create files or folders in the root directory.”
Why don’t make their respective root folder write-able? How do we do that?
Many thanks! this was a huge help when I needed to set up an ftp server in a hurry. It worked almost perfectly out of the box on my Ubuntu 12.04 server. One error in your instructions: the first line of your vsftpd.conf script is in fact two lines, and the service failed to start until the file was corrected.
listen=YESanonymous_enable=NO
Again, big thanks for your article.
Awesome! I could install Drupal like in a real web hosting. BTW how do you remove directories created/owned by www-data? TIA
Great tutorial. Helped me out a ton. Thanks for this.
One thing I noticed, that may confuse others, is near the bottom of Step 7 (the bash code has some html in it):
at the end of line 1 “”
and beginning of line 2 “”
Hi,
Nice write up btw. I’m having trouble after setting vsftpd using your guide… basically permissions are correct (owner and group is set to user1:nogroup and user directories are set to 755) when checking from ssh. But when i’m logged in via filezilla client the i can see that the owner/group appears as ftp:ftp and permissions the files and folders are still 755. How can i make sure that owner:group appear as user1:nogroup via ftp? Thanks in advance.
I just created files under one of the folders that I’ve set 777 permissions and the files created via ftp is appearing as created by the user vsftpd! Hopefully i figure out what’s going on soon.
Brilliant how-to. Thank you.
I had an issue where attempting to connect with ftp after setting up this procedure in Ubuntu 12.10 resulted in a segmentation fault: “www kernel: [ 5656.244925] vsftpd[3030]: segfault at 968″.
Research lead to uninstalling libpam-smbpass: sudo apt-get remove libpam-smbpass
(Google “[Bug 303458] Re: segfault in pam_smbpass.so”: https://lists.ubuntu.com/archives/ubuntu-server-bugs/2010-October/045147.html)
FTP users could then connect exactly as described here.
Thank you! You saved my life! I`m tryed to setup proftpd
and vsftpd for ours, without success. Thank you again!
Thanks for the great tutorial! I finally found one that
does nearly exactly what I am trying to accomplish! How would you
change it so the Admin user logs into /var/www instead of
/home/vsftpd? This would be much easier for staff than having them
navigate manually from /home/vsftpd to /var/www. I’d prefer the
Admin only to have access to /var/www and subdirectories, not the
entire server. Thanks!
This line: This means that your user will be placed into
their folder (as a jail) EXCEPT users into the
/etc/vsftpd.chroot_list Suppose to add your username manually
This line: This means that your user will be placed into
their folder (as a jail) EXCEPT users into the
/etc/vsftpd.chroot_list Add – “add your username manually” if it’s
not there. Work for me.
[...] perksa So I used this guide to setup vsftpd with
multiple users locked into their own dir. The problem I am having
is I make my [...]
Thanks so much for this tutorial! My only question is that
there are already folders that are owned by different user/group
(ie www-data:www-data) how do I allow ‘theadmin’ to edit them.
Currently, through ftp I can see them, open them but not save
changes
To give ‘theadmin’ access to files that might be already
owned do the following: 1. Add this to bottom of vsftpd.conf:
user_config_dir=/var/www/userconfs (or whatever you want to call
that directory) 2. Make that directory: mkdir /var/www/userconfs 3.
Create a specific file in your new directory for ‘theadmin’: sudo
nano /var/www/userconfs/theadmin 4. Add this line to the file:
local_root=/var/www (for access to subdirectories in www) AND this
line: guest_username=www-data (or whatever the user is that
currently owns the files you want to edit). 5. Save and sudo
service vsftpd restart Now you edit and save with your theadmin
user any files that are created by www-data. Thanks to this
tuturorial – > http://alethotech.com/?p=309