Configuring FTP server VSFTPD

Configure VSFTPD Virtual Users

The document describes how to fine-tune vsftpd and the system to significantly expand the capabilities of vsftpd:
  1. Read-only users.
  2. Record-Only Users.
  3. Create an anonymous ftp server, if necessary, only special users with permissions can see the downloaded files.
  4. Limit FTP speeds for [not] anonymous \ any_ individual users.
  5. Restrict any necessary users to work only in the subdirectories assigned to them, and users working with all such directories.
  6. And so on, everything that can be configured in vsftpd, but for each individual virtual user!
For the scheme to work, the packages pam, xinetd, db4, db4-utils ( /usr/bin/db_load ) are needed.
Creating a unix-shell user for a new configuration instance.
We will create several vsftpd configurations independent of each other, for each such instance one real unix-shell user and our own set of vsftpd configs will be used. In the example, the username is f_ftp.
# umask 0077;
# mkdir -m 0701 /home/ftp_users
# useradd -m -d /home/ftp_users/f_ftp f_ftp
# chmod 705 /home/ftp_users/f_ftp
# mkdir -m 0775 /home/ftp_users/f_ftp/incoming
# chown ftp:f_ftp /home/ftp_users/f_ftp/incoming
# edquota f_ftp <= assign a common quota for this ftp and all its virtual users.
If you do not plan to give anonymous access, you can not create the incoming directory.
If you want the downloaded files to the incoming directory to be accessible to all anonymous users (anonymous, ftp in the examples below) for downloading only by a "direct link", that is, for those who know the file name, but the list of files in this directory was not displayed, in order to remove the possibility of listing the directory, invoke:
# chmod 0375 /home/ftp_users/f_ftp/incoming;

Setting vsftpd's instance. Configure xinetd

Using xinetd we will be able to run several independent vsftpd, each of which will be with its own configuration. Each vsftpd is hung on its own IP. When accessing this IP, xinetd will call the corresponding vsftpd with a specific configuration file:
# mkdir -m 700 /etc/xinetd.d/vsftpd_virtual
# cat > /etc/xinetd.d/vsftpd_virtual/f_ftp << EOF
service ftp
{
      socket_type     = stream
      protocol        = tcp
      user            = root
      wait            = no
      rlimit_as       = 16M
      server          = /usr/sbin/vsftpd
      bind            = 192.168.0.33
      server_args     = /etc/vsftpd/f_ftp/vsftpd.conf
      disable         = no
}
EOF
192.168.0.33 -- The unique IP stuck behind this instance. Change it.
# echo "includedir /etc/xinetd.d/vsftpd_virtual" >> /etc/xinetd.conf

Setting vsftpd's instance. Vsftpd.conf main configuration file

# mkdir -p -m 0700 /etc/vsftpd/f_ftp
# touch /etc/vsftpd/f_ftp/vsftpd.conf; chmod 600 /etc/vsftpd/f_ftp/vsftpd.conf
# cat > /etc/vsftpd/f_ftp/vsftpd.conf << EOF
anonymous_enable=YES
ftp_username=ftp
anon_root=/home/ftp_users/f_ftp
#chown_username=f_ftp (see bugs section)
#chown_uploads=YES (see bugs section)
anon_upload_enable=YES
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
anon_world_readable_only=YES
anon_umask=022
anon_max_rate=80960

local_enable=YES
write_enable=YES
local_umask=022
  
dirmessage_enable=YES
xferlog_enable=YES
log_ftp_protocol=YES

port_enable=YES
connect_from_port_20=YES

pasv_enable=YES
pasv_min_port=49152
pasv_max_port=65535

idle_session_timeout=65
data_connection_timeout=60
accept_timeout=10
connect_timeout=10
max_clients=5
#max_per_ip=2
#<--- 421 There are too many connections from your internet address.
max_per_ip=10
nopriv_user=vsftpd

async_abor_enable=NO
ascii_upload_enable=NO
ascii_download_enable=NO

ftpd_banner=Welcome to Super Client instance FTP server.

ls_recurse_enable=YES
hide_ids=YES

use_localtime=YES

userlist_deny=NO
userlist_enable=YES
userlist_file=/etc/vsftpd/f_ftp/allowed_list

pam_service_name=vsftpd.f_ftp
guest_enable=YES
guest_username=f_ftp
user_config_dir=/etc/vsftpd/f_ftp/users


#500 OOPS: vsftpd: refusing to run with writable root inside chroot()
allow_writeable_chroot=YES

EOF
Main settings:
  1. ftpd_banner -- FTP banner.
  2. pam_service_name=vsftpd.f_ftp -- see below for setting up PAM.
  3. guest_username=f_ftp -- The name of the user into which virtual users registered in virtual_users map (see below on Pre-Configuring PAM).
  4. userlist_file=/etc/vsftpd/f_ftp/allowed_list -- See below about the file allowed_list
  5. user_config_dir=/etc/vsftpd/f_ftp/users -- See below about 'users' directory

PAM setup

Directive pam_service_name=vsftpd.f_ftp points to a file:
# cat > /etc/pam.d/vsftpd.f_ftp << EOF
auth     required    pam_nologin.so
auth     required    pam_userdb.so db=/etc/vsftpd/f_ftp/virtual_users
account  required    pam_userdb.so db=/etc/vsftpd/f_ftp/virtual_users
EOF

PAM further configuration . 'virtual_users' file

By this file VSFTPD authorize "users" through PAM, here __only__ virtual users should be indicated:
# cat > /etc/vsftpd/f_ftp/virtual_users << EOF
vuser1
vpass1
vuser2
vpass2
EOF
Check this file, there should not be empty lines at the beginning and end of the file, there should be no spaces at the end of lines, etc.
Then, to generate the .db file (PAM actually use that .db file, not original):
  # db_load -T -t hash -f /etc/vsftpd/f_ftp/virtual_users /etc/vsftpd/f_ftp/virtual_users.db
Do not forget to run this command after entering a new virtual user or changing the password to an existing one.
Configure VSFTPD. 'allowed_list' file.
Config Directive: userlist_file=/etc/vsftpd/f_ftp/allowed_list
allowed_list -- list of allowed users, __including__ virtual.
There is no need to make this .db file.
# touch /etc/vsftpd/f_ftp/allowed_list; chmod 600 /etc/vsftpd/f_ftp/allowed_list
# cat >> /etc/vsftpd/f_ftp/allowed_list << EOF
f_ftp
vuser1
vuser2
anonymous
ftp
EOF

Just exclude a user from this list to deny him access.
Exclude usernames anonymous and ftp if you do not plan to give anonymous access.
The users anonymous and ftp are the standard anonymous (guest) usernames of the FTP protocol.

Configure VSFTPD. Directory with configuration files 'users'

Config Directive: user_config_dir=/etc/vsftpd/f_ftp/users
The vsftpd.conf configuration files directory for each virtual user individually.
When creating a new virtual user, configure his specific parameters.
# mkdir -m 700 /etc/vsftpd/f_ftp/users/
Create an anonymous, read-only user with the name vuser1:
# cat > /etc/vsftpd/f_ftp/users/vuser1 << EOF
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
EOF
Create a private user, with the ability to write, with the name vuser2:
# cat > /etc/vsftpd/f_ftp/users/vuser2 << 
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
anon_max_rate=0
#local_root=/home/ftp_users/f_ftp/subdir
EOF

Directive anon_max_rate=0 Completely removes (equating to zero) a more general speed limit (see above "the main vsftpd.conf configuration file").
Uncomment #local_root=, to limit the user to the ability to work with only one specific [sub] directory.

Using 'f_ftp' Account

Unix-shell user f_ftp cannot log in to the FTP server. You should only set a password for him if you plan to work with account data through, say, SSH (SCP). To set a unix-shell password for a user:
# passwd f_ftp

If you want f_ftp to have access to the FTP server with this name, just make another virtual FTP user f_ftp by writing it to allowed_list:
# echo "f_ftp" >>/etc/vsftpd/f_ftp/allowed_list
And set him a password:
# cat >> /etc/vsftpd/f_ftp/virtual_users << EOF
f_ftp
f_ftp_user_pass
EOF
# db_load -T -t hash -f /etc/vsftpd/f_ftp/virtual_users /etc/vsftpd/f_ftp/virtual_users.db

Please note that the password in the virtual_users file for the virtual user f_ftp will be the password by which f_ftp will go to the FTP server, the password of the unix-shell account does not play any role here.

Bugs / Features

When using options:
  chown_username=f_ftp
  chown_uploads=YES
A file uploaded to incoming using anonymous changes its rights not taking into account anon_umask, but rigidly with 600 rights.
FIXME - requires fixing.


Option anon_max_rate limits all connections of all users, and not just connections with logins anonymous and / or ftp.
Option local_max_rate in this case does not play any role.
Having registered this or that directive in a configuration file of a specific user from "Directories with configuration files 'users'",
we will replace the settings (defaults) declared in "main configuration file 'vsftpd.conf'".
In the examples above, we thus remove the TCP limit for the speed of upload / download of files to a specific user vuser2 by setting the anon_max_rate option to zero, if not - option will play a role for this user anon_max_rate=80960 main configuration file.