Secure FTP server -
- Proficiency with a command-line editor (using
viin this example)
- A heavy comfort level with issuing commands from the command-line, viewing logs, and other general systems administrator duties
- An understanding of PAM, and
opensslcommands are helpful
- Running commands here with the root user or a regular user and
vsftpd is the Very Secure FTP Daemon (FTP being the file transfer protocol). It has been available for many years, and is the default FTP daemon in Rocky Linux and many other Linux distributions.
vsftpd allows for the use of virtual users with pluggable authentication modules (PAM). These virtual users do not exist in the system and have no other permissions except FTP. If a virtual user gets compromised, the person with those credentials will have no other permissions after gaining access as that user. This setup is very secure but requires a bit of extra work.
Even with the security settings used here to set up
vsftpd, you may want to consider
sftp will encrypt the entire connection stream and is more secure. We have created a document called Secure Server -
sftp that deals with setting up
sftp and the locking down SSH.
You must also ensure the
openssl installation. If you are running a web server, this probably is already installed, but just to verify you can run:
dnf install vsftpd openssl
You will also want to enable the vsftpd service:
systemctl enable vsftpd
Do not start the service just yet.
You want to ensure the disabling of some settings and enabling others. Generally, installing
vsftpd includes the most sane options already set. It is still a good idea to verify them.
To check the configuration file and make changes when necessary, run:
Look for the line "anonymous_enable=" and ensure that it is "NO" and that it is NOT commented out. (Commenting out this line will enable anonymous logins). The line will look like this when it is correct:
Ensure that "local_enable" is yes:
Add a line for the local root user. If the server is a web server, and you use the Apache Web Server Multi-Site Setup, your local root will reflect that. If your setup is different, or if this is not a web server, adjust the "local_root" setting:
Ensure that "write_enable" is yes also:
Find the line to "chroot_local_users" and remove the remark. Add two lines after that shown here:
chroot_local_user=YES allow_writeable_chroot=YES hide_ids=YES
Beneath this you want to add a section that will deal with virtual users:
# Virtual User Settings user_config_dir=/etc/vsftpd/vsftpd_user_conf guest_enable=YES virtual_use_local_privs=YES pam_service_name=vsftpd nopriv_user=vsftpd guest_username=vsftpd
You need to add a section near the bottom of the file to force encryption of passwords sent over the internet. You need
openssl installed and you must also create the certificate for this.
Start by adding these lines at the bottom of the file:
rsa_cert_file=/etc/vsftpd/vsftpd.pem rsa_private_key_file=/etc/vsftpd/vsftpd.key ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO pasv_min_port=7000 pasv_max_port=7500
Save your configuration. (SHIFT+:+wq for
Setting up the RSA certificate¶
You need to create the
vsftpd RSA certificate file. The author generally figures that a server is good for 4 or 5 years. Set the number of days for this certificate based on the number of years you believe you will have the server up and running on this hardware.
Edit the number of days as you see fit, and use the format of this command to create the certificate and private key files:
openssl req -x509 -nodes -days 1825 -newkey rsa:2048 -keyout /etc/vsftpd/vsftpd.key -out /etc/vsftpd/vsftpd.pem
Like all certificate creation processes, this will start a script that will ask you for some information. This is not a difficult process. You will leave many fields blank.
The first field is the country code field, fill this one in with your country two letter code:
Country Name (2 letter code) [XX]:
Next comes the state or province, fill this in by typing the whole name, not the abbreviation:
State or Province Name (full name) :
Next is the locality name. This is your city:
Locality Name (eg, city) [Default City]:
Next is the company or organizational name. You can leave this blank or fill it in. It is optional:
Organization Name (eg, company) [Default Company Ltd]:
Next is the organizational unit name. You can fill this in if the server is for a specific division, or leave it blank:
Organizational Unit Name (eg, section) :
The following field needs filling in, but you can decide how you want it. This is the common name of your server. Example:
Common Name (eg, your name or your server's hostname) :
The email field can be left blank:
Email Address :
When completed, the certificate creation will occur.
Setting up virtual users¶
As stated earlier, using virtual users for
vsftpd is much more secure because they have no system privileges. That said, you need to add a user for the virtual users. You also need to add a group:
groupadd nogroup useradd --home-dir /home/vsftpd --gid nogroup -m --shell /bin/false vsftpd
The user must match the
guest_username= line in the
Go to the configuration directory for
You need to create a password database. You use this database to authenticate our virtual users. You need to create a file to read the virtual users and passwords. This will create the database.
In the future, when adding users, you will want to duplicate this process again:
The user and password are line separated, enter the user, hit ENTER, and enter the password. Continue until you have added all of the users you currently want to have access to the system. Example:
user_name_a user_password_a user_name_b user_password_b
When done creating the text file, you want to generate the password database that
vsftpd will use for the virtual users. Do this with the command
db_load is provided by
libdb-utils which should be loaded on your system, but if it is not, you can simply install it with:
dnf install libdb-utils
Create the database from the text file with:
db_load -T -t hash -f vusers.txt vsftpd-virtual-user.db
Take just a moment here to review what
db_load is doing:
- The -T allows the import of a text file into the database
- The -t says to specify the underlying access method
- The hash is the underlying access method you are specifying
- The -f says to read from a specified file
- The specified file is vusers.txt
- And the database you are creating or adding to is vsftpd-virtual-user.db
Change the default permissions of the database file:
chmod 600 vsftpd-virtual-user.db
Remove the "vusers.txt" file:
When adding users, use
vi to create another "vusers.txt" file, and re-run the
db_load command, which will add the users to the database.
Setting up PAM¶
vsftpd installs a default pam file when you install the package. You are going to replace this with your own content. Always make a backup copy of the old file first.
Make a directory for your backup file in /root:
Copy the pam file to this directory:
cp /etc/pam.d/vsftpd /root/backup_vsftpd_pam/
Edit the original file:
Remove everything in this file except the "#%PAM-1.0" and add in the following lines:
auth required pam_userdb.so db=/etc/vsftpd/vsftpd-virtual-user account required pam_userdb.so db=/etc/vsftpd/vsftpd-virtual-user session required pam_loginuid.so
Save your changes and exit (SHIFT+:+wq in
This will enable login for your virtual users defined in
vsftpd-virtual-user.db, and will disable local logins.
Setting up the virtual user's configuration¶
Each virtual user has a configuration file, specifying their own "local_root" directory. Ownership of this local root is the user "vsftpd" and the group "nogroup".
Refer to Setting Up Virtual Users section above. To change the ownership for the directory, enter this at the command line:
chown vsftpd.nogroup /var/www/sub-domains/whatever_the_domain_name_is/html
You need to create the file that has the virtual user's configuration:
mkdir /etc/vsftpd/vsftpd_user_conf vi /etc/vsftpd/vsftpd_user_conf/username
This will have a single line in it that specifies the virtual user's "local_root":
Specification of this path is in the "Virtual User" section of the
vsftpd service and test your users, assuming that the service starts correctly:
systemctl restart vsftpd
You can test your setup with the command line on a machine and test access to the machine with FTP. That said, the easiest way to test is to test with an FTP client, such as FileZilla.
When you test with a virtual user to the server running
vsftpd, you will get an SSL/TLS certificate trust message. This trust message tells the person that the server uses a certificate and asks them to approve it before continuing. You can place files in the "local_root" folder when connected as a virtual user.
If you are unable to upload a file, you might need to go back and verify each of the steps again. For instance, it might be that the ownership permissions for the "local_root" are not set to the "vsftpd" user and the "nogroup" group.
vsftpd is a popular and common FTP server and can be a stand-alone server, or part of an Apache Hardened Web Server. It is pretty secure if set up to use virtual users and a certificate.
This procedure has many steps to for setting up
vsftpd. Taking the extra time to set it up correctly will ensure that your server is as secure as it can be.
Author: Steven Spencer
Contributors: Ezequiel Bruni, Ganna Zhyrnova