Setting up an FTP server with vsFTPd on the Raspberry Pi

In this article I will demonstrate how we can set up an FTP server on the Raspberry Pi which can be used to share files across your devices. We will use vsFTPd as it is very stable, secure, and a very fast FTP server. I will also demonstrate how to configure vsFTPd to restrict users to their HOME directories, along with encrypting the entire connection using SSL/TLS.

If you want to follow this material, you must have the Raspberry Pi OS installed on your Raspberry Pi. Running an FTP server does not require a graphical interface, so I recommend installing Raspberry Pi OS Lite with the SSH service enabled, enabling remote access.

Instalar o vsFTPd no Raspberry Pi

The vsftpd package is available from the official Raspberry Pi OS repositories, so it can be installed with the following commands:

sudo apt update
sudo apt install vsftpd

After installation, the FTP server service will start automatically. To check the status of this service, run:

sudo systemctl status vsftpd

The return from this command should return “Active: active (running) since…”, something like:

vsftpd.service - vsftpd FTP server
   Loaded: loaded (/lib/systemd/system/vsftpd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2021-05-23 07:02:41 BST; 14s ago
...

How to Migrate From CentOS 8 to Rocky Linux 8/Alma Linux 8

Configure FTP server with vsFTPd

The vsFTPd configuration is done through the file /etc/vsftpd.conf .

Most of the settings are well documented, in English, in the configuration file. If you want to evaluate all available options, I recommend the official website at: Manpage of VSFTPD.CONF

1. FTP server access

To ensure that only local operating system users can access the FTP server, look for the anonymous_enable and local_enable entries in the configuration file, leaving them as follows:

anonymous_enable=NO
local_enable=YES

2. Enabling uploads

Locate and uncomment the write_enable setting to allow file system changes, enabling users to upload and remove files:

write_enable=YES

3. Chroot cage

To prevent FTP users from accessing files outside their home folder, we must create a chroot jail, uncommenting the setting chroot_local_user :

chroot_local_user=YES

When the chroot function is enabled, vsFTPd will disable file upload if the user directory is locked.

Use one of the options below to leave the chrooted environment in write mode.

Option 1 – the recommended way to enable the upload of files and leave the chroot active, configuring the FTP directories. In the following example, I will create an ftp directory inside the user’s home folder, which will serve as the folder used by chroot and will enable the files to be uploaded into it.

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

Option 2 – Another alternative is to add the allow_writeable_chroot setting in the vsftpd.conf file. This option will enable the option to write to users’ home folder.

allow_writeable_chroot=YES

4. Passive connections on FTP server

By default, vsFTPd uses active mode. To use passive mode, set the minimum and maximum range of ports used.

pasv_min_port=30000
pasv_max_port=31000

vsFTPd can use any port in passive mode. When passive mode is enabled, the FTP client opens a connection on a random port when connecting to the FTP server, at the interval you set in the configuration file.

5. Limit logging in to certain users

We can configure vsFTPd to allow only a few users to log in. To perform this configuration, add the following lines to the settings file:

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


When this setting is enabled, you must specify which users will be able to log in, adding their user names in the /etc/vsftpd.user_list file, with one user per line.

6. Secure transmission with SSL/TLS

To encrypt FTP transmission with SSL/TLS, you need to have an SSL certificate and configure the FTP server to use it. We can use an existing SSL certificate signed by a certified issuer, or create a self-signed certificate.

If you have a domain, or subdomain pointing to your FTP server IP, you can generate a free SSL certificate using Let’s Encrypt. If you’ve never used it before, follow the official documentation: Getting Started – Let’s Encrypt – Free SSL/TLS Certificates

In this article, we will generate a self-signed key using the openssl command.

Run the command below to create a 2048-bit, self-signed, 10-year private key (certificate) that is valid for 10 years. Public and private keys will be stored in the same file.

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

After creating the keys, open the vsFTPd settings file again:

sudo nano /etc/vsftpd.conf

Find the rsa_cert_file and rsa_private_key_file settings by changing their values ​​to the pem file and set the ssl_enable setting to YES.

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

If these settings are not configured correctly, the FTP server will only use TLS to secure connections.

Reboot or FTP server

When the above settings are performed, the vsFTPd settings file should look like this (without the comments):

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
allow_writeable_chroot=YES
pasv_min_port=30000
pasv_max_port=31000
userlist_enable=YES
userlist_file=/etc/vsftpd.user_list
userlist_deny=NO
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES

Save the file and restart the vsFTPd service for changes to this file to take effect:

sudo systemctl restart vsftpd

Opening the Firewall

If you use UFW Firewall in your distribution, you must release FTP traffic, opening ports 20 (FTP data), 21 (FTP commands) and 30000-31000 (passive mode ports), using the following commands:

sudo ufw allow 20:21/tcp
sudo ufw allow 30000:31000/tcp

Now, reread the UFW rules, disabling and re-enabling them.

sudo ufw disable
sudo ufw enable

Create a user for FTP

To test our FTP server, we will create a user.

  • If you already have a user that will be used and you just want to give him access, skip the first step.
  • If you have set allow_writeable_chroot=YES in your configuration file, skip the third step.

01. Create a user called novouserftp:

sudo adduser novouserftp

When prompted, set the user’s password.

02. Add the user to the list of those who can use the FTP server.

echo "novouserftp" | sudo tee -a /etc/vsftpd.user_list

03. Create FTP directory and set correct permissions.

sudo mkdir -p /home/novouserftp/ftp/upload
sudo chmod 550 /home/novouserftp/ftp
sudo chmod 750 /home/novouserftp/ftp/upload
sudo chown -R novouserftp: / home / novouserftp / ftp

As discussed earlier, the user will be able to upload files in the ftp/upload folder of their home directory.

At this point, your FTP server is fully functional and you can connect to it using FTP clients like FileZilla!

Disable shell access

By default, when a user is created, if no additional configuration is done, this user has SSH access to the server. To disable this access, create a new shell that just displays a message telling the user that this account is limited to FTP access only.

Create the shell /bin/ftponly and make it executable.

echo -e '#!/bin/sh echo "This account is limited to FTP access only."' | sudo tee -a /bin/ftponly
sudo chmod a+x /bin/ftponly

Add the new shell to the list of valid shells in the file /etc/shells :

echo "/bin/ftponly" | sudo tee -a /etc/shells

Change the created user shell to /bin/ftponly:

sudo usermod novouserftp -s / bin / ftponly

Use this last command for all users who will only have access to the FTP server.

Conclusions

Hopefully it’s clear how to install and configure a fast and secure FTP server on your Raspberry Pi system.

Be the first to comment

Leave a Reply

Your email address will not be published.


*