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
</IfModule>
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 1.2.3.4
# This is useful for masquerading address with dynamic IPs:
# refresh any configured MasqueradeAddress directives every 8 hours
<IfModule mod_dynmasq.c>
# DynMasqRefresh 28800
</IfModule>
# 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>
<IfModule mod_ratio.c>
Ratios off
</IfModule>
# 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>
<IfModule mod_ctrls.c>
ControlsEngine off
ControlsMaxClients 2
ControlsLog /var/log/proftpd/controls.log
ControlsInterval 5
ControlsSocket /var/run/proftpd/proftpd.sock
</IfModule>
<IfModule mod_ctrls_admin.c>
AdminControlsEngine off
</IfModule>
#
# 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/
<Global>
RootLogin off
RequireValidShell off
</Global>
DefaultRoot /var/www/
<Limit LOGIN>
DenyGroup !ftpgroup
</Limit>
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
</IfModule>
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:
Host: 123.123.123.123
Username: george
Password: the password for user george
created earlier
Port: 1053
Replace george
with your FTP user, 123.123.123.123
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:
/var/log/proftpd/proftpd.log
/var/log/proftpd/controls.log
{
# weekly
missingok
# rotate 7
rotate 10
compress
delaycompress
notifempty
create 640 root adm
size 2M
sharedscripts
postrotate
# reload could be not sufficient for all logs, a restart is safer
invoke-rc.d proftpd restart 2>/dev/null >/dev/null || true
endscript
}
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:
[proftpd]
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.