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.