CentOS: vsftpf with virtual users setup

CentOS 5.5, CentOS 6 and CentOS7 include vsftpd, the Very Secure FTP Daemon. Here we talk about how to set it up with virtual users, i.e. WITHOUT making a local login for each person. One of many use cases is to enable a set of users who will end up working on web site content, so 1-to-1 ftp to web domains.  The benefit to using virtual users is that when people try to guess logins to your system by banging on the ftp door, they never learn anything about real accounts.

NB: CentOS 6.5 yum install vsftpd gives you vsftpd version 2.2.2.  Later source is available, e.g. 3.0.2. (See Compiling VSFTPD from source to get latest version; I tried in July 2014 and could not make the binary with SSL support, only without.)    However CentOS7 yum install vsftpd gives a MUCH newer version.

The first thing to understand is that you will need one real Linux account, whose permissions and group membership are used to give access to the virtual ftp users.  For the sake of this article, that user's name will be elvis.  The default name that you will see in most vsftpd.conf sample files is ftpsecure. Carefully choose a unique name for this account and be sure to swap it out in all the instructions below. 


Add Elvis 

The elvis account will be shared by all virtual users. If you have a desktop installed, start the User Manager: go to System (on the panel) => Administration => Users and Groups.  (From command line, see useradd reference.) The user that you create here will be referenced as the guest user in the vsftpd.conf file.  Be sure to use a very strong password because this is a REAL account on your Linux server.

# useradd elvis
# passwd elvis

This creates a bunch of stuff for elvis, including his home folder, /home/elvis.


Put Elvis in the FTP Group

You can use another group name, but it is not bad to stick to the idea of the FTP group. 
# usermod -a -G ftp elvis

Prepare the directories that virtual users will access

You will need a directory tree that starts from a place that elvis has access to.  If you know how to make links to other parts of your disk, that is up to you. Here we will consider a simple directory layout.

/home/elvis/vftp/andrea
/home/elvis/vftp/bobby
/home/elvis vftp/charlie

If you will be using the elvis account to let www customers go to their folder area, you should create those folders and make sure elvis can access them.  When making lots of folders at once, you can use this shortcut for making multiple nested folders at once: mkdir www.domain1.com/{live,private,log,backup}.

Getting the directory structure correct, and making sure that elvis can CD into all the folders, is essential.  


This fixes not being able to write once logged into FTP
# chown -R elvis:elvis  /home/vweb/
# chmod -R 644 /home/elvis/vftp/
# cd /
# find /home/elvis/vftp/ -type d -exec chmod 755 {} \;

If you are trying to grant access to a virtual user outside of the so-called home directory, see How to give a virtual vsftpd user access to a folder outside the home area.

Install the Very Secure FTP Daemon VSFTPD

This is a simple overview (you will need to learn all this and more):
install-ftp-server

You will need to do these steps to enable encryption (SSL), which you should do before expecting the vsftpd service to start with SSL enabled:
enable SSL within vsftpd

Re SSL client in July 2014, try using the FileZilla FTP client.  The LeapFTP client is one example that is great for seeing the error message about SELinux blocking the change-directory to the home area, but fails to see a directory listing when connected with SSL. (LeapFTP works fine without SSL to vsftpd).  Use FileZilla for the client when you want to test SSL connections!

Re SSL on the server side, set the following lovely flag in /etc/vsftpd/vsftpd.conf (thanks to this thread) and then restart the service.

ssl_ciphers=HIGH

Create your list of virtual users and passwords

To set up your database of virtual users, you need to use something called PAM. Follow these excellent instructions BUT (a) note that CentOS7 minimal install includes PAM and there is no need to install db4, and (b) take the advice of one of the first comments which is that you MUST add  crypt=hash to the end of the first two configuration lines. Otherwise you will never be able to login over ftp.

Here is what you would have in the vusers.txt file, but using much better passwords, say from grc.com.  You can use 32 characters for a password. Go for it.

andrea
password1
bobby
password2
charlie
password3

Caveat for modifying the list of users -- I have not figured out how to add/modify/delete virtual users so I just stop the vsftpd service, modify the vusers.txt file, delete the virtual user .db file, and then recreate it with db_load, and then start the vsftpd.  That works. 

# cd /etc/vsftpd
# service vsftpd stop
# rm vsftpd-virtual-user.db
# vi vusers.txt
# db_load -T -t hash -f vusers.txt vsftpd-virtual-user.db

optional:
# chmod 600 vsftpd-virtual-user.db


# service vsftpd start

Custom Folders and Permissions for Certain Users

What if you want multiple users to have readonly access to some folders that a read/write user is allowed to maintain for them? For this (and other use cases), you want to take advantage of the user_config_dir feature of vsftpd.  This feature is documented on the CentOS Wiki page for VirtualVsFtpd.  Within the /etc/vsftpd/vsftpd_user_conf directory, you create one (1) file for each user deserving of special rules.  The special rules can make the user a readonly user, and can put the user into a particular directory anywhere on the system. Sample file contents are shown as a listing for /etc/vsftpd/vsftpd_user_conf/user1 on the Wiki page.

Customize the VSFTPD.conf configuration file

You will definitely need the manual page for vsftpd: vsftpd_conf

Here is a complete copy of a fully functioning vsftpd.conf file.  Watch for references to elvis.  

# VSFTPD config file /etc/vsftpd/vsftpd.conf
#
# Please read the vsftpd.conf.5 manual page to get a 
# full idea of vsftpd's
# capabilities.
#
# Allow anonymous FTP? (Beware - allowed by default 
# if you comment this out).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
# local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
write_enable=YES
#
# Default umask for local users is 077. You may wish to 
# change this to 022,
# if your users expect that (022 is used by most other ftpd's)
local_umask=022
#
# Uncomment this to allow the anonymous FTP user to upload 
# files. This only
# has an effect if the above global write enable is 
# activated. Also, you will
# obviously need to create a directory writable by the FTP user.
# anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be 
# able to create
# new directories.
# anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote 
# users when they
# go into a certain directory.
# dirmessage_enable=YES
#
# The target log file can be vsftpd_log_file or xferlog_file.
# This depends on setting xferlog_std_format parameter
xferlog_enable=YES
#
# PORT transfer connections can originate from 
# port 20 (ftp-data).
# connect_from_port_20=YES
pasv_enable=YES
pasv_min_port=8021
pasv_max_port=8025
pasv_address=209.201.224.7
#
# If you want, you can arrange for uploaded anonymous 
# files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# The name of log file when xferlog_enable=YES and xferlog_std_format=YES
# WARNING - changing this filename affects /etc/logrotate.d/vsftpd.log
#xferlog_file=/var/log/xferlog
#
# Switches between logging into vsftpd_log_file and 
# xferlog_file files.
# NO writes to vsftpd_log_file, YES to xferlog_file
xferlog_std_format=YES

#
# You may change the default value for timing out an 
# idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a 
# data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a 
# unique user which the
# ftp server can use as a totally isolated and unprivileged user.
nopriv_user=elvis

#
# Enable this and the server will recognise asynchronous 
# ABOR requests. Not
# recommended for security (the code is non-trivial). 
# Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode 
# but in fact ignore
# the request. Turn on the below options to have the 
# server actually do ASCII
# mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a 
# denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII 
# mode. vsftpd
# predicted this attack and has always been safe, reporting 
# the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#ascii_upload_enable=YES
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
ftpd_banner=Welcome to Super Duper FTP service
#
# You may specify a file of disallowed anonymous 
# e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
#deny_email_enable=YES
# (default follows)
#banned_email_file=/etc/vsftpd/banned_emails
#
# You may specify an explicit list of local users to 
# chroot() to their home
# directory. If chroot_local_user is YES, then this list 
# becomes a list of
# users to NOT chroot().
chroot_local_user=YES

# following line for latest vsftpd on CentOS7
allow_writeable_chroot=YES


#chroot_list_enable=NO
# (default follows)
#chroot_list_file=/etc/vsftpd/chroot_list
#
# You may activate the "-R" option to the builtin ls. 
# This is disabled by
# default to avoid remote users being able to cause 
# excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" 
# and "mirror" assume
# the presence of the "-R" option, so there is a strong 
# case for enabling it.
ls_recurse_enable=YES
#
# When "listen" directive is enabled, vsftpd runs in 
# standalone mode and
# listens on IPv4 sockets. This directive cannot be used 
# in conjunction
# with the listen_ipv6 directive.
listen=YES
#
# This directive enables listening on IPv6 sockets. To 
# listen on IPv4 and IPv6
# sockets, you must run two copies of vsftpd with 
# two configuration files.
# Make sure, that one of the listen options is commented !!
#listen_ipv6=YES

pam_service_name=vsftpd.virtual
max_clients=5

#This must be enabled for non-anonymous login to work, incl virtual users
local_enable=YES

userlist_enable=YES
userlist_deny=YES
userlist_file=etc/vsftpd/user_list

virtual_use_local_privs=YES

# Automatic home dir for each virtual user based on template
# $USER will be andreas, bobby, charlie, etc.
user_sub_token=$USER
local_root=/home/elvis/vftp/$USER

# Activate virtual users
guest_enable=YES
guest_username=elvis
# make sure following directory exists even if empty
user_config_dir=/etc/vsftpd/vsftpd_user_conf 

# Hide ids from user
hide_ids=YES


# When enabled, TCP wrappers are used to grant access to 
# the server.
# Relevant when the ftp server should work on multiple 
# ip addresses with
# varying configuration.
tcp_wrappers=NO

# SSL support
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=NO
force_local_logins_ssl=NO
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
ssl_ciphers=HIGH
rsa_cert_file=/etc/vsftpd/vsftpd.pem

After changing the configuration, restart the service.


# service vsftpd restart



Troubleshooting: when vsftpd fails to start

Ben Cane has excellent advice for troubleshooting, especially but not only for CentOS7.  If you run vsftpd by yourself instead of starting it through services, you can see errors about your configuration, e.g. typos in the keywords that can prevent vsftpd from starting.


# /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

Aside from typos, with CentOS7, you will not be able to start vsftpd if /home/elvis/___  directories have WRITE permission unless you enable that in your vsftpd.conf.  You will need to do that if you want users to be able to write to the top of their "home" folder.  (The symptoms of elvis not having write access are error messages "550 Delete operation failed"  and "553 Could not create file".)

# read about chroot choices at benscobie.com
allow_writeable_chroot=YES

On CentOS7 you may also need this to enable writing to the home directory
setsebool -P ftp_home_dir on


Once vsftpd starts successfully

It is time to test with an ftp client to see whether you get in.  Make sure the firewall configuration is open for tcp ports 21 plus 8021-8025 for the pasv.  (You can use a larger pasv port range to support more users if you want.) (In CentOS7 you can just enable the service called FTP in the firewalld configuration.)

It is likely that you will get an error that boils down to the fact that elvis cannot get to his home directory. This wonderful web page had the final steps needed, which are so difficult to find that I am repeating the details here now:

Fixes "500 OOPS: cannot change directory". If SELinux is not enabled or enforcing then this can be ignored.
# /usr/sbin/setsebool  -P ftp_home_dir=1
(See also vsftpd-transfer-done-but-failed-to-open-directory )

There are even more complexities with SELinux;
see SELinux manual page and you may need the simplest solution which is to turn off SELinux for FTP (although this is for older CentOS definitely not CentOS7) :
# setsebool -P ftpd_disable_trans 1.


Testing with FTP Clients

If you have any trouble, try many different ftp clients.  They all have pros and cons.

Some ftp clients give more useful diagnostics than others.  It helps to test from multiple clients to get a well-rounded view of problems.  Bad firewall configuration can lead to hanging.  Insufficent permissions on the home folder can give the symptom of a missing directory.  Bad SSL setup can give a lack of response for connections of ExplicitSSL while the very same configuration works fine from an unencrypted connection.




Additional:



Comments

Anonymous said…
Hi,
Thank you for the above very helpful article.
However, did you know that your sidebar sticky float sits on the Windows scroll-bar and as such it makes it very difficult, and really annoying, to scroll down the page and read your text?
As somebody who works in the tech/web environment, I would have thought that you would resist using silly gimmicks like that.
Very annoyed Centos user.
Blogger said…
Are you trying to make money from your websites/blogs by running popunder advertisments?
If so, did you take a look at Propeller Ads?

Popular Posts