- How to setup and configure an FTP server in Linux?
- How does the FTP server work?
- Stepwise Implementation
- Step 1: Install FTP server
- Step 2: Configure Firewall
- Step 3: Configure Users
- Step 4: Create the FTP folder and set permissions
- Step 5: Configure and secure vsftpd
- Locking user into the home directory
- Setting file permission
- Step 6: Securing vsftpd with SSL/TLS
- Step 7: Connecting to our FTP server
- FTP server commands
- How to enable FTP passive mode on Ubuntu vsftpd server
How to setup and configure an FTP server in Linux?
FTP (file transfer protocol) is an internet protocol that is used for transferring files between client and server over the internet or a computer network. It is similar to other internet protocols like SMTP which is used for emails and HTTP which is used for websites. FTP server enables the functionality of transferring files between server and client. A client connects to the server with credentials and depending upon the permissions it has, it can either read files or upload files to the server as well. In this article, we will see how to set up an FTP server, configure user permissions, configure firewall and finally encrypt our FTP traffic with SSL.
How does the FTP server work?
FTP server facilitates the transfer of files between client and server. You can either upload a file to a server or download a file from the server. A client makes two types of connection with the server, one for giving commands and one for transferring data. The client issues the command to the FTP server on port 21, which is the command port for FTP. For transferring data, a data port is used. There are two types of connection modes for transferring data:
- Active mode: In Active mode, the client opens a port and waits for the server to connect to it to transfer data. The server uses its port 20 to connect to the client for data transfer. Active mode is not set by default in most of the FTP clients because most firewalls block the connections which are initiated from outside, in this case, the connection initiated by our FTP server. To use this, you have to configure your firewall.
- Passive mode: In this, when a client requests a file from the server, the server opens a random port and tells the client to connect to that port. In this case, the connections are initiated by the client and this also solves the firewall issues. Most of the FTP clients use passive mode by default.
Stepwise Implementation
At first SSH into your Linux virtual machine with a user who has sudo permissions and follows the following steps:
Step 1: Install FTP server
There are many FTP servers to choose from like ProFTPD, vsftpd, etc. We will be using vsftpd.
Features of vsftpd FTP server
vsftpd has a lot of features which make it a great option as an FTP server. It
- Supports SSL/TLS integration
- Can jail users into its home directory with a feature called chroot. We will set this up later in this article.
- Can limit bandwidth.
- Supports virtual users
- Supports virtual IP configuration
- Supports IPv6
Type in the following command to install vsftpd
Now we will check if the vsftpd service is active or not. Type in
sudo systemctl status vsftpd
You can see under the Active heading that it’s active and running. systemctl command is used to manage and check services on Linux. We can also use this command to enable and disable services on Linux. If your vsftpd is not active, then type in
sudo systemctl enable --now vsftpd
The –now flag ensures that enable command affects our service immediately and not after a reboot.
Step 2: Configure Firewall
FTP uses port 20 for active mode, port 21 for commands, and a range of ports for passive mode. We need to open these ports from our firewall. If you do not use any firewall, you can skip this step. Most of the Linux systems use ufw to manage firewalls, however, some cloud service providers like Microsoft Azure have firewalls outside of the Virtual machine and you have to configure that from their portal. Whatever the case, just open ports 20 and 21 for TCP connections and open a range of ports for passive FTP connections. The range for passive ports depends upon how many concurrent user clients you expect to have. Also, a single client can use multiple ports to transfer multiple files or a large file. We also need to specify our FTP server to use those ports and we will see how to do it later in this tutorial The ports till 1024 are reserved and our passive FTP port range should be higher than that. I’ll open ports from 5000-10000. We will also open port 990 for TCP which we will configure later. Let’s do it for ufw. Type in
sudo ufw allow 20/tcp sudo ufw allow 21/tcp sudo ufw allow 990/tcp sudo ufw allow 5000:10000/tcp
Step 3: Configure Users
The two most common use cases of FTP servers are:
- You want to host a public FTP server and a lot of public users are going to connect to your FTP server to download files.
- You want to upload your files to your Linux server for personal use and you would not have public users.
In the first case, you would need to create an additional user and share its username and password with your clients to access the files. Everything else is the same for the second case.
The basic idea is that the admin user should be able to upload files to any folder of the machine, and the public user should be able to view and download files from a specific directory only. To make this happen, you should have a basic idea of user permissions. The root user has the permission to write files into any folder of the server, and any other user has access to every folder inside their home directory which is /home/username and most of the other directories are not writable by other users. So if you want to upload files to other directories outside of your admin user’s home directory, let’s say /var/www, then you would need to change the owner of this directory to your admin user with chown command, or change directory modification permissions with chmod command.
Let’s start by creating our public user account. Type in
Enter your password, leave other values empty, and at last, enter Y to save changes.
Now, for security purposes, we will disable ssh permission for this user. Type in
sudo nano /etc/ssh/sshd_config
Add the following line in this file
Press Ctrl + x then y then enter. Now, restart the SSH service so that these new settings take effect.
sudo systemctl restart sshd
Step 4: Create the FTP folder and set permissions
We will create our FTP folder. Type in
Now, we will change this directory’s owner to our admin user. Type in
If you want to upload files to any folder that is not owned by your admin user, you will have to change that folder’s owner using the above-mentioned command.
Step 5: Configure and secure vsftpd
Open the vsftpd configuration file. Type in
Make sure the following lines are uncommented
. anonymous_enable=NO local_enable=YES write_enable=YES .
Also, we opened ports 5000 to 10000 in step 2 for passive mode, so now we will let vsftpd know which ports to use for passive FTP connection. Add the following lines in vsftpd.conf file
pasv_min_port=5000 pasv_max_port=10000
Now, we will specify the default directory for FTP connections which will open when someone connects to our FTP server. Add the following line
Remember, do not put any space before and after = in this configuration file.
Locking user into the home directory
Now, for security reasons, we will lock the ftpuser to the default directory, as by default, a user can browse the whole Linux server. To do this, vsftpd uses chroot. To do this, un-comment the following lines
. chroot_local_user=YES chroot_list_enable=YES chroot_list_file=/etc/vsftpd.chroot_list .
Also, add the following line as it is not in the configuration file by default
allow_writeable_chroot=YES
The first line enables chroot feature for local users which includes our admin user and our ftpuser. The second and third lines let us choose which users to apply chroot to.
Setting file permission
This line will set the modification permission of every new file created to 664(-rw-rw-r-) and of every new folder to 775(rwxrwxr-x). With this, the ftpuser can only read and download files from every sub-directory of our FTP directory, but it does not have permission to upload anything to our FTP directory since it is not the owner.
Press Ctrl + x then y then enter. Now, we need to create that list file. Type in
sudo touch /etc/vsftpd.chroot_list sudo nano /etc/vsftpd.chroot_list
Whatever users you specify in this file, will not be chroot-ed. So add your admin username in this file because we do not want to lock it. Press Ctrl + x then y then enter. Now we need to restart our vsftpd server so that all these settings get applied immediately. Type in
sudo systemctl restart --now vsftpd
Step 6: Securing vsftpd with SSL/TLS
It is recommended to encrypt FTP traffic if you want to use it over the internet. We will encrypt our traffic with FTPS (file transfer protocol over SSL). Let’s start by generating a self-signed certificate. Type in
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
Enter all the required information and your certificate will be generated. You can also Hit Enter if you want the default values to be set. Now, open the vsftpd configuration file. Type
Go to the end of the file and remove the following lines
And, paste the following lines
rsa_cert_file=/etc/ssl/private/vsftpd.pem rsa_private_key_file=/etc/ssl/private/vsftpd.pem ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO require_ssl_reuse=NO ssl_ciphers=HIGH
Save the changes and finally, restart the vsftpd service by typing in
sudo systemctl restart --now vsftpd
Step 7: Connecting to our FTP server
To do this, you will need an FTP client. Again, there are a bunch of them to choose from. I’d suggest you go with Filezilla. Download and install it and then open it. Enter your server’s IP address in the Host field, your username, and password, and click connect and you are good to go.
On the left side, you would see your PC’s directories, and on the right, you would see the directories of your FTP server. You can drag and drop files to upload and download files between the FTP server and your device(client).
FTP server commands
You can also connect to your FTP server on the terminal and operate it with FTP commands. A list of a few of them is given below.
Command | Function |
---|---|
pwd | print the current working directory |
cwd | change working directory |
dele | delete the specified file |
cdup | change to the parent directory |
help | displays help information |
cd | change the working directory |
get filename | download the specified file |
put filename | uploads the specified file |
bye | end FTP session |
How to enable FTP passive mode on Ubuntu vsftpd server
By default, FTP Connections are in Active mode. However, there is another mode called Passive FTP.
From the server, we need to enable passive FTP If the FTP client uses the passive mode to initiate the FTP connection. In order to configure vsftpd passive mode in Ubuntu 18.04, we must add the following parameters to the /etc/vsftpd.conf file.
pasv_enable=Yes pasv_min_port=10100 pasv_max_port=10110
Then restart the vsftpd service:
sudo systemctl restart vsftpd
The pasv_enable=Yes directive enables the passive mode for Ubuntu vsftpd server, then we defined a range of ports that will be used for the data connection (you can use any custom port range).
If the Ubuntu server is behind a firewall, you need to open passive port range. Following example shows how to open passive port range from the UFW Ubuntu firewall.
sudo ufw allow from any to any proto tcp port 10100:10110
In an active mode, the FTP client uses a random port to initiate the connection. With passive mode, the client requests the passive connection and requests a random port from the FTP server. Normally The FTP client uses the Passive mode when the client is behind a firewall.
By enabling passive FTP you will also solve the following Filezilla error: Connection timed out after 20 seconds of inactivity, Failed to retrieve directory listing.