How to Set Up a Secure FTP Server with Pure-FTPd on Ubuntu

Pure-FTPd is a free open-source FTP server designed with security in mind. In this tutorial, we are going to take a look at how to set up a secure FTP server on Ubuntu server with Pure-FTPd and how to enforce TLS encryption.

Note: This tutorial works on all current Ubuntu releases, including Ubuntu 22.04, 20.04, and 18.04.

Pure-FTPd Features:

  • It supports SSL/TLS encryption and thus passwords and commands can be protected.
  • It can run on most Unix-like systems: Linux, BSDs, Solaris, Darwin, HPUX, AIX, and even iPhone.
  • Available in 21 languages.
  • Allows you to monitor active sessions.
  • Supports a virtual quota system.
  • And much more

For a complete list of features, please go to Pure-FTPd official website.

Step 1: Install Pure-FTPd on Ubuntu Server

It’s in the software repository, so issue the following command to install the FTP server.

sudo apt install pure-ftpd

Once installed, Pure-FTPd will be automatically started, as can be seen with this command:

systemctl status pure-ftpd

Output:

 pure-ftpd.service
   Loaded: loaded (/etc/init.d/pure-ftpd; bad; vendor preset: enabled)
   Active: active (running) since Mon 2016-12-12 21:51:46 EST; 23s ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/pure-ftpd.service
           └─3435 pure-ftpd (SERVER)

preset: enabled indicates it will auto-start at system boot time. If it’s not running, star it with:

sudo systemctl start pure-ftpd

And it’s listening on TCP port 21, which is the control port, as can be seen with

sudo ss -lnpt | grep pure-ftpd

ubuntu ftp server

Anonymous access is disabled by default. From now on you can use your system account to login, but plain text FTP is insecure and strongly discouraged. To have a secure FTP server, we need to encrypt communication with TLS.

Step 2: Enforce TLS Encryption

To enable both plain-text and TLS encryption, run the following command, which create the /etc/pure-ftpd/conf/TLS file and put number 1 into the file.

echo 1 | sudo tee /etc/pure-ftpd/conf/TLS

But it’s recommended to disable plain-text and use TLS encryption only, so put the number 2 to the file instead.

echo 2 | sudo tee /etc/pure-ftpd/conf/TLS

Now we enforced TLS, we need to obtain a valid TLS certificate. A self-signed certificate is not recommended because users will see warning like the screenshot below.

nautilus ftps

Step 3: Obtain a Trusted TLS Certificate from Let’s Encrypt

Run the following command to install Let’s Encrypt client (certbot) from the default Ubuntu repository.

sudo apt install certbot

I recommend using the standalone or webroot plugin to obtain TLS certificate for Pure-FTPd.

Standalone Plugin

If there’s no web server running on your Ubuntu server, you can use the standalone plugin. Run the following command. Don’t forget to set DNS A record for your sub-domain.

sudo certbot certonly --standalone --preferred-challenges http --agree-tos --email [email protected] -d ftp.example.com

Where:

  • certonly: Obtain a certificate but don’t install it.
  • --standalone: Use the standalone plugin to obtain a certificate
  • --preferred-challenges http: Perform http-01 challenge to validate our domain, which will use port 80.
  • --agree-tos: Agree to Let’s Encrypt terms of service.
  • --email: Email address is used for account registration and recovery.
  • -d: Specify your domain name.

As you can see from the following screenshot, I successfully obtained the certificate.

pure-ftpd ubuntu server enforce TLS encryption

Using webroot Plugin

If your Ubuntu server has a web server, then it’s a good idea to use the webroot plugin to obtain a certificate because the webroot plugin works with pretty much every web server and we don’t need to install the certificate in the web server.

First, you need to create a virtual host for ftp.example.com.

Apache

If you are using Apache, then

sudo nano /etc/apache2/sites-available/ftp.example.com.conf

And paste the following lines into the file.

<VirtualHost *:80>        
        ServerName ftp.example.com

        DocumentRoot /var/www/Pure-FTPd
</VirtualHost>

Save and close the file. Then create the web root directory.

sudo mkdir /var/www/Pure-FTPd

Set www-data (Apache user) as the owner of the web root.

sudo chown www-data:www-data /var/www/Pure-FTPd -R

Enable this virtual host.

sudo a2ensite ftp.example.com

Reload Apache for the changes to take effect.

sudo systemctl reload apache2

Once virtual host is created and enabled, run the following command to obtain Let’s Encrypt certificate using webroot plugin.

sudo certbot certonly --webroot --agree-tos --email [email protected] -d ftp.example.com -w /var/www/Pure-FTPd

Nginx

If you are using Nginx, then

sudo nano /etc/nginx/conf.d/ftp.example.com.conf

Paste the following lines into the file.

server {
      listen 80;
      listen [::]:80;
      server_name ftp.example.com;

      root /var/www/Pure-FTPd/;

      location ~ /.well-known/acme-challenge {
         allow all;
      }
}

Save and close the file. Then create the web root directory.

sudo mkdir -p /var/www/Pure-FTPd

Set www-data (Nginx user) as the owner of the web root.

sudo chown www-data:www-data /var/www/Pure-FTPd -R

Reload Nginx for the changes to take effect.

sudo systemctl reload nginx

Once virtual host is created and enabled, run the following command to obtain Let’s Encrypt certificate using webroot plugin.

sudo certbot certonly --webroot --agree-tos --email [email protected] -d ftp.example.com -w /var/www/Pure-FTPd

Step 4: Install the Certificate

Pure-FTPd requires that the certificate and private key are combined into one file named pure-ftpd.pem and stored under /etc/ssl/private/ directory.

Change to the /etc/letsencrypt/live/ftp.example.com/ directory.

cd /etc/letsencrypt/live/ftp.example.com/

You can use cat command to combine two files into one like below.

sudo cat fullchain.pem privkey.pem | sudo tee /etc/ssl/private/pure-ftpd.pem

Make sure only the root user can read the file.

sudo chmod 600 /etc/ssl/private/pure-ftpd.pem

we need to generate the Diffie-Hellman parameter with:

sudo openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 4096

If your server has a single CPU core, then this is going to take a long time (about 10 minutes).

Once that’s done, restart Pure-FTPd.

sudo systemctl restart pure-ftpd

Check the status to see if it’s running.

systemctl status pure-ftpd

Now you can connect to your FTP server over TLS.

Step 5: Using FTP Client

Nautilus File Manager on Ubuntu Desktop

If you use the Nautilus file manager to connect to FTP server via plain text ftp:// protocol

nautilus connect to ftp server

The connection will be refused.

cleartext sessions are not accepted on this server

Instead of ftp://, you must use ftps://. By default, FTP users will be brought to the / root directory on the server.

Filezilla FTP Client

Filezilla download link: https://filezilla-project.org/download.php?type=client

In Filezilla, you can use the SFTP protocol (FTP over SSH)

  • sftp://ftp.example.com   port 22

or use the FTPES protocol (FTP over explicit TLS)

  • ftpes://ftp.example.com  port 21

Please note that Filezilla doesn’t trust any certificate (self-signed or CA-signed) by default. Users must choose to trust certificate for themselves.

filezilla unknown certificate

FileZilla Unknown Certificate Warning

Set Default Directory (SFTP)

If you use the SFTP protocol, you can change the default directory for FTP login.

Edit the SSH server configuration file.

sudo nano /etc/ssh/sshd_config

Find the following line.

Subsystem sftp /usr/lib/openssh/sftp-server

Change it to:

Subsystem sftp internal-sftp

Then add the following lines at the end of this file.

Match User username
        ChrootDirectory /
        ForceCommand internal-sftp -d /var/www/html/

In the above lines, I set the default directory to /var/www/html/, so when the user logs in over SFTP, the default directory would be set to /var/www/html/.  You need to change the username to your real username.

Save and close the file. Then restart SSH server.

sudo systemctl restart ssh

Auto-Renew TLS Certificate

You can create Cron job to automatically renew TLS certificate. Simply open root user’s crontab file.

sudo crontab -e

Add the following line at the bottom of the file.

@daily certbot renew --quiet && cd /etc/letsencrypt/live/ftp.example.com/ && cat fullchain.pem privkey.pem | tee /etc/ssl/private/pure-ftpd.pem && systemctl restart pure-ftpd

It’s necessary to reload pure-ftpd to make it pick up the new certificate and private key.

Wrapping Up

I hope this tutorial helped you set up a secure FTP server with Pure-FTPd on Ubuntu. As always, if you found this post useful, then subscribe to our free newsletter. You can also follow us on Twitter or like our Facebook page.

You may also want to set up SSH passwordless login.

Secure your SSH service with two-factor authentication.

Rate this tutorial
[Total: 5 Average: 5]

11 Responses to “How to Set Up a Secure FTP Server with Pure-FTPd on Ubuntu

  • LinuxGuy
    5 years ago

    What port should I open in firewall?

    • Xiao Guo An (Admin)
      5 years ago

      You should open port 20 and 21. For example, use UFW.

      sudo ufw allow 20,21/tcp
    • ports 20 and 21 are used for when FTP is in the active mode. some clients behind firewalls out of their own reach however will find they need passive mode, and then you need to open just port 21/tcp and a range of ports on the high end, to get ftp working. but you would need to tell pure-ftpd about it like so:

       # echo "55521 55522" > /etc/pure-ftpd/conf/PassivePortRange

      This writes a port range 55521-55522 into the file PassivePortRange, in our example pure-ftpd would have two ports to connect two times to (a) client(s) at max. If you want to have more connections, just add some more ports to the range. like write “55521 55530” if you want to have 10 ports, which pure-ftpd will then be able to choose randomly for sessions.

      Hope that helps someone.
      h08

      then restart the service

      # servicepure-ftpd-mysql restart

      make sure you open the ports you gave pure-ftpd for passive connections in your firewall, like Xiao Guo An explained above.

  • Wesley Santos
    4 years ago

    Hi Xiao, do you have a tutorial for setting up FTP server on Ubuntu 18.04 or Debian 10?

    best regards,
    Wesley Santos

    • Xiao Guoan (Admin)
      3 years ago

      This tutorial works on all current Ubuntu releases. It might also work on Debian 10 without changing anything in the commands.

  • The tutorial helps a lot, unfortunately, I am struggling with getting a valid certificate from Letsencrypt. I am using the Nginx-stack and receive the following error when requesting a certificate:

    I have set up a valid DNS-A record and it is up and running (I replaced the original domain with mydomain.com for this comment)

    ———-

    http-01 challenge for sftp.mydomain.com
    Using the webroot path /var/www/Pure-FTPd for all unmatched domains.
    Waiting for verification…
    Challenge failed for domain sftp.mydomain.com
    http-01 challenge for sftp.mydomain.com
    Cleaning up challenges
    Some challenges have failed.

    IMPORTANT NOTES:
    – The following errors were reported by the server:

    Domain: sftp.mydomain.com
    Type: unauthorized
    Detail: Invalid response from
    https://sftp.mydomain.com/.well-known/acme-challenge/eQwg9ieTsV-4uCuStdRYXXXXXXXXXNy64AlqopMMlY0
    [XX.XXX.XXX.XX]: “\r\n404 Not<br /> Found\r\n\r\n

    404 Not
    Found

    \r\n


    nginx\r\n”

    To fix these errors, please make sure that your domain name was
    entered correctly and the DNS A/AAAA record(s) for that domain
    contain(s) the right IP address.

    ——————-
    How can I proceed in this case? I guess the issue stems somehow from the fact that I am using the same server for an Iredmail mailserver and so I guess port 80 is already used by the mail application (though it is using another domain name) and cannot be used again. I hardly ever use Nginx for I tend to use Apache normally, so I am really struggling here at the moment. Any help is highly appreciated.

  • Great, works fine. Thanks!

  • sudo netstat -lnpt | grep pure-ftpd

    netstat is no longer working in Ubuntu 20.04 lts

  • MaltaCode
    1 year ago

    Hi Xiao,

    How would one set up this using an OpenLightSpeed HTTP server running on Ubuntu 20.04 and CyberPanel?
    It would help me a lot if I can offer sftp to my customers.

Leave a Comment

  • Comments with links are moderated by admin before published.
  • Your email address will not be published.
  • Use <pre> ... </pre> HTML tag to quote the output from your terminal/console.
  • Please use the community (https://community.linuxbabe.com) for questions unrelated to this article.
  • I don't have time to answer every question. Making a donation would incentivize me to spend more time answering questions.

The maximum upload file size: 2 MB. You can upload: image. Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded. Drop file here