10. Install ProFTPD

by Double Bastion - Updated January 27, 2022

From time to time, you will want to upload files to your server via FTP. Therefore, you will need a FTP server, like ProFTPD. Install ProFTPD and OpenSSL, a very important cryptography library, by running:

apt-get install proftpd-basic openssl

You can check the ProFTPD version with:

proftpd -v

10.1. Create ProFTPD users

First, create a user for FTP access, without shell access. You can call this user george. Replace george with a name that you find suitable for the FTP user.

adduser --shell /bin/false george

Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for george
Enter the new value, or press ENTER for the default<--ENTER
    Full Name []: <--ENTER
    Room Number []: <--ENTER
    Work Phone []: <--ENTER
    Home Phone []: <--ENTER
    Other []: <--ENTER
Is the information correct? [Y/n] <--Y

Create a group for FTP users. You can call it ftpgroup:

addgroup ftpgroup

Add the FTP user to the FTP group:

adduser george ftpgroup

You can create other FTP users and add them to the FTP group in a similar way.

10.2. Configure ProFTPD

Make a copy of the original /etc/proftpd/proftpd.conf file:

cp /etc/proftpd/proftpd.conf /etc/proftpd/proftpd.conf_orig

Open the /etc/proftpd/proftpd.conf file for editing:

nano /etc/proftpd/proftpd.conf

Make all the changes marked with blue and red:

# /etc/proftpd/proftpd.conf -- This is a basic ProFTPD configuration file.
# To really apply changes, reload proftpd after modifications, if
# it runs in daemon mode. It is not required in inetd/xinetd mode.

# Includes DSO modules
Include /etc/proftpd/modules.conf

# Set off to disable IPv6 support which is annoying on IPv4 only boxes.
# UseIPv6 on
UseIPv6 off
# If set on you can experience a longer connection delay in many cases.
<IfModule mod_ident.c>
  IdentLookups off

ServerName "Debian"
# Set to inetd only if you would run proftpd by inetd/xinetd/socket.
# Read README.Debian for more information on proper configuration.
ServerType standalone
DeferWelcome off

# Disable MultilineRFC2228 per https://github.com/proftpd/proftpd/issues/1085
# MultilineRFC2228on
DefaultServer on
ShowSymlinks on

TimeoutNoTransfer 600
TimeoutStalled 600
TimeoutIdle 1200

DisplayLogin welcome.msg
DisplayChdir .message true
ListOptions "-l"

DenyFilter \*.*/

# Use this to jail all users in their homes 
# DefaultRoot~

# Users require a valid shell listed in /etc/shells to login.
# Use this directive to release that constrain.
# RequireValidShelloff

# Port 21 is the standard FTP port.
# Port 21
Port 1053

# In some cases you have to specify passive ports range to by-pass
# firewall limitations. Ephemeral ports can be used for that, but
# feel free to use a more narrow range.
# PassivePorts 49152 65534
PassivePorts 30856 30857

# If your host was NATted, this option is useful in order to
# allow passive tranfers to work. You have to use your public
# address and opening the passive ports used on your firewall as well.
# MasqueradeAddress

# This is useful for masquerading address with dynamic IPs:
# refresh any configured MasqueradeAddress directives every 8 hours
<IfModule mod_dynmasq.c>
# DynMasqRefresh 28800

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances 30

# Set the user and group that the server normally runs at.
User proftpd
Group nogroup

# Umask 022 is a good standard umask to prevent new files and dirs
# (second parm) from being group and world writable.
Umask 022 022
# Normally, we want files to be overwriteable.
AllowOverwrite on

# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
# PersistentPasswd off

# This is required to use both PAM-based authentication and local passwords
# AuthOrder mod_auth_pam.c* mod_auth_unix.c

# Be warned: use of this directive impacts CPU average load!
# Uncomment this if you like to see progress and transfer rate with ftpwho
# in downloads. That is not needed for uploads rates.
# UseSendFile off

TransferLog /var/log/proftpd/xferlog
SystemLog /var/log/proftpd/proftpd.log

# Logging onto /var/log/lastlog is enabled but set to off by default
#UseLastlog on

# In order to keep log file dates consistent after chroot, use timezone info
# from /etc/localtime.  If this is not set, and proftpd is configured to
# chroot (e.g. DefaultRoot or <Anonymous>), it will use the non-daylight
# savings timezone regardless of whether DST is in effect.
#SetEnv TZ :/etc/localtime

<IfModule mod_quotatab.c>
QuotaEngine off

<IfModule mod_ratio.c>
Ratios off

# Delay engine reduces impact of the so-called Timing Attack described in
# http://www.securityfocus.com/bid/11430/discuss
# It is on by default. 
<IfModule mod_delay.c>
DelayEngine on

<IfModule mod_ctrls.c>
ControlsEngine off
ControlsMaxClients 2
ControlsLog /var/log/proftpd/controls.log
ControlsInterval 5
ControlsSocket /var/run/proftpd/proftpd.sock

<IfModule mod_ctrls_admin.c>
AdminControlsEngine off

# Alternative authentication frameworks
#Include /etc/proftpd/ldap.conf
#Include /etc/proftpd/sql.conf

# This is used for FTPS connections
Include /etc/proftpd/tls.conf

# This is used for SFTP connections
#Include /etc/proftpd/sftp.conf

# This is used for other add-on modules
#Include /etc/proftpd/dnsbl.conf
#Include /etc/proftpd/geoip.conf
#Include /etc/proftpd/snmp.conf

# Useful to keep VirtualHost/VirtualRoot directives separated
#Include /etc/proftpd/virtuals.conf

# A basic anonymous configuration, no upload directories.

# <Anonymous ~ftp>
#   User ftp
#   Group nogroup
#   # We want clients to be able to login with "anonymous" as well as "ftp"
#   UserAlias anonymous ftp
#   # Cosmetic changes, all files belongs to ftp user
#   DirFakeUser on ftp
#   DirFakeGroup on ftp
#   RequireValidShell off
#   # Limit the maximum number of anonymous logins
#   MaxClients 10
#   # We want 'welcome.msg' displayed at login, and '.message' displayed
#   # in each newly chdired directory.
#   DisplayLogin welcome.msg
#   DisplayChdir .message
#   # Limit WRITE everywhere in the anonymous chroot
#   <Directory *>
#     <Limit WRITE>
#       DenyAll
#     </Limit>
#   </Directory>
#   # Uncomment this if you're brave.
#   # <Directory incoming>
#   #   # Umask 022 is a good standard umask to prevent new files and dirs
#   #   # (second parm) from being group and world writable.
#   #   Umask022  022
#   #   <Limit READ WRITE>
#   #     DenyAll
#   #     </Limit>
#   #       <Limit STOR>
#   #         AllowAll
#   #     </Limit>
#   # </Directory>
# </Anonymous>

# Include other custom configuration files
# !! Please note, that this statement will read /all/ file from this subdir,
# i.e. backup files created by your editor, too !!!
# Eventually create file patterns like this: /etc/proftpd/conf.d/*.conf
Include /etc/proftpd/conf.d/

    RootLogin   off
    RequireValidShell off

DefaultRoot  /var/www/

<Limit LOGIN>
    DenyGroup !ftpgroup

Replace 1053 with your custom FTP port, 30856 30857 with your custom FTP passive ports and ftpgroup with the name of your group for FTP users.

In the settings from above you are disabling root login to ProFTPD by setting RootLogon to off. DefaultRoot is added to restrict users to the specified directory. DenyGroup will allow only the users belonging to the ftpgroup to access the FTP server; all the other users will be rejected.

10.3. Enable TLS

Make a backup copy of the /etc/proftpd/tls.conf file:

cp /etc/proftpd/tls.conf /etc/proftpd/tls.conf_orig

Delete the content of the file, then open it:

cat /dev/null > /etc/proftpd/tls.conf
nano /etc/proftpd/tls.conf

Add the following content inside this file:

<IfModule mod_tls.c>

TLSEngine                  on
TLSLog                     /var/log/proftpd/tls.log
TLSProtocol                TLSv1.2 TLSv1.3
TLSOptions                 NoCertRequest
TLSRSACertificateFile      /etc/proftpd/ssl/host.cert
TLSRSACertificateKeyFile   /etc/proftpd/ssl/host.key
#Require TLS / SSL, force encrypted logins and transfers only.
TLSRequired                on
#Fix that some clients disconnect with SSL / TLS errors
TLSOptions NoSessionReuseRequired
TLSVerifyClient            off


Next, create the directory where the SSL certificate will be stored:

mkdir /etc/proftpd/ssl

Then, you can generate the SSL certificate as follows:

openssl req -new -x509 -days 54750 -nodes -out /etc/proftpd/ssl/host.cert -keyout /etc/proftpd/ssl/host.key

The output will be a list of questions to which you can answer or you can leave the fields empty by pressing Enter:

Country Name (2 letter code) [AU]: <-- Enter your Country Name (e.g., "DE").
State or Province Name (full name) [Some-State]: <-- Enter your State or Province Name.
Locality Name (eg, city) []: <-- Enter your City.
Organization Name (eg, company) [Internet Widgits Pty Ltd]: <-- Enter your Organization Name (e.g., the name of your company).
Organizational Unit Name (eg, section) []: <-- Enter your Organizational Unit Name (e.g. "IT Department").
Common Name (eg, YOUR name) []: <-- Enter the Fully Qualified Domain Name of the system (e.g. "server1.example.com").
Email Address []: <-- Enter your Email Address.

Change permissions for the key file:

chmod 400 /etc/proftpd/ssl/host.key

Open the /etc/proftpd/modules.conf file for editing:

nano /etc/proftpd/modules.conf

Uncomment the #LoadModule mod_tls.c line, to make it look like this:

LoadModule mod_tls.c

Restart the ProFTPD server:

systemctl restart proftpd

Next, open the FTP port and the passive FTP ports in the firewall using ufw:

ufw allow 1053
ufw allow 30856
ufw allow 30857

Replace 1053, 30856, 30857 with your actual ports. By default, the ufw allow portnumber command opens the specified port for both IPv4 and IPv6 access. However, if you configure a service or application to be accessible only over IPv4 (like sshd or ProFTPD), which is enough for effective communication and in some cases it can be safer, you should disable IPv6 access to the specific ports dedicated to those specific applications. To disable IPv6 access to the 3 ports mentioned above, first run:

ufw status numbered

The result will look similar to the following:

     To                         Action      From
     --                         ------      ----
[ 1] 6283                       ALLOW IN    Anywhere                  
[ 2] 1053                       ALLOW IN    Anywhere                  
[ 3] 30856                      ALLOW IN    Anywhere                  
[ 4] 30856                      ALLOW IN    Anywhere                  
[ 5] 1053 (v6)                  ALLOW IN    Anywhere (v6)             
[ 6] 30856 (v6)                 ALLOW IN    Anywhere (v6)             
[ 7] 30856 (v6)                 ALLOW IN    Anywhere (v6)

To disable IPv6 access to the FTP ports, here 1053, 30856 and 30856, run ufw delete followed by the number of the rule you want to delete, like this:

ufw delete 5

Please note that after each ufw delete command, the number of the rules that follow the rule you have just deleted will change. Therefore, after each ufw delete command you will need to run the ufw status numbered command again, to see the new numbers.

10.4. Connect to ProFTPD remotely

For george, the FTP user, to be able to upload files in a folder inside the default FTP directory (/var/www) you will have to temporarily make george the owner of that folder and its content:

chown -R george:www-data /var/www/example.com

Then, you can connect to the ProFTPD server with a FTP client like FileZilla. If you use Debian on your local machine and you don’t have FileZilla installed, you can install it from the Debian repository. Otherwise, you can install it from here.

The credentials needed to connect the FTP client to ProFTPD will be:

Username: george
Password: the password for user george created earlier
Port: 1053

Replace george with your FTP user, with the real IP of your server and 1053 with your custom FTP port.

The first time you connect, FileZilla will prompt you for an ‘Unknown certificate’. Check ‘Always trust this certificate in future sessionss.’ and click ‘OK’.

FileZilla will establish the connection to the default FTP directory, /var/www, and the user george will be able to upload/doanload/edit files in the /var/www/example.com directory, whose owner he is. After all the operations are completed, the previous ownership of that respective directory should be restored by running for example :

chown -R www-data:www-data /var/www/example.com

10.5. Configure logrotate to rotate log files

Edit the logrotate settings for ProFTPD in order to allow larger log files, necessary for ‘System Health and Security Probe’. Open the /etc/logrotate.d/proftpd-core file:

nano /etc/logrotate.d/proftpd-core

In the first block, comment out the weekly parameter, change rotate 7 to rotate 10 and add size 2M , like below:

#       weekly
#       rotate 7
        rotate 10
        create 640 root adm
        size 2M
                # reload could be not sufficient for all logs, a restart is safer
                invoke-rc.d proftpd restart 2>/dev/null >/dev/null || true

10.6. Configure Fail2ban to protect ProFTPD against brute-force attacks

Open the /etc/fail2ban/jail.local file:

nano /etc/fail2ban/jail.local

Search for the [proftpd] section and make it look like this:


enabled  = true
port     = 1053,30856,30857,ftp,ftp-data,ftps,ftps-data
filter   = proftpd
logpath  = /var/log/proftpd/proftpd.log
maxretry = 4
bantime  = 604800

Replace 1053 with your custom FTP port and 30856 and 30857 with your passive FTP ports.

Reload Fail2ban:

systemctl reload fail2ban

10.7. Upgrading ProFTPD

Since ProFTPD has been installed from the official Debian repository, to upgrade it, all you need to do is to run apt-get update && apt-get dist-upgrade with a specific frequency, as described in the Maintenance steps chapter. This command will upgrade ProFTPD if there is a new version available. Also, during these upgrades, the configuration changes implemented as described above, will be preserved.

You can send your questions and comments to: