Graham Eddy

vsftpd Server

Install and configure vsftpd server which provides ISP-grade sftp domain-oriented service.

2022-07-28 Raspbian buster


Domain users are mapped to UNIX accounts as follows:

Domain user
user@domain
Virtual User on server
user (stored in passwd-like file, follows same rules as UNIX username)
UNIX User
vftp
UNIX group
vftp
Domain directory directory
/srv/ftp/domain (current dir on login)
UNIX user home directory
/srv/ftp/domain/user

All domain users in a domain can read/write each others' files. Domains have no view of other domains.


Installation & base configuration

graham:~ sudo apt update graham:~ sudo apt install vsftpd libpam-pwdfile graham:~ sudo systemctl stop vsftpd # stop vsftpd for updating graham:~ sudo vi /etc/vsftpd.conf
/etc/vsftpd.conf ensure these settings
listen=YES
anonymous_enable=NO
write_enable=YES
local_umask=022
dirmessage_enable=NO
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=NO
#xferlog_file=/var/log/vsftpd.log
xferlog_std_format=NO
nopriv_user=vftp
chroot_local_user=YES
ls_recurse_enable=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=YES
/etc/vsftpd.conf (continued) append to end
########################################################################
# additions to default config file

# If enabled, virtual users will use the same privileges as local users.
# By default, virtual users will use the same privileges as anonymous
# users, which tends to be more restrictive (especially in terms of write
# access).
virtual_use_local_privs=YES

# If enabled, all non-anonymous logins are classed as "guest" logins.
# A guest login is remapped to the user specified in the guest_username
# setting.
guest_enable=YES

# This option is useful is conjunction with virtual users. It is used to
# automatically generate a home directory for each virtual user, based
# on a template.
# For example, if the home directory of the real user specified via
# guest_username is /home/virtual/$USER, and user_sub_token is set to $USER,
# then when virtual user fred logs in, he will end up (usually chroot()'ed)
# in the directory /home/virtual/fred. This option also takes affect if
# local_root contains user_sub_token.
#user_sub_token=$USER

#This option represents a directory which vsftpd will try to change into
# after a local (i.e. non-anonymous) login. Failure is silently ignored.
local_root=/var/run/vsftpd/empty

# If enabled, all user and group information in directory listings will
# be displayed as "ftp".
hide_ids=YES

# See the boolean setting guest_enable for a description  of  what
# constitutes  a  guest  login.  This setting is the real username which
# guest users are mapped to.
guest_username=vftp

# Set to NO if you want to disallow the PASV method of obtaining a data
# connection.
pasv_enable=YES

# The  minimum  port  to allocate for PASV style data connections. Can be
# used to specify a  narrow  port  range  to  assist  firewalling.
pasv_min_port=30000

# The  maximum  port  to allocate for PASV style data connections. Can be
# used to specify a  narrow  port  range  to  assist  firewalling.
pasv_max_port=30100

# If  enabled,  then  any  log  output  which  would  have gone to
# /var/log/vsftpd.log goes to the system log instead.  Logging  is done
# under the FTPD facility.
syslog_enable=YES

# This powerful option allows the override of any config option specified
# in the manual page, on a per-user basis. Usage is simple, and is best
# illustrated with an example.
# If you set user_config_dir to be /etc/vsftpd_user_conf and then log on
# as the user "chris", then vsftpd will apply the settings in the file
# /etc/vsftpd_user_conf/chris for the duration of the session.
# The format of this file is as detailed in this manual page! PLEASE NOTE
# that not all settings are effective on a per-user basis. For example,
# many settings only prior to the user's session being started.
# Examples of settings which will not affect any behviour on a per-user
# basis include listen_address, banner_file, max_per_ip, max_clients,
# xferlog_file, etc.
user_config_dir=/etc/vsftpd/users

# When enabled, all FTP requests and responses are logged, providing the
# option xferlog_std_format is not enabled. Useful for debugging.
log_ftp_protocol=YES
graham:~ sudo mkdir -p /srv/ftp # container for per-domain shares graham:~ sudo adduser --no-create-home --home /srv/ftp \ --shell /usr/sbin/nologin --gecos 'virtual ftp users' vftp # proxy user for all domain users graham:~ sudo usermod --expiredate 1 vftp graham:~ sudo mkdir -p /etc/vsftpd/users # authentication for all domain users graham:~ sudo touch /etc/vsftpd/passwd graham:~ sudo vi /etc/pam.d/vsftpd
/etc/pam.d/vsftpd replace all content
auth    required pam_pwdfile.so pwdfile /etc/vsftpd/passwd legacy_crypt
account required pam_permit.so
graham:~ sudo vi /etc/rsyslog.d/vsftpd.conf
/etc/rsyslog.d/vsftpd.conf new file
:programname, isequal, "vsftpd"  /var/log/vsftpd.log
:programname, isequal, "vsftpd"  stop
graham:~ sudo systemctl restart rsyslog graham:~ sudo systemctl start vsftpd # start vsftpd again graham:~ sudo tail /var/log/vsftpd.log

Add a domain

Add domain geddy.au.

graham:~ sudo mkdir -p /srv/ftp/geddy.au # container for this domain's shares graham:~ sudo chown root:root /srv/ftp/geddy.au graham:~ sudo chmod 755 /srv/ftp/geddy.au graham:~ sudo vi /etc/vsftpd/users/@geddy.au # template user config for this domain
/etc/vsftpd.users/@geddy.au new file
local_root=/srv/ftp/geddy.au

Add a virtual user

Add domain user fred.nerk to domain geddy.au.

graham:~ sudo ln -s /etc/vsftpd/users/@geddy.au /etc/vsftpd/users/fred.nerk@geddy.au graham:~ echo "fred.nerk:$(openssl passwd -1)" | \ sudo tee -a /etc/vsftpd/passwd # apply template user config for this user Password: fred.nerk's password graham:~ sudo mkdir /srv/ftp/geddy.au/fred.nerk # container of this domain user's share graham:~ sudo chown vftp:vftp /srv/ftp/geddy.au/fred.nerk graham:~ sudo chmod 2775 /srv/ftp/geddy.au/fred.nerk