How to set up vsftpd for user directories on Ubuntu 16.04

Introduction

FTP is the abbreviation of File Transfer Protocol, a network protocol that was once widely used to move files between clients and servers. It has been replaced by faster, safer and more convenient file transfer methods. Many casual netizens want to download it directly from their web browser using https, and it is easier for command line users to use secure protocols such as scp or SFTP.

FTP is still used to support legacy applications and workflows with specific requirements. If you can choose which protocol to use, consider exploring more modern options. However, when you do need FTP, vsftpd is a good choice. vsftpd is optimized for security, performance and stability, can well prevent many security problems existing in other FTP servers, and is the default setting for many Linux distributions.

In this tutorial, we will show you how to configure vsftpd to allow a user to upload files to his or her home directory using FTP with SSL/TLS protected login credentials.

prerequisites

To follow this tutorial, you need:

Once you have an Ubuntu server, you can start.

Step 1-Install vsftpd

We first update our package list and install the vsftpd daemon:

sudo apt-get update
sudo apt-get install vsftpd

After the installation is complete, we will copy the configuration file so that we can start with a blank configuration and save the original file as a backup.

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig

By backing up the configuration, we are ready to configure the firewall. If you are using Tencent Cloud's CVM server, you can directly set it in Security Group in the Tencent Cloud console.

Step 2-Turn on the firewall

We will check the firewall status to see if it is enabled. If so, we will make sure to allow FTP traffic so that you don't encounter firewall rules that prevent you from testing.

sudo ufw status

In this case, only SSH is allowed:

Status: active
​
To Action  From
------------
OpenSSH ALLOW   Anywhere
OpenSSH(v6)   ALLOW   Anywhere(v6)

You may have other rules or no firewall rules at all. Since ssh only allows traffic in this case, we need to add rules for FTP traffic.

We need to open ports 20 and 21 for FTP, port 990 for us to enable TLS in the future, and ports 40000-50000 for the passive port range we plan to set in the configuration file:

sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 990/tcp
sudo ufw allow 40000:50000/tcp
sudo ufw status

Now our firewall rules are as follows:

Status: active
​
To                         Action      From
------------
OpenSSH                    ALLOW       Anywhere
990 /tcp                    ALLOW       Anywhere
20 /tcp                     ALLOW       Anywhere
21 /tcp                     ALLOW       Anywhere
40000:50000 /tcp            ALLOW       Anywhere
OpenSSH(v6)               ALLOW       Anywhere(v6)20/tcp(v6)                ALLOW       Anywhere(v6)21/tcp(v6)                ALLOW       Anywhere(v6)990/tcp(v6)               ALLOW       Anywhere(v6)40000:50000/tcp(v6)       ALLOW       Anywhere(v6)

With vsftpd installed and the necessary ports opened, we are ready to proceed to the next step.

Step 3-Prepare User Directory

For this tutorial, we will create a user, but you may already have a user who needs FTP access. We will take care to retain existing users' access to the data in the following instructions. Even so, we recommend that you contact the new user before configuring and testing the settings.

First, we will add a test user:

sudo adduser sammy

Assign a password when prompted, you can press "ENTER" at other prompts.

When users are restricted to specific directories, FTP is usually more secure. vsftpd uses chrootjails to complete this step. When local users start chroot, they will be restricted to their home directory by default. However, due to the way vsftpd protects the directory, the user cannot write it. This is great for new users who should only connect via FTP, but existing users may need to write to their home folder (if they also have shell access).

In this example, we will create a ftp directory as a chroot, and create a writable files directory to store actual files, instead of removing writable permissions from the home directory.

Create the ftp folder, set its ownership, and make sure to remove write permissions with the following command:

sudo mkdir /home/sammy/ftp
sudo chown nobody:nogroup /home/sammy/ftp
sudo chmod a-w /home/sammy/ftp

Let's verify permissions:

sudo ls -la /home/sammy/ftp
total 84 dr-xr-xr-x  2 nobody nogroup 4096 Aug 2421:29.4 drwxr-xr-x 3 sammy  sammy   4096 Aug 2421:29..

Next, we will create a directory where files can be uploaded and assign ownership to the user:

sudo mkdir /home/sammy/ftp/files
sudo chown sammy:sammy /home/sammy/ftp/files

A permission check on the files directory should return the following:

sudo ls -la /home/sammy/ftp
Outputtotal 12
dr-xr-xr-x 3 nobody nogroup 4096 Aug 2614:01.
drwxr-xr-x 3 sammy  sammy   4096 Aug 2613:59..
drwxr-xr-x 2 sammy  sammy   4096 Aug 2614:01 files

Finally, we will add the file test.txt to be used in future tests:

echo "vsftpd test file"| sudo tee /home/sammy/ftp/files/test.txt

Now that we have secured the ftp directory and allowed users to access the files directory, we turn our attention to configuration.

Step 4-Configure FTP access

We plan to allow a single user with a local shell account to connect with FTP. Two key settings have been placed in vsftpd.conf. First open the configuration file and verify that the settings in the configuration match the following settings:

sudo nano /etc/vsftpd.conf
...
# Allow anonymous FTP?(Disabled by default).
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
local_enable=YES
...

Next, we need to change some values in the file. In order to allow users to upload files, we will uncomment the write_enable setting so that we have:

...
write_enable=YES
...

We will also uncomment the chroot to prevent FTP connected users from accessing any files or commands outside the directory tree.

...
chroot_local_user=YES
...

We will add a user_sub_token to insert the username in our local_root directory path so that our configuration applies to this user and any future users that may be added.

user_sub_token=$USER
local_root=/home/$USER/ftp

We will limit the range of ports that can be used for passive FTP to ensure that enough connections are available:

pasv_min_port=40000
pasv_max_port=50000

**Note: **We pre-opened the ports we set here for the passive port range. If you change the value, be sure to update the firewall settings.

Since we only intend to allow FTP access based on specific circumstances, we will set up the configuration so that users can only be accessed when they are explicitly added to the list and not by default:

userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

userlist_deny can switch logic. When it is set to "YES", the users in the list are denied FTP access. When it is set to "NO", only users in the list are allowed to access. After making changes, save and exit the file.

Finally, we will create users and add them to the file. We will use the -a flag to append to the file:

echo "sammy"| sudo tee -a /etc/vsftpd.userlist

Double check that it was added as expected:

cat /etc/vsftpd.userlist
sammy

Restart the daemon to load configuration changes:

sudo systemctl restart vsftpd

Now we are ready to test.

Step 5-Test FTP access

We have configured the server to only allow the user sammy to connect via FTP. Let us make sure this is the case.

Anonymous users should not be able to connect: We have disabled anonymous access. Here, we will test by trying to connect anonymously. If we have done it correctly, we should deny access to anonymous users:

ftp -p 203.0.113.0
Connected to 203.0.113.0.220(vsFTPd 3.0.3)Name(203.0.113.0:default): anonymous
530 Permission denied.
ftp: Login failed.
ftp>

Close the connection:

bye

The other user sammy should not be able to connect: Next, we will try to connect as the sudo user. They should also be denied access, and it should happen before they are allowed to enter the password.

ftp -p 203.0.113.0
Connected to 203.0.113.0.220(vsFTPd 3.0.3)Name(203.0.113.0:default): sudo_user
530 Permission denied.
ftp: Login failed.
ftp>

Close the connection:

bye

sammy should be able to connect, as well as read and write files: Here, we will ensure that our designated users can connect:

ftp -p 203.0.113.0
Connected to 203.0.113.0.220(vsFTPd 3.0.3)Name(203.0.113.0:default): sammy
331 Please specify the password.
Password: your_user's_password
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

We will change to the files directory, and then use the get command to transfer the test file we created earlier to the local computer:

cd files
get test.txt
227 Entering Passive Mode(203,0,113,0,169,12).150 Opening BINARY mode data connection for test.txt(16 bytes).226 Transfer complete.16 bytes received in0.0101seconds(1588 bytes/s)
ftp>

We will turn right and try to upload a file with a new name to test write access:

put test.txt upload.txt
227 Entering Passive Mode(203,0,113,0,164,71).150 Ok to send data.226 Transfer complete.16 bytes sent in0.000894seconds(17897 bytes/s)

Close the connection:

bye

Now that we have tested our configuration, we will take steps to further protect our server.

Step 6-Secure the transaction

Because FTP does not encrypt any data during transmission, including user credentials, we will enable TTL/SSL to provide encryption. The first step is to create an SSL certificate for vsftpd.

We will use openssl to create a new certificate and use the -days flag to make it valid for one year. In the same command, we will add a private 2048-bit RSA key. Then by setting the -keyout and -out flags to the same value, the private key and certificate will be in the same file.

We will use the following command to do this:

sudo openssl req -x509 -nodes -days 365-newkey rsa:2048-keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem

You will be prompted to provide the address information of the certificate. Replace your own information with the following questions:

Generating a 2048 bit RSA private key
............................................................................+++...........+++
writing newprivate key to '/etc/ssl/private/vsftpd.pem'-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.-----
Country Name(2 letter code)[AU]:US
State or Province Name(full name)[Some-State]:NY
Locality Name(eg, city)[]:New York City
Organization Name(eg, company)[Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name(eg, section)[]:
Common Name(e.g. server FQDN or YOUR name)[]: your_IP_address
Email Address []:

For more detailed information about certificate signs, please refer to Tencent Cloud SSL Certificate Service

After creating the certificate, open the vsftpd configuration file again:

sudo nano /etc/vsftpd.conf

At the bottom of the file, you should have two lines starting with rsa_. Comments make them look like:

# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

Below them, add the following lines, which point to the certificate and private key we just created:

rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem

After that, we will force the use of SSL, which will prevent client connections that cannot handle TLS. This is necessary to ensure that all traffic is encrypted, but may force your FTP users to change the client. Change ssl_enable to YES:

ssl_enable=YES

After that, add the following line to explicitly reject anonymous connections over SSL and require SSL for data transmission and login:

allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

After this, we configure the server to use TLS, which is the preferred successor to SSL, adding the following line:

ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

Finally, we will add two options. First of all, we will not require the reuse of SSL because it may break many FTP clients. We will need a "high" encryption cipher suite, which currently means that the key length is equal to or greater than 128 bits:

require_ssl_reuse=NO
ssl_ciphers=HIGH

When finished, save and close the file.

Now, we need to restart the server for the changes to take effect:

sudo systemctl restart vsftpd

At this point, we will no longer be able to connect using insecure command line clients. If we tried, we would see something like:

ftp -p 203.0.113.0
Connected to 203.0.113.0.220(vsFTPd 3.0.3)Name(203.0.113.0:default): sammy
530 Non-anonymous sessions must use encryption.
ftp: Login failed.421 Service not available, remote server has closed connection
ftp>

Next, we will verify whether we can connect using a client that supports TLS.

Step 7-Use FileZilla to test TLS

Most modern FTP clients can be configured to use TLS encryption. We will demonstrate how to connect using FileZilla because it supports cross-platform. Please refer to the documentation of other customers.

When opening FileZilla for the first time, find the "Site Manager" icon below the text, which is the leftmost icon on the top line. click it:

A new window will open. Click the "New Site" button in the lower right corner:

Under "My Site", a new icon with the words "New Site" will appear. You can name it now or go back later and use the "Rename" button.

You must fill in the "Host" field with a name or IP address. Under the "Encryption" drop-down menu, select "Require explicit FTP over TLS".

For "Login Type", select "Ask Password". Fill in the FTP user you created in the "User" field:

Click "Connect" at the bottom of the interface. The system will ask you to enter the user password:

Click "OK" to connect. You should now use TLS/SSL encryption to connect with your server.

After you accept the certificate, double-click the files folder and drag upload.txt to the left to confirm that you can download the file.

When you are done, right-click on the local copy, rename it to upload-tls.txt` and drag it back to the server to confirm that you can upload the file.

You have now confirmed that you can safely and successfully transfer SSL/TLS-enabled files.

Step 8-Disable Shell Access (optional)

If TLS cannot be used due to client requirements, you can gain some security by disabling FTP users to log in in any other way. A relatively simple method is to prevent it by creating a custom shell. This will not provide any encryption, but will restrict the infected account's access to FTP-accessible files.

First, open the file named ftponly in the bin directory:

sudo nano /bin/ftponly

We will add a message to tell users why they cannot log in. Paste as follows:

#! /bin/sh
echo "This account is limited to FTP access only."

Change permissions to make the file executable:

sudo chmod a+x /bin/ftponly

Open the list of valid shells:

sudo nano /etc/shells

At the bottom, add:

... /bin/ftponly

Update the user's shell with the following command:

sudo usermod sammy -s /bin/ftponly

Now try to log in as sammy:

ssh [email protected]

You should see something like:

This account is limited to FTP access only.
Connection to 203.0.113.0 closed.

This confirms that users can no longer use ssh to access the server, only FTP access.

in conclusion

In this tutorial, we covered setting up FTP for users with local accounts. If you need to use an external authentication source, you may need to understand vsftpd's support for virtual users. This provides a wealth of options through the use of PAM (pluggable authentication module), which is a good choice if you manage users in other systems (such as LDAP or Kerberos).

For more Ubuntu tutorials, please go to [Tencent Cloud + Community] (https://cloud.tencent.com/developer?from=10680) to learn more.


Reference: "How To Set Up vsftpd for a User's Directory on Ubuntu 16.04"

Recommended Posts

How to set up vsftpd for user directories on Ubuntu 16.04
How to set up vsftpd for anonymous downloads on Ubuntu 16.04
How to set up Gogs on Ubuntu 14.04
How to set up R on Ubuntu 14.04
How to set up Shiny Server on Ubuntu 14.04
How to set up time synchronization on Ubuntu 18.04
How to set up Ghost one-click app for Ubuntu 16.04
How to set up Java Home on Ubuntu and Raspbian
How to set up a Masterless Puppet environment on Ubuntu 14.04
How to set up a firewall with UFW on Ubuntu 14.04
How to set up an Apache virtual host on Ubuntu 16.04
How to set up an Apache virtual host on Ubuntu 20.04
How to set up password authentication with Nginx on Ubuntu 14.04
How to set PostgreSQL startup on Ubuntu 16.04
How to set static IP on Ubuntu 18.04 Server
How to set static IP on Ubuntu 18.04 Server
How to set up SSH keys on CentOS 8
Explain how to set static IP on ubuntu14.04
How to change root user password on Ubuntu
How to set a fixed IP based on Ubuntu 16.04
How to install Ruby on Ubuntu 20.04
How to install Memcached on Ubuntu 20.04
How to install Java on Ubuntu 20.04
How to install MySQL on Ubuntu 20.04
How to install VirtualBox on Ubuntu 20.04
How to install Elasticsearch on Ubuntu 20.04
How to set up an Apache virtual host on CentOS 7
How to install Nginx on Ubuntu 20.04
How to install Apache on Ubuntu 20.04
How to install Git on Ubuntu 20.04
How to install Node.js on Ubuntu 16.04
How to install MySQL on Ubuntu 20.04
How to install Vagrant on Ubuntu 20.04
How to install PostgreSQL on Ubuntu 16.04
How to install Git on Ubuntu 20.04
How to install Memcached on Ubuntu 18.04
How to install Jenkins on Ubuntu 16.04
How to install MemSQL on Ubuntu 14.04
How to install MongoDB on Ubuntu 16.04
How to install Mailpile on Ubuntu 14.04
How to upgrade to PHP 7 on Ubuntu 14.04
How to install Skype on Ubuntu 20.04
How to install Jenkins on Ubuntu 20.04
How to install Python 3.8 on Ubuntu 18.04
How to install KVM on Ubuntu 18.04
How to install KVM on Ubuntu 20.04
How to install opencv3.0.0 on ubuntu14.04
How to install Anaconda on Ubuntu 20.04
How to install Jenkins on Ubuntu 18.04
How to install Apache on Ubuntu 20.04
How to install R on Ubuntu 20.04
How to set or modify the time zone on Ubuntu 20.04
How to install Moodle on Ubuntu 16.04
How to install Teamviewer on Ubuntu 16.04
How to secure Nginx on Ubuntu 14.04
How to install MariaDB on Ubuntu 20.04
How to install Nginx on Ubuntu 20.04
How to install Go on Ubuntu 20.04
How to install Zoom on Ubuntu 20.04
How to install Nginx on Ubuntu 16.04
How to create a Sudo user on Ubuntu [Quick Start]