Cart

    Sorry, we could not find any results for your search querry.

    Installing an FTP server in Linux with vsftpd

    The most commonly used FTP servers on Linux are PureFTPd, ProFTPD and vsftpd. You can find an overview of the differences on this website. We advise against ProFTPD because it is maintained less actively than PureFTPd and vsftpd.

    An FTP server offers a straightforward way to upload files to your server. This is useful, for example, for a web server to deploy website updates to your VPS or instance, or for a media server to upload files.

    In this tutorial, we show how to install and configure an FTP server on a Linux distribution with vsftpd (Very Secure FTP Daemon), and how to use Let’s Encrypt to set up a secure FTPS connection.

    Prefer SFTP? See this guide.


     

    Installing and configuring the FTP server

     

    Step 1

    Connect to your server via SSH, the VPS console (VPS) or the OpenStack console (OpenStack instance).


     

    Step 2

    Install vsftpd with:

    Ubuntu/Debian:

    sudo apt -y install vsftpd

    AlmaLinux/Rocky Linux/CentOS Stream:

    sudo dnf -y install vsftpd

    vsftpd starts automatically after installation and on OS reboots.


     

    Step 3

    Before you start your FTP server, make a few adjustments to the vsftpd configuration to fine-tune access to your FTP server.

    Open the configuration file with nano or vi:

    sudo nano /etc/vsftpd.conf

     

    Step 4

    Change the following settings (add them if they do not yet exist). Read the notes first before changing these settings. Save your changes and exit with ctrl + > > enter.

    anonymous_enable=NO
    chroot_local_user=YES
    allow_writeable_chroot=YES
    userlist_enable=YES
    userlist_file=/etc/vsftpd.userlist
    userlist_deny=NO
    pasv_enable=YES
    pasv_min_port=20100
    pasv_max_port=20200
    • anonymous_enable=NO: Prevents unauthenticated users from logging in to your FTP server.
    • chroot_local_user=YES: Places FTP users in their own home directory (i.e. a chroot jail) after logging in to your FTP server. 
    • allow_writeable_chroot=YES: Allows FTP users to make changes within the chroot directory (i.e. their own home directory).
    • userlist_enable=YES: Enables the vsftpd user list, letting you explicitly allow or deny users access to your FTP server.
    • userlist_file=/etc/vsftpd.userlist: The location of the user list mentioned above.
    • userlist_deny=NO: Only the user accounts listed in the user list file may log in to your FTP server. If you set this option to ‘YES’, the user list denies access rather than allowing it.
    • pasv_enable=YES: Enables passive mode. After the control connection on port 21 is established, passive data ports are used for file transfers. If your server is behind NAT, also set pasv_address and pasv_addr_resolve appropriately.
    • pasv_min_port=20100: The lowest number in the passive port range. Any unused port above 1023 is sufficient.
    • pasv_max_port=20200: The highest number in the passive port range. A small range of up to 100 ports is usually more than adequate. 


    Step 5

    Ubuntu ships with UFW as its firewall out of the box, where all ports are closed by default. Open port 21 and your passive range with:

    Ubuntu/Debian:

    sudo ufw allow 21/tcp
    sudo ufw allow 20100:20200/tcp

    AlmaLinux/Rocky Linux/CentOS Stream:

    sudo firewall-cmd --zone=public --permanent --add-port=21/tcp
    sudo firewall-cmd --zone=public --permanent --add-port=20100-20200/tcp
    sudo firewall-cmd --reload

     

    Creating users and granting access to your FTP server

     

    In the previous steps you enabled the vsftpd user list, together with the setting that only user accounts in the user list file have access to your FTP server. In this section you will (optionally) create a new user and add the user to the list.

     

    Step 1

    You create FTP users in the same way as regular Linux users. Want to use an existing user account? Then continue with step 3.

    sudo useradd -m -c "ftp demo" username
    sudo passwd username

    Code explanation

    • -m: creates a home directory for the user. This is optional and only needed if you want the user to have a home directory on your VPS at /home/username. If in the 'Adjusting users’ home directories' section you set a home directory outside /home, you can omit -m.
    • -c: also optional; adds a comment to the user (handy to note what an account is for).
    • username: the actual username
    • passwd username: sets the user’s password

    Optional:

    Optionally you can also give FTP users a specific home directory and make them a member of a group by creating an FTP group, for example:

    sudo groupadd ftp
    sudo useradd -g ftp -d /ftp -c "ftp demo" username
    sudo passwd username

     

    Step 2

    Open the user list file:

    sudo nano /etc/vsftpd.userlist

     

    Step 3

    Add the username to the file, save your changes and exit nano with ctrl + x > y > enter. Add each username on a new line, for example:

    transip
    admin
    username

    Tip: as an alternative you can append the username with a single command:

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

     

    Adjusting users’ home directories

     

    Thanks to the earlier configuration, FTP users are placed in their home directory by default. In this section we show how to set optional specific directories. This is useful, for example, if you want to direct users to a specific directory containing their website (on web servers), or a specific folder (e.g. Block Storage) on a media server.

     

    Step 1

    Want to use an existing directory? Then continue with step 3. If the directory does not yet exist, create it first and remove all write permissions for all users (replace ‘username’ with the user’s name).

    sudo mkdir /home/username/ftp
    sudo chown nobody:nogroup /home/username/ftp
    sudo chmod a-w /home/username/ftp

    Note: on RHEL-like distributions, the group is commonly nobody:nobody.


     

    Step 2

    Create the directory where the user is allowed to place files and give only that user full permissions on it. Replace ‘username’ with the user’s name:

    sudo mkdir /home/username/ftp/files
    sudo chown username:username /home/username/ftp/files
    sudo chmod 0700 /home/username/ftp/files

     

    Step 3

    Now set the user’s home directory. Reopen the vsftpd configuration file:

    sudo nano /etc/vsftpd.conf

     

    Step 4

    Add the following two lines at the bottom of the file:

    user_sub_token=$USER
    local_root=/home/$USER/ftp/
    • user_sub_token=$USER: the name of the user connecting to your FTP server is used for the $USER variable.
    • local_root: the directory your FTP users end up in. In this example, it is the ftp folder in the user’s home directory. Unless you add more subfolders under ftp, you could also set /home/$USER/ftp/files directly.
      • If, for example, you have Block Storage attached to your VPS and want to use it (e.g. for a media server), then set local_root=/mnt/bigstorage/ (replace with the actual mount point).
      • If you host websites (in /var/www/html/) and used your domain as the username in the previous section, you could set local_root=/var/www/html/$USER here.

    Save your changes and exit with ctrl + > > enter.


     

    Step 5

    Finally, restart vsftpd to apply the new configuration. It can sometimes take a few minutes before a change like this is reflected when connecting via your FTP client.

    sudo systemctl restart vsftpd

     

    Securing your FTP server

     

    The FTP protocol does not encrypt data and is therefore insecure. In practice, SFTP or FTPS is almost always used instead (see this article for an explanation of the differences). In this part of the guide you’ll secure your FTP server with FTPS. 

    For these steps you’ll need a (sub)domain whose A record points to your FTP server, at a minimum.

     

     

    Step 1

    We’ll use a Let’s Encrypt certificate as the SSL(TLS) certificate. For installing Let’s Encrypt, the Let’s Encrypt project recommends using Snap. 

    1. First install Snap.
    2. Optionally remove any existing Certbot installations (the tool used to obtain Let’s Encrypt certificates). 
    3. Then install Certbot with Snap.
    4. Finally, create a symbolic link so you can run certbot commands directly. 

    Ubuntu/Debian:

    sudo apt -y install snapd
    sudo apt -y remove certbot
    sudo snap install --classic certbot
    sudo ln -s /snap/bin/certbot /usr/bin/certbot

    AlmaLinux/Rocky Linux/CentOS Stream:

    sudo dnf -y install snapd
    sudo dnf -y remove certbot
    sudo snap install --classic certbot
    sudo ln -s /snap/bin/certbot /usr/bin/certbot

     

    Step 2

    For validation, it’s important that ports 80 and 443 are open in your firewall. If they aren’t open yet, use:

    Ubuntu/Debian:

    sudo ufw allow 80,443/tcp

    AlmaLinux/Rocky Linux/CentOS Stream:

    sudo firewall-cmd --zone=public --permanent --add-port=80/tcp
    sudo firewall-cmd --zone=public --permanent --add-port=443/tcp
    sudo firewall-cmd --reload

     

    Step 3

    It’s important that ports 80 and 443 are not currently in use. Check this by installing net-tools and using netstat:

    Ubuntu/Debian:

    sudo apt -y install net-tools
    sudo netstat -tulpn | less

    AlmaLinux/Rocky Linux/CentOS Stream:

    sudo dnf -y install net-tools
    sudo netstat -tulpn

    You’ll see an overview similar to:

    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
    tcp        0      0 127.0.0.54:53           0.0.0.0:*               LISTEN      628/systemd-resolve
    tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      1184/exim4
    tcp        0      0 0.0.0.0:45123           0.0.0.0:*               LISTEN      1/init
    tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      628/systemd-resolve
    tcp6       0      0 :::80                   :::*                    LISTEN      801/apache2
    tcp6       0      0 :::21                   :::*                    LISTEN      15788/vsftpd
    tcp6       0      0 :::25                   :::*                    LISTEN      1184/exim4
    tcp6       0      0 :::45123                :::*                    LISTEN      1/init
    tcp6       0      0 :::443                  :::*                    LISTEN      801/apache2
    udp        0      0 127.0.0.54:53           0.0.0.0:*                           628/systemd-resolve
    udp        0      0 127.0.0.53:53           0.0.0.0:*                           628/systemd-resolve
    udp        0      0 12.123.123.2:68         0.0.0.0:*                           672/systemd-network

    As you can see, both ports are in use by apache2. Temporarily stop the relevant service, in this case with:

    sudo systemctl stop apache2

     

    Step 4

    Next, generate a certificate with the command below. Replace ftp.voorbeeld.nl with your hostname (check with the hostnamectl command) and admin@voorbeeld.nl with the email address you want to manage the certificates with. 

    sudo certbot certonly --standalone -d ftp.voorbeeld.nl -m admin@voorbeeld.nl --agree-tos --non-interactive

    Then start any services you stopped, for example:

    sudo systemctl start apache2

     

    Step 5

    Your Let’s Encrypt certificate and key file are stored in /etc/letsencrypt/live/<hostname>/ (the exact path is shown in the output from step 4).

    Next, adjust the vsftpd configuration to use the Let’s Encrypt certificates and to refuse insecure connections. Reopen /etc/vsftpd.conf:

    nano /etc/vsftpd.conf

     

    Step 6

    Add the following configuration at the bottom of the file, replacing server.voorbeeld.nl with your hostname.

    ssl_enable=YES
    allow_anon_ssl=NO
    require_ssl_reuse=NO
    force_local_data_ssl=YES
    force_local_logins_ssl=YES
    ssl_tlsv1_1=YES
    ssl_tlsv1_2=YES
    # ssl_tlsv1_3=YES  # uncomment if your vsftpd build supports TLS 1.3
    
    # disable insecure protocols
    ssl_tlsv1=NO
    ssl_sslv2=NO
    ssl_sslv3=NO
    
    # certificate file locations
    rsa_cert_file=/etc/letsencrypt/live/server.voorbeeld.nl/fullchain.pem
    rsa_private_key_file=/etc/letsencrypt/live/server.voorbeeld.nl/privkey.pem

    Not all FTP clients work with the same settings. These steps were tested with FileZilla. Older FTP clients may require ssl_tlsv1=YES. Note, however, that it’s safer to use a newer FTP client.


     

    Step 7

    You’re almost done: just restart vsftpd with the command below.

    sudo systemctl restart vsftpd

    Finally, the fun bit: you can now test your connection!


     

    Connect to your vsftpd server

     

    To connect to your FTP server, use the settings below. The screenshot underneath shows an example in FileZilla.

    • Protocol: FTP – File Transfer Protocol (or FTPS if your FTP application names it explicitly)
    • Host: The IP address of your FTP server or a (sub)domain that points to it. The (sub)domain is the same as the one for which you optionally generated an SSL certificate.
    • Port: 21 
    • Encryption: If you use an SSL certificate we recommend ‘Require explicit FTP over TLS’. If not (insecure), ‘Use explicit FTP over TLS if available’ will suffice.
    • Logon Type: Normal (never anonymous). 
    • User: A previously created FTP user account.
    • Password: The password for the user mentioned above.

    Need help?

    Receive personal support from our supporters

    Contact us