Installing an FTP server (vsftpd) on Ubuntu 18.04

Installing an FTP server (vsftpd) on Ubuntu 18.04

Last updated on

vsftpd (Very Secure File Transfer Protocol Daemon) is a popular FTP server for Ubuntu. In this guide we will install and configure vsftpd on Ubuntu 18.04 LTS (Bionic Beaver). We will also set up an FTP user and optionally configure SFTP for secure file transfers.

Before you begin…

It’s surprising how many web developers are still unaware of SFTP and the advantages over FTP/FTPS. I admit myself that until recently I would religiously set up a vsftpd server with every new Linux install, but it’s really not necessary. If your FTP client supports SFTP, you should use it!

1. Install vsftpd

Let’s begin by updating the package lists and installing vsftpd on Ubuntu 18.04.

Below we have two commands separated by &&. The first command will update the package lists to ensure you get the latest version and dependencies for vsftpd. The second command will then download and install vsftpd. Press y and ENTER when asked to continue.

sudo apt update && sudo apt install vsftpd

Once installed, check the status of vsftpd

sudo service vsftpd status
 vsftpd.service - vsftpd FTP server
   Loaded: loaded (/lib/systemd/system/vsftpd.service; enabled; vendor preset: enabled
   Active: active (running) since Tue 2018-04-17 15:23:22 UTC; 10s ago
 Main PID: 31602 (vsftpd)
   CGroup: /system.slice/vsftpd.service
           └─31602 /usr/sbin/vsftpd /etc/vsftpd.conf

Apr 17 15:23:22 myserver systemd[1]: Starting vsftpd FTP server...
Apr 17 15:23:22 myserver systemd[1]: Started vsftpd FTP server.

Above we can see our FTP server is now up and running.

2. Configure Firewall

If you haven’t already done so, it is recommended that you enable the ufw firewall for Ubuntu 18.04. Before enabling ufw firewall, make sure you add a rule for SSH, otherwise you may get locked out of your server if you’re connected remotely. If you don’t want to set up a firewall, skip to Step 3.

sudo ufw allow OpenSSH

Let’s open ports 20 and 21 for FTP, and ports 40000-50000 for passive FTP. We’ll also open port 990 for TLS, which we will set up later.

sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 40000:50000/tcp
sudo ufw allow 990/tcp

Now, enable the firewall if it isn’t already. Press y and ENTER if warned about disrupting the SSH connection.

sudo ufw enable

To check the status of the firewall, run:

sudo ufw status

If the firewall is running, you should see Status: active and the firewall rules we just added.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Apache Full                ALLOW       Anywhere
3306                       ALLOW       Anywhere
20/tcp                     ALLOW       Anywhere
21/tcp                     ALLOW       Anywhere
40000:50000/tcp            ALLOW       Anywhere
990/tcp                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Apache Full (v6)           ALLOW       Anywhere (v6)
3306 (v6)                  ALLOW       Anywhere (v6)
20/tcp (v6)                ALLOW       Anywhere (v6)
21/tcp (v6)                ALLOW       Anywhere (v6)
40000:50000/tcp (v6)       ALLOW       Anywhere (v6)
990/tcp (v6)               ALLOW       Anywhere (v6)

3. Create FTP User

We will now create a new user that we will use to log into FTP. In this example, we will create a new user called ftpuser.

sudo adduser ftpuser

Generate a strong password and keep it safe.

You may also be asked to enter some contact information. You can just press ENTER to each of these.

If you only want ftpuser to log in via FTP, you should disable their SSH access by blacklisting their username in the SSH config file. Otherwise, skip to Step 4.

Open the SSH config in nano.

sudo nano /etc/ssh/sshd_config

Add the following to the bottom of the file replacing ftpuser with the user you want to deny SSH and SFTP access. You can add multiple users here separated by a single space. (To paste in nano, press the right mouse button).

DenyUsers ftpuser

To save file and exit, press CTRL + X, press Y and then press ENTER.

Restart the SSH service.

sudo service sshd restart

4. Directory Permissions

You now need to decide where this new FTP user is allowed to view and upload files.

vsftpd uses chroot jails to restrict users to their home directories and requires that the home directory is not writable. For that reason, we have to set up some directories and permissions.

If you plan on using this FTP user account to upload files to a web server, continue to Step 4.1. If you just want to upload to a home folder, skip to Step 4.2.

4.1. Upload to a Web Server

In many cases, you want to be able to upload files to the document root on the web server.

If you followed a previous guide here for setting up multiple domains, your document root may be located in somewhere like /var/www/ – in that case, you would need to set the home folder for ftpuser to the folder above the document root: /var/www/ (substituting for your own domain).

If you are not using multiple domains, we will assume you are using the default document root /var/www/html for both Apache and Nginx in Ubuntu 18.04. In this scenario, we have to make /var/www/ the home directory for our user ftpuser.

Let’s set the folder above the document root as the home directory for ftpuser.

sudo usermod -d /var/www ftpuser

Now set ownership of the document root directory to ftpuser. (The default is /var/www/html, though it may be /var/www/ on your server.)

This will allow our FTP user to write and alter files in the document root directory.

sudo chown ftpuser:ftpuser /var/www/html

Now skip to Step 5 to configure vsftpd.

4.2 Upload to a Home Folder

If instead you want this user to upload files to the home directory, create a new directory called ftp in the user’s home directory and another within it called files. In this example below our user is called ftpuser.

sudo mkdir /home/ftpuser/ftp

Set the ownership of the ftp directory to no nobody:nogroup.

sudo chown nobody:nogroup /home/ftpuser/ftp

Set permissions for the ftp directory using chmod so that it is not writable by anyone, otherwise vsftpd will not allow you to log in.  a-w means  a = all/everyone  - = remove  w = write permission, so, remove write permissions for everyone.

sudo chmod a-w /home/ftpuser/ftp

Next we will create a new directory within /ftp where the user can view and upload files.

sudo mkdir /home/ftpuser/ftp/files

Assign ownership of this directory to our new FTP user otherwise they will not be able to write to it.

sudo chown ftpuser:ftpuser /home/ftpuser/ftp/files

5. Configure vsftpd

There are a few changes we have to make to the vsftpd configuration file before you can start using FTP on Ubuntu 18.04.

Before editing the config file, create a backup.

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

Now, open the config file in nano editor.

sudo nano /etc/vsftpd.conf

This is quite a large file but it’s mostly filled with comments to help you along.

You need to go down the file and make sure that the settings match those below. Note: you can search in nano using CTRL + W

Look for #write_enable=YES and uncomment it by removing the # sign. This will allow FTP users to write files to the server.


Look for #chroot_local_user=YES and uncomment it by removing the # sign. This will prevent FTP users from browsing outside their own directory.


Look for #local_umask=022 and uncomment it by removing the # sign. This will give uploaded files and folders the correct permissions.


We now need to add some directives that don’t exist in the file.

Since Linux doesn’t show files beginning with a dot, files like .htaccess will not be visible in FTP. This may be a problem if you intend to use Apache and want to work with .htaccess.

To force vsftpd to show file names that begin with a dot, paste the following to the bottom of the file. (To paste in nano, press the right mouse button)


Lastly, let’s add some port ranges for passive FTP to make sure enough connections are available. Paste the following to the bottom of the file. (To paste in nano, press the right mouse button)


If you followed Step 4.2 previously and only want this user to upload files to the home folder, we must tell vsftpd that the local_root is the /ftp folder we created earlier.

Don’t add these two lines if you want the user to upload to the web document root!


We are done with vsftpd.conf for the moment but will return in later steps to set up security and SSL.

To save file and exit, press CTRL + X, press Y and then press ENTER.

Restart vsftpd.

sudo systemctl restart vsftpd

6. Test FTP

We can now test vsftpd to see if we can log in as the user we created earlier. We recommend FileZilla, which works on Windows, Mac and Linux.

Enter your server’s IP, your FTP username and password you created earlier, and click Quickconnect.

Above we can see we have connected successfully and the web root directory html is displayed, though this may be different on your server.

Try uploading, creating and editing folders and files within the web root directory to ensure permissions are working correctly.

You will notice we have a warning in FileZilla “Status: Insecure server, it does not support FTP over TLS.” It is highly recommended that you now configure TLS so that login credentials and traffic are encrypted over the FTP connection.

If you are having problems logging in to the FTP server, try checking the vsftpd log. To view the last 200 entries using tail:

sudo tail /var/log/vsftpd.log -n 200

7. Secure FTP with TLS (optional)

It’s important to keep a few things in mind when using FTP – it is not encrypted by default meaning your credentials and files that you send are vulnerable to interception. To address this you should connect to vsftpd using FTPS (FTP over SSL/TLS).

Let’s begin by creating a new certificate with the openssl tool.

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

You will be asked to enter some details like country, etc. You don’t have to fill these in. You can just press ENTER for defaults.

Now that your private key has been created, there are a few changes we have to make to the vsftpd configuration file.

Open the config file in nano editor.

sudo nano /etc/vsftpd.conf

Find the following line: (Note: you can search in nano using CTRL + W)


Change it to:


Paste in the following beneath it.


Save file and exit (press CTRL + X, press Y and then press ENTER).

Restart vsftpd.

sudo systemctl restart vsftpd

8. Testing TLS with FileZilla

We can now test TLS. We recommend FileZilla, which works on Windows, Mac and Linux.

Enter your server’s IP, your FTP username and password you created earlier, and click Quickconnect.

You may be presented with an Unknown Certificate warning. Click Always trust this certificate in future sessions and click OK.

If you are connected over TLS, it will tell you in the connection log. You will also see a padlock in the bottom right corner.

You’re all done!

Let me know in the comments if this helped. Follow me on Twitter, Facebook and YouTube.

p.s. I increased my AdSense revenue by 68% using AI 🤖. Read my Ezoic review to find out how.

1 Star2 Stars3 Stars4 Stars5 Stars 4.67 (24 votes)

Leave a Reply

Your email address will not be published. Required fields are marked *

We use Markdown to style comments, like on Github and Reddit.
To do a line break, type two spaces after the sentence.
You can add inline code by wrapping it in backticks: `code here`

    To do an entire block of code  
    type four spaces before the line
    and it will appear in a block like this.
    <-- four empty spaces

20 replies

I followed this excellent guide step by step and managed to test the ftp server perfectly, both locally and remotely. Everything worked without problems; but only the first time.
In all subsequent attempts I found this error:

“Status: Connection established, waiting for welcome message…
Status: Initializing TLS…
Status: Verifying certificate…
Status: TLS connection established.
Status: Server does not support non-ASCII characters.
Status: Logged in
Status: Retrieving directory listing of “/”…
Status: Server sent passive reply with unroutable address. Using server address instead.
Command: LIST
Error: The data connection could not be established: ECONNREFUSED – Connection refused by server
Error: Connection timed out after 20 seconds of inactivity
Error: Failed to retrieve directory listing”

Vielen Dank für die tollen Infos. So deutlich, klar und verständlich erklärt, das auch ich als lernender Anfänger verstehe worum es geht. Es ist kaum zu glauben, aber nachdem ich diese Webside zufällig fand und den Anweisungen folgte, funktionierte alles einwandfrei.
Herzlichen Dank dafür!

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

Shouldn’t it keyout to a key file instead of a pem one? or it doesn’t matter?

Thank you very much. I have had gave up already to install sftp access to /www/var and the web is full of trouble about that. Your receipe worked though I stored the rsa cert in the /etc/ssl/certs directory (typo?)

I can`t understand why do I remove the permissions to myself (as ftpuser) by using this command:

chown nobody:nogroup /home/ftpuser/ftp

Why this is needed?

Because the folder above the folder you want to upload to should not be writable.

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. Rather than removing write privileges from the home directory, we create an ftp directory (/home/ftpuser/ftp) to serve as the chroot and a writable files directory (/home/ftpuser/ftp/files) to hold the actual files.

I got mine running but I get an error 550. It says “an error occurred opening the folder on the ftp server. Make sure you have permission to access the folder” but I should have access right?

Let me correct what happened. when copying files to the server it said “make sure have permission to put files on the server.”
—200swithing to binary mode—
—227entering passive mode—
—550premission denied—

Did you add local_root=/home/$USER/ftp to etc/vsftpd.conf?

You can also configure a default remote directory in your FTP client.

Your blog has got me up and running. i can ftp with local ip address but not externally. Is there a setting for this? My main problem is a blank landing page (script im using) but admin works.

Hi thank this will help, but then I got an error. When I tried to login using filezilla ..
Response: 234 Proceed with negotiation.
Status: Initializing TLS…
Status: Verifying certificate…
Status: TLS connection established.
Command: USER ftpuser1
Response: 331 Please specify the password.
Command: PASS ********
Error: GnuTLS error -15: An unexpected TLS packet was received.
Error: Could not connect to server

If you’re certain the password is correct, this can happen if the user’s root directory is writable, which isn’t allowed when using chroot restrictions. To test, add allow_writeable_chroot=YES to /etc/vsftpd.conf and restart vsftpd sudo systemctl restart vsftpd

If it works, then you know it’s a folder permission problem.