Vsftpd is the acronym of Very Secure FTP Daemon: it is one of the most used ftp servers on Linux and other Unix-like operating systems. It is open source and released under the GPL license, and supports virtual users and SSL for data
encryption. In this tutorial we will see how to install it and configure it on Linux.
In this tutorial you will learn:
- How to install vsftpd on Debian 10
- How to configure vsftpd
- How to setup anonymous usage
- How to setup login with local users
- How to setup virtual users
- How to setup ufw to allow incoming traffic
Software requirements and conventions used
Category | Requirements, Conventions or Software Version Used |
---|---|
System | Debian 10 (Buster) |
Software | vsftpd, openssl, libpam-pwdfile |
Other | Root permissions to install and configure vsftpd |
Conventions | # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command$ – requires given linux-commands to be executed as a regular non-privileged user |
Installation
Vsftpd is available in the official Debian repositories, therefore to install it we can use our favorite package manager; it’s just a matter of synchronizing the repositories and install the package. Both things can be accomplished by
running the following commands:
$ sudo apt-get update && sudo apt-get install vsftpd
Few seconds and the package will be installed on our Debian system. The installation scripts included in the package will also take care to start the vsftpd service automatically but we must remember to restart or reload the service each time we change the configuration file. To be able to use the virtual users feature provided by the vsftpd we also need to install another package:
$ sudo apt-get install libpam-pwdfile
We will see its usage in the dedicated section of this tutorial.
Once the needed packages are installed, we can proceed further and configure vsftpd: we will see how to do it in the next section of this tutorial.
Vsftpd setup
The vsftpd configuration file is /etc/vsftpd.conf
. If we open it we can see the various directives already contained in it. Let’s see what are the most relevant for the most common cases.
Enable anonymous login
Unauthenticated access to the server, as anonymous users, is disabled by default. To enable it, we must use the anonymous_enable
directive, which on the configuration file is placed at line 25
. All we have to do is to set it on YES
:
must change the instruction to:
anonymous_enable=YES
Another directive we may want to change is the one which let us set a directory in what vsftpd will try to navigate after an anonymous access. The directive which let us control this setting is anon_root
. Let’s say we want an anonymous user to access the /srv/ftp
directory by default, we would write:
anon_root=/srv/ftp
All the anonymous login are mapped internally to a designed user, which, by default is ftp
. To change this mapping we have to use the ftp_username
option and set it to the name of the user we want to map anonymous users to.
By default an anonymous user will not be allowed to write anything on the server, for obvious security reasons. If you want to change this behavior (not recommended) there are few options that need to be changed. First of all the general write_enable
directive must be set to YES
. This directive is commented on line 31
of the configuration file, so all you have to do is to remove the comment.
# Uncomment this to enable any form of FTP write command. write_enable=YES
Once this directive is enabled, all we have to do is to work on another two options: anon_upload_enable
and anon_mkdir_write_enable
. When the former is set to YES
an anonymous user will be able to upload files, but only if the user on which it is mapped to (as we said, ftp, by default) has write permissions on the destination directory. To activate this option, all we have to do is to remove the comment from the line 40
of the configuration file:
# 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
The anon_mkdir_write_enable
directive, instead, when set to YES
allows anonymous users to create new directories on the server, at the same conditions we saw above (the underlying user on the server must have write permissions on the parent directory). The directive is located at line 44
of the configuration file:
# Uncomment this if you want the anonymous FTP user to be able to create # new directories. anon_mkdir_write_enable=YES
Once again, since the variable is already set to YES
, for it to be relevant, all we have to do is to remove the comment from it.
To allow anonymous users to perform also other kind of write operations, as for example renaming or deleting a directory, we must use another directive which is not present in the configuration file, anon_other_write_enable
and set it to YES
if the one above is our desired behavior:
anon_other_write_enable=YES
Authenticated logins
To allow the local system users to access the ftp server with their system password, the local_enable
directive must be set to YES
: this is the default on the Debian system. The directive can be found on line 28
of the daemon
configuration file:
# Uncomment this to allow local users to log in. local_enable=YES
By default, when a local user successfully authenticates, he/she will have its own home directory as root. It is possible, however, to specify an alternative starting point by using the local_root
directive. This directive is not present in the configuration file, so we must add it if we want to use. To set the /srv/ftp
directory as local root, for example, we would write:
local_root=/srv/ftp
Chroot local users
As a security measure it is possible to chroot each authenticated user in its own home directory. To accomplish this task we must use the chroot_local_user
directive:
chroot_local_user=YES
When this feature is enabled, it is possible to specify a list of exclusions, (a list of users which should not be chrooted) using the following directives:
chroot_list_enable=YES chroot_list_file=/etc/vsftpd.chroot_list
The first directive is needed to activate the feature, the other one to specify the location of the file containing the exclusion list. The file must be created if doesn’t already exist, otherwise login will fail.
As a security measure, when an user is chrooted, it should not be able to write to the top level directory of the chroot. If it is the case, in the most recent versions of vsftpd, an user will not be able to login, and the server will respond with the following message:
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
This issue can be solved in basically two ways. This first one is obviously consists into fixing the permissions, denying the user write access to the top level directory of the chroot and letting them write only on sub-directories.
The second way to solve the problem, if you don’t care about the possible security implications, is to bypass this restriction, using the following directive:
allow_writeable_chroot=YES
Speaking about permissions, it’s important to keep in mind that the default umask for local user is set to 077
. If this setting is considered too restrictive, it is possible to change it using the local_umask
directive. This directive is commented at line 35
of the configuration file:
# 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
Login with virtual users
One nice feature offered by vsftpd is the possibility to login using virtual users. A virtual user is an user who doesn’t really exist on the system, but only in the context of the sftpd application. To enable this feature we have to use the following directive:
guest_enable=YES
When the feature is active, all non-anonymous logins (so even real/local users) are mapped to the user specified with the guest_username
directive, which by default, as we already saw is ftp.
The next step is to create a file containing the usernames and passwords of virtual users. To generate an hashed password, we can use openssl
and issue the following command:
$ openssl passwd -1 Password: Verifying - Password: $1$pfwh3Jou$DQBiNjw8bBtDqys7ezTpr.
The passwd command of openssl is used to generated hashed passwords (md5). In the example above, we were asked for the password to be hashed and its confirmation. Finally the hashed password is generated and displayed onscreen.
The username, together with the password, must be put into a file, let’s say it is /etc/virtual_users.pwd
, in the following format:
username:hashed_password
So supposing our virtual user is called “linuxconfig” we would write:
linuxconfig:$1$pfwh3Jou$DQBiNjw8bBtDqys7ezTpr.
The operation must be repeated for each virtual user we want to configure.
Now we have to create the pam service that will be used by vsftpd to authenticate virtual users. We will name the file vsftpd_virtual
and place it in the /etc/pam.d
directory. Its content will be the following:
#%PAM-1.0 auth required pam_pwdfile.so pwdfile /etc/vsftpd/virtual_users.pwd account required pam_permit.so
As you can see, we specified the path of the file containing the username and passwords of the virtual users in the first line. All we need to do, now, is to instruct vsftpd to use this pam “service”. We can do it with the pam_service_name
directive:
pam_service_name=vsftpd_virtual
At this point we can save the configuration file, restart the daemon and verify that we are able to login with the virtual user we just created.
Enabling SSL support for data encryption
By default SSL support is disabled on vsftpd, so transferred data will be not encrypted. To enable SSL support we must use the following directives, located at lines 149
to 151
of the configuration file:
# This option specifies the location of the RSA certificate to use for SSL # encrypted connections. rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key ssl_enable=YES
The first directive, rsa_cert_file
is used to indicate the path of the RSA certificate to use for SSL encrypted connections. The second one, rsa_private_key
, instead, is used to specify the location of the RSA private key. Finally, the ssl_enable
directive is used to enable the use of SSL encryption.
The example uses the /etc/ssl/certs/ssl-cert-snakeoil.pem
and /etc/ssl/private/ssl-cert-snakeoil.key
files, but you almost certainly want to use a dedicated one.
Specifying port range for passive mode
FTP passive mode is the default on a new installation of vsftpd, but if we want to be enable it explicitly we can use the following directive:
# Set to NO if you want to disallow the PASV method of obtaining a data connection # (passive mode). Default: YES pasv_enable=YES
When the server operates in passive mode, it sends to the client an IP address and port that it should listens to for connection. This ports are by default selected randomly, however, since we must use a firewall on our server, we must know what ports we should allow traffic thorough. The range of ports to use can be specified with the pasv_min_port
and pasv_max_port
directives, for example:
# 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=10090 # The maximum port to allocate for PASV style data connections. Can be used to # specify a narrow port range to assist firewalling. Default: 0 (use any port) pasv_max_port=10100
With the following configuration the server will use a range of ports that goes from 10090
to 10100
.
Firewall setup
For our vsftpd server to work correctly we must allow traffic through the needed ports, some we must setup the appropriate rules for our firewall. In this tutorial I will assume the use of the ufw firewall manager (Uncomplicated Firewall).
The first port we want to allow traffic through is port 21
, which is the standard port used by the FTP protocol:
$ sudo ufw allow in 21/tcp
As a second thing we must allow incoming traffic via the specified port range we setup in the previous section. To specify a range of ports we can run:
$ sudo ufw allow in 10090:10100/tcp
Conclusions
In this article we saw how to install and configure vsftpd on Debian 10 Buster. We saw how to setup anonymous usage and local users usage, and how we can take advantage of the virtual users feature provided by the service. Since FTP doesn’t provide data encryption, we saw how to enable SSL support, and finally how to setup the firewall to allow incoming traffic through the needed ports. For a complete list of the possible directives that can be used in the vsftpd configuration file, please take a look at the vsftpd.conf manpage (VSFTPD.CONF(5)). Want to know how to programmatically work with an FTP server? Take a look at our article on How to connect to an FTP server using python.