10. Install ProFTPD

by Cover Tower - Updated October 15, 2021

From time to time, you may 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, we create a user for FTP access, without shell access. We’ll 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

We also create a group for FTP users, that we can call ftpgroup:

addgroup ftpgroup

We add the FTP user to the FTP group:

adduser george ftpgroup

Next, make a copy of the original /etc/proftpd/proftpd.conf file:

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

You need to edit the /etc/proftpd/proftpd.conf file as follows:

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.2. 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


In order to use TLS, you have to create an SSL certificate. First create the directory where the 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

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.

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 FTP client like FileZilla. If you don’t have FileZilla installed on your local machine, you can install it from the Debian repositories (if you use Debian), or from here.

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

Host =
Protocol = FTP
User = george
Port = 1053
Password = the password for user george created earlier

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 certificate in future sessions’ 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:

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

10.3. Configure logrotate to rotate the log files

We’ll also have to 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.4. 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 edit it to 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
You can send your questions and comments to: