How to Configure a VSFTP Server to Run in Passive Mode on Ubuntu 20.04 and Debian 11
Beyond being fast and stable, VSFTPD is secure compared to regular FTP servers. Thankfully, it is the default FTP server on some of the most popular Linux distros, including Ubuntu. But even if it isn’t the default FTP server on your Linux machine, you can always configure it.
Below, I talk about how to configure a VSFTP server on Ubuntu 20.04 and Debian 11.
Table of Contents
- Installing VSFTPD
- Adjusting Firewall Rules
- Creating the VSFTP User and Home Directory
- Create a local_root Directory, Remove Its Write Permission, and Change Its Owner and Group
- Create a Files Directory with Write Permission in the local_root Directory
- Configuring VSFTPD
- Test Your VSFTPD
Install VSFTPD
To install VSFTPD on your server, run the following commands:
#This updates the apt repos.
sudo apt update
Then
#This installs vsftpd
sudo apt install vsftpd
To confirm that VSFTPD has been installed and is active, run
sudo systemctl status vsftpd
Adjusting Firewall Rules
Allow Command Port
Your VSFTP server must allow incoming connections on port 21. Port 21 is the FTP command port; when on passive mode, it does the following:
- It receives the PASV command from the FTP client.
- The server sends a PORT command to the FTP client through port 21.
To allow incoming connections to port 21 on your server, run:
sudo ufw allow 21
Define and Allow Passive Port Range
The passive port range is the range of ports the client can connect to on the server for file transfer.
In this case, our passive port range will be 4000–5000. To allow incoming connections on the ports within that range, we will run:
sudo ufw allow 4000:5000/tcp
Creating the FTP User and Home Directory
Ordinarily, you can use the regular users on your server for FTP. But then, this is generally insecure. For one, you will have to divulge the credentials of such user to the FTP client, leaving it vulnerable. But you can avoid that by creating a user dedicated to FTP processes only.
The command for creating an FTP user is the same as the command for creating a regular user on Linux:
sudo useradd -m ftp_user
The -m
flag ensures that the ftp_user
is created with a home directory.
After creating the ftp_user, create a password for it:
sudo passwd ftp_user
After running the command above, follow the prompt and input the password you want for the ftp_user.
Create a local_root Directory, Remove Its Write Permission, and Change Its Owner and Group
VSFTPD comes with chroot jail — a security feature that restricts FTP clients and the FTP user to the FTP user’s home directory. However, to activate chroot jail, the FTP user’s home directory (which we will use as local_root
) must have no write permission.
If your FTP user is a new user dedicated to FTP processes only, removing write permissions may not be an issue. However, if your FTP user is an existing user - one that you’ve been using for write processes in its home directory - removing write permissions would be an issue.
In our case, ftp_user
is dedicated to FTP processes, so we can just remove write permission on its home directory before activating chroot jail by running:
#remove write permissions
sudo chmod 555 /home/ftp_user
#change owner and group to nobody and nogroup
sudo chown nobody:nogroup /home/ftp_user
But if ftp_user
is an existing user — a user not meant solely for FTP processes, we can create a new directory within its home directory and use that directory as our local_root
. Here’s how:
#creating a new directory named ftp in the ftp_user home directory
sudo mkdir /home/ftp_user/ftp
#change owner and group to nobody and nogroup
sudo chown nobody:nogroup /home/ftp_user/ftp
#remove write permissions
sudo chmod 555 /home/ftp_user/ftp
We change the owner and group of the local_root
directory to nobody and nogroup for extra security. Nobody and nogroup have the least privilege on Linux machines; they have no home directories, login credentials, or special privileges. So, it is hard to compromise the server through them.
Create a Files Directory with Write Permission in the local_root Directory
If your ftp_user
is dedicated to FTP processes:
#creating the files directory
sudo mkdir /home/ftp_user/files
#changing owner and group of the files directory to ftp_user
sudo chown ftp_user:ftp_user /home/ftp_user/files
If your ftp_user
is an existing user (not dedicated to FTP processes):
#creating the files directory
sudo mkdir /home/ftp_user/ftp/files
#changing owner and group of the files directory to ftp_user
sudo chown ftp_user:ftp_user /home/ftp_user/ftp/files
Create a test file in the files directory; we’ll use this when testing the VSFTPD configuration:
#if your FTP user is a dedicated user
echo "This is a test file" | tee /home/ftp_user/files/testfile
#if your FTP user is not a dedicated user
echo "This is a test file" | tee /home/ftp_user/ftp/files/testfile
Configuring VSFTPD
After creating the necessary directories and adjusting ownership and permission accordingly, you may configure VSFTPD to run in passive mode.
Here’s how:
Backup the Original vsftpd.conf
File
By backing up the original vsftpd.conf
file, you can always revert to the default configuration if things go wrong.
#creating a backup named vstfpd.conf.bkup
sudo cp /etc/vsftpd.conf vsftpd.conf.bkup
Specify Ports for Passive Mode
echo -e "# Passive Mode for VSFTP communication with server\npasv_min_port=4000\npasv_max_port=5000" | sudo tee -a /etc/vsftpd.conf
In our case, the minimum port would be 4000 and the maximum 5000 as we specified in the ufw
rule earlier.
Specify the local_root
If your ftp_user
is dedicated to FTP processes:
echo -e "# Location for FTP communication\nlocal_root=/home/ftp_user/" | sudo tee -a /etc/vsftpd.conf
If your ftp_user
is an existing user (not dedicated to FTP processes):
echo -e "# Location for FTP communication\nlocal_root=/home/ftp_user/ftp" | sudo tee -a /etc/vsftpd.conf
Activate chroot jail
Chroot jail basically limits the ftp_user
to its local_root
. In other words, when an FTP client gains FTP access to the ftp_user
, it only sees and gains access to the files in the local_root
.
To activate chroot jail in VSFTPD, open the vsftpd.conf file
sudo nano /etc/vsftpd.conf
Search for the line with #chroot_local_user=YES
.
Then remove #
to uncomment it.
Enable FTP Write Command
Search for the line with #write_enable=YES
.
Then remove #
to uncomment it.
Reload VSFTPD
sudo systemctl reload vsftpd.service
Test Your VSFTPD
To test your VSFTPD server, you need FTP installed. In some cases, it should already be installed. But you can confirm by running this command:
dpkg -l | grep -w ftp
If FTP is installed, you should get an output like this:
If FTP is not installed, you can install it by running:
sudo apt update
sudo apt install ftp
Login Test
After installing FTP, run the following command to login into your localhost:
ftp localhost
You should get a response like this:
Enter the username of your FTP user; in our case, the username is ftp_user
. Then when prompted, enter the password.
If your configurations and credentials are correct, you should get the following response:
Download the Test File
To download the test file, change directory to the files directory (where stored the testfile)
ftp> cd files
Then run this command to download the testfile:
ftp> get testfile
If successful, you should get a response like this:
Upload a New File
A simple way to test the FTP upload function is to ‘upload’ our testfile with another name in the files directory. To do that, run:
ftp> cd files
ftp> put testfile anothername
If this runs successfully, you should see the following when you run the ls
command:
Chroot Jail Test
To test that chroot jail works, try to cd into the /etc directory:
ftp> cd /etc
If the chroot jail configuration works, you should get this response:
Exit the FTP Shell
To exit the FTP Shell, run:
ftp> bye
#or
ftp> exit
Final Thoughts
In this article, I discussed some of the basic configurations needed to get a VSFTPD server running. In coming articles, we will talk about how to limit FTP access for users. We will also discuss how to encrypt FTP connections.