1. Overview

In this tutorial, we’ll configure vsftpd to limit users from browsing parent directories when a connection is made through FTP. We’ll make this possible by creating an FTP user and modifying the default configurations in the vsftpd.conf file.

2. Setting up an FTP User

To begin, let’s create an FTP user with limited permissions:

$ sudo useradd ftpuser

Next, let’s set the user’s password:

$ sudo passwd ftpuser
New password: 
Retype new password: 
passwd: password updated successfully

Alternatively, we can use sudo useradd ftpuser -s /sbin/nologin to prevent SSH logins.

Next, let’s create a directory called ftp within the ftpuser’s home directory. We’ll use the -p flag to create the user’s default home directory:

$ sudo mkdir -p /home/ftpuser/ftp

Next, let’s set ownership and remove write permission:

$ sudo chown ftpuser:ftpuser /home/ftpuser/ftp
$ sudo chmod a-w /home/ftpuser/ftp

Removing the write permission from all users denies anyone from modifying the file contents. For example, we won’t be able to rename or remove files from this directory. However, the owner of the directory still has written permission.

Inside the ftp directory, let’s add two directories and change their ownership to ftpuser:

$ sudo mkdir /home/ftpuser/ftp/documents /home/ftpuser/ftp/Python
$ sudo chown ftpuser:ftpuser /home/ftpuser/ftp/documents /home/ftpuser/ftp/Python
$ sudo ls -l /home/ftpuser/ftp
total 8 
drwxr-xr-x 2 ftpuser ftpuser 4096 Aug  3 01:18 documents
drwxr-xr-x 2 ftpuser ftpuser 4096 Aug  3 01:39 Python

3. Configuring vsftpd

Now, we’ll edit the vsftpd configurations. We’ll make changes and add the required setting to limit our FTP user.

Firstly, let’s confirm if vsftpd is installed and is running:

$ sudo systemctl status vsftpd
● vsftpd.service - vsftpd FTP server
Loaded: loaded (/lib/systemd/system/vsftpd.service; enabled; vendor preset>
Active: active (running) since Thu 2023-08-03 01:32:16 CDT; 4h 6min ago
Process: 2896 ExecStartPre=/bin/mkdir -p /var/run/vsftpd/empty (code=exited>
Main PID: 2897 (vsftpd)
Tasks: 1 (limit: 2256)
Memory: 852.0K
CPU: 175ms
CGroup: /system.slice/vsftpd.service
└─2897 /usr/sbin/vsftpd /etc/vsftpd.conf

Otherwise, if it’s not available, we install it through:

$ sudo apt-get install vsftpd

Secondly, let’s edit the vsftpd configuration file to set up user-specific restrictions and directory access. Before making any adjustments, we must make a copy of the original file:

$ sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.copy

We create a copy of the original file to make it easier to restore in case we need the original configuration later or if our modifications are not working.

Now, let’s edit the vsftpd.conf file:

$ sudo nano /etc/vsftpd.conf

After we’ve opened the file, let’s set the following directives:

anonymous_enable=NO
local_enable=YES

These directives are important because anonymous_enable prevents anonymous logins while local_enable allows local users to log in.

Next, let’s find and uncomment the following line:

write_enable=YES

This directive allows us to add, change, or remove files and directories on the filesystem.

To prevent users from accessing files and commands outside the directory tree, let’s uncomment:

chroot_local_user=YES

Lastly, let’s add the shared directory path:

local_root=/home/ftpuser/ftp

If we manage many users, we can use the $USER variable to set the shared directories and route users to their home directories. The user_sub_token directive logs in each user to their home directory while local_root sets the path to the shared directory:

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

For these changes to take effect, we need to restart the vsftpd service:

$ sudo service vsftpd restart

Let’s test our connection and confirm if the changes have taken effect:

$ ftp 192.168.0.105     
Connected to 192.168.0.105.
220 (vsFTPd 3.0.5)
Name (192.168.0.105:gt2): ftpuser
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> pwd
Remote directory: /
ftp> ls
229 Entering Extended Passive Mode (|||24367|)
150 Here comes the directory listing.
drwxr-xr-x    2 0        0            4096 Aug 03 01:39 Python
drwxr-xr-x    2 1001     1001         4096 Aug 03 01:18 documents
226 Directory send OK.
ftp> cd documents
250 Directory successfully changed.
ftp> cd /etc
550 Failed to change directory.
ftp> cd /root
550 Failed to change directory.
ftp> cd /Python
250 Directory successfully changed.
ftp> 

The user is directed to the ftp directory (which is indicated as the remote directory or / ) upon login. The ftpuser can move to child directories but can’t move outside the ftp directory.

4. Conclusion

In this article, we’ve discussed creating an FTP user with limited capabilities and preventing the user from accessing parent directories. The FTP user we’ve created can only browse the directories within it. Further, we mentioned that we should turn off shell logins for this kind of user to prevent authorized access (especially through SSH).

Next, we must ensure that the vsftpd server is running. If it’s running and the status isn’t active, let’s reinstall it. Lastly, when modifying the vsftpd.conf file, we must ensure that the right directives are enabled to ensure that the proper permissions are given to the right users.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.