VSFTPD Virtual User Configuration with Umask Settings Explained

Setup Overview

(1) Implementing virtual user authentication
(2) Creating separate read-write and read-only accounts

Working Configuration Setup

(1) Install required packages

# yum -y install vsftpd pam pam-devel

(2) Authentication configuration

# vim /etc/pam.d/vsftpd 
#%PAM-1.0
auth required /lib64/security/pam_userdb.so  db=/etc/vsftpd/vsftpd_login
account required /lib64/security/pam_userdb.so db=/etc/vsftpd/vsftpd_login

# vim /etc/vsftpd/vsftpd.conf 
listen=YES
connect_from_port_20=YES
ftpd_banner=Secure File Transfer Service
idle_session_timeout=300
data_connection_timeout=300
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
anonymous_enable=NO
local_enable=YES
anon_upload_enable=NO
anon_mkdir_write_enable=NO
anon_other_write_enable=NO
chroot_local_user=YES
allow_writeable_chroot=YES
local_umask=022
guest_enable=YES
guest_username=ftpuser
virtual_use_local_privs=YES
max_per_ip=50
use_localtime=YES
chroot_list_enable=YES
pam_service_name=vsftpd
user_config_dir=/etc/vsftpd/vsftpd_user_conf
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
reverse_lookup_enable=NO
use_localtime=YES

User-specific configurations for read-only and read-write access

# mkdir /etc/vsftpd/vsftpd_user_conf
# vim readonly_user 
local_root=/opt/www/assets
# vim  upload_user
write_enable=YES
local_root=/opt/www/assets

Credential file setup

# vim /etc/vsftpd/login.pass
readonly_user
simplepass
upload_user
simplepass

# db_load -T -t hash -f /etc/vsftpd/login.pass /etc/vsftpd/vsftpd_login.db

(3) Execute systemctl restart vsftpd to restart the service. Users can now log into FTP using either readonly_user or upload_user credentials.

Configuration Considerations

(1) Understanding chroot_list_enable and chroot_local_user interaction

Let's examine both options:

chroot_list_enable
  When activated, you can specify local users who are placed in a chroot() jail within their home directory upon login. The behavior changes when chroot_local_user is set to YES. In this scenario, the list represents users who should NOT be placed in a chroot() jail. By default, the file containing this list is /etc/vsftpd/chroot_list, but you can override this with the chroot_list_file directive.

  Default: NO

chroot_local_user
  When set to YES, local users will be placed in a chroot() jail within their home directory after login. Warning: This option has security implications, particularly if users have upload permissions or shell access. Enable only when you understand the implications. Note that these security concerns apply to all FTP daemons offering chroot() functionality.

  Default: NO

The documentation clearly states that when both chroot_local_user and chroot_list_enable are set to YES, users listed in /etc/vsftpd/chroot_list are exempt from chroot restrictions. This requires careful attention!

For example, if readonly_user appears in /etc/vsftpd/chroot_list:

# cat /etc/vsftpd/chroot_list
readonly_user

Testing with readonly_user login:

# ftp localhost
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
220 Secure File Transfer Service
Name (localhost:root): readonly_user      
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (127,0,0,1,130,118).
150 Here comes the directory listing.
drwxr-xr-x   40 1000     1000         8192 Apr 26 11:02 assets
lrwxrwxrwx    1 1000     1000            6 Jun 06 16:00 backup_files -> assets
226 Directory send OK.
ftp> cd /       ## Successfully navigates to root directory
250 Directory successfully changed.
ftp> ls
227 Entering Passive Mode (127,0,0,1,75,155).
150 Here comes the directory listing.
lrwxrwxrwx    1 0        0               7 Apr 30  2020 bin -> usr/bin
dr-xr-xr-x    5 0        0            4096 Sep 29  2023 boot
...... output omitted


This demonstrates direct access to the root filesystem, creating significant security vulnerabilities that require immediate attention! (With the proper configuration, removing the readonly_user from /etc/vsftpd/chroot_list resolves this issue)

(2) Umask configuraton considerations

Key umask-related settings:

anon_umask
  Sets the umask value for file creation by anonymous users. NOTE! For octal values, include the "0" prefix; otherwise, the value will be interpreted as decimal!

  Default: 077
 
local_umask
  Sets the umask value for file creation by local users. NOTE! For octal values, include the "0" prefix; otherwise, the value will be interpreted as decimal!

  Default: 077

Additional important paramter:

virtual_use_local_privs
  When enabled, virtual users will have the same privileges as local users. By default, virtual users operate with anonymous user privileges, which are typically more restrictive (especially regarding write permissions).

  Default: NO

A common isue occurs when administrators configure vsftpd but find uploaded files have permissions of 600 and directories 700, despite setting local_umask=022. The expected permissions (644 for files, 755 for directories) don't appear. This typically relates to virtual user configuration, specifically when virtual_use_local_privs isn't properly set to YES.

Summary

When encountering unexpected behavior with vsftpd, consult the documentation using man vsftpd.conf to verify configuration parameters. Check system file ownership, permissions, and related directory structures for correctness.

Tags: vsftpd FTP virtual-users umask chroot

Posted on Sun, 12 Jul 2026 17:32:51 +0000 by busin3ss