In this post, we will see how we can install an FTP server on our Ubuntu Server in order to transfer files between the server and other clients.

We will use the vsftpd service, to create the FTP server and we will access it either as a new ftpuser authenticated user or Anonymously without authentication.

If you are going to use the FTP service remotely on the public internet, it is best to not use Anonymous FTP, as anyone will be able to download from the server. Also, another and safer option is to use SFTP for remote transferring file that uses SSH, but for local network transfers a normal FTP service will be fine.

Install the FTP framework

Install the FTP framework:

sudo apt install vsftpd

Configure firewall

If we have a firewall running we must enable the FTP port in order to access the server. The default ports for FTP are port 20, port 21 and the range of passive ports can be port 49152-65535.

For a firewall like ufw, we can enable the FTP by running the following commands:

sudo ufw allow ftp
sudo ufw enable
sudo ufw status

But we can also manually enable the ports to limit the range of passive ports to port 10000-10100:

sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 990/tcp
sudo ufw allow 10000:10100/tcp
sudo ufw status

Install FileZilla (on client)

Install FileZilla on a client computer in order to test the FTP server:

sudo apt install filezilla

Authenticated FTP

Creating ftpuser user

We will create a dedicated FTP user that we will use only for FTP with minimum privileges in order to be more safe.

Firstly create the ftpuser user:

sudo adduser ftpuser

Add a password when prompted.

FTP is generally more secure when users are restricted to a specific directory. vsftpd accomplishes this with chroot jails. When chroot is enabled for local users, they are restricted to their home directory by default. However, because of the way vsftpd secures the directory, it must not be writable by the user. This is fine for a new user who should only connect via FTP, but an existing user may need to write to their home folder if they also have shell access.

Because we don’t want to disable write privileges completely from the home directory, we will create a server directory inside the ftpuser’s home directory that will be used to host all the files for the FTP service.

Create the server directory:

sudo mkdir /home/ftpuser/server

Set the ownership to the ftpuser user:

sudo chown ftpuser:ftpuser /home/ftpuser/server

Disable write access:

sudo chmod a-w /home/ftpuser/server

FTP configuration file

We are going to make some changes to the default config file of vsftpd, so it is best to take a copy of the default file if something goes wrong or you want to go back to the default settings:

sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak

Now we are going to edit the vsftpd.conf file:

sudo vim /etc/vsftpd.conf

Make sure this settings are the same:

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

Also, enable users to upload files by changing the write_enable setting:

# Uncomment this to enable any form of FTP write command.
write_enable=YES

We will also enable the chroot_local_user setting to restrict access outside the specified FTP directory:

# You may restrict local users to their home directories.  See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.
chroot_local_user=YES

We will, add a user_sub_token to insert the username in our local_root directory path so our configuration will work for the ftp user and any additional future users we would want o add:

user_sub_token=$USER
local_root=/home/$USER/server

We will limit the range of passive ports to the ones we selected to enable on the firewall:

pasv_enable=YES
pasv_min_port=10000
pasv_max_port=10100

To allow only the users we will specify we want to enable a userlist to add the users:

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

The userlist_deny=NO setting is used to permit only users in the userlist to have FTP access.

In the /etc/vsftpd.userlist we will add the users we want:

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

And we will check if the list is ok:

cat /etc/vsftpd.userlist

ftpuser

Restart the daemon to make changes take effect:

sudo systemctl restart vsftpd

Test FTP Access

Lets first try to connect anonymously to test that we will fail:

ftp -p 192.168.1.99 # Replace with your servers IP

Output:

Connected to 192.168.1.99.
220 (vsFTPd 3.0.3)
Name (192.168.1.99:default): anonymous
530 Permission denied.
ftp: Login failed.
ftp>

We see that access was denied as expected.

Close the connection:

ftp> bye

Now lets try accessing with the ftpuser user:

ftp -p 192.168.1.99 # Replace with your servers IP

Output:

Connected to 192.168.1.99.
220 (vsFTPd 3.0.3)
Name (192.168.1.99:default): ftpuser
331 Please specify the password.
Password: "ADD_YOUR_PASSWORD"
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

We now have access as expected.

Close the connection:

ftp> bye

Anonymous FTP

In this section we will see how to setup vsftpd to allow only anonymous users to access FTP, so anyone can access the server without having an account, and we will disallow user account to access the FTP server.

For anonymous FTP, the default location for the files is under /srv/ftp. If we want to change this location we will have to create the directory and specify it in the configuration file.

Create ftp directory

In order to change the default location for the files we have to create a new directory:

sudo mkdir -p /var/ftp/pub

And change the ownership to nobody:nogroup. Later we will configure to show all files as being owned by the existing ftp user and group:

sudo chown nobody:nogroup /var/ftp/pub

And create a test file to check later:

echo "Hey there" | sudo tee /var/ftp/pub/test.txt

FTP configuration file

Make sure this settings are the same:

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

Also, if you want anonymous users to upload files, you do that by changing the write_enable setting:

# Uncomment this to enable any form of FTP write command.
write_enable=YES

We will limit the range of passive ports to the ones we selected to enable on the firewall:

pasv_enable=YES
pasv_min_port=10000
pasv_max_port=10100

Some other useful settings are the following:

# Stop prompting for a password on the command line.
no_anon_password=YES
#
# Show the user and group as ftp:ftp, regardless of the owner.
hide_ids=YES

And lastly, to change the default file location, to /var/ftp we specify it with:

# Point users at a custom directory.
anon_root=/var/ftp/

Restart the daemon to make changes take effect:

sudo systemctl restart vsftpd

Test FTP Access

Lets try connecting anonymously to test the connection:

ftp -p 192.168.1.99 # Replace with your servers IP

Output:

Connected to 192.168.1.99.
220 (vsFTPd 3.0.3)
Name (192.168.1.99:default): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

We now have access as expected.

In the Name section we can either try the anonymous or the ftp user.

Close the connection:

ftp> bye

We can also access the ftp server from the browser at:

ftp://192.168.1.99 # Replace with your servers IP