Introduction
FTP stands for File Transfer Protocol which is used for transferring file between a centralized server and clients over a network. This tutorial describes the installation, configuration and securing process of FTP server. This tutorial uses VSFTPD
as a FTP server software which stands Very Secure FTP Daemon.
The communication between FTP client and server is done by using two type of connection namely control connection and a data connection. Control connection is used to send commands to FTP server such as LIST
to list files and folders on the server. Then the server sends the list of files and folders using data connection. The control connection uses port 21
and the data connection port depends on the mode, namely active and passive.
Active Mode
In active mode, FTP client uses a random unprivileged port (N > 1023) to connect to FTP server on port 21. Then the client starts listening on port N+1 and sends FTP command PORT N+1
to the FTP server. The server will connect to listening client port N+1
from the local data port 20
For example:
- Client uses port
1026
to connect to server's command port21
. - Send the command
PORT 1027
to server's command port21
. - Server uses port
20
to connect to port1027
. - Finally, the client sends an TCP ACK message.
Start FTP client in debug mode to view connection details when connecting to FTP server:
ftp -d <IP>
NOTE: When using active mode, the client-side firewall must allow the data port the client is listening on. If the client uses NAT, the FTP user needs port redirection.
Passive Mode
In passive mode, the FTP client initiates a control connection using a random unprivileged port (N > 1023) to server on port 21 and instead of sending PORT N+1
command to indicate the port that the client is listening on for incoming data connection, the client will send PASV
command to FTP server. Then the server send back a port on which server is listening for incoming data connection.
For example:
- Client uses port
1026
to connect to server's command port21
. - Send the command
PASV
to server. - The client connects using port
1026
to port2024
sent by the server in response to thePASV
command. - Finally, the server sends an TCP ACK message.
Configure FTP server
Install FTP Server
First start by installing VSFTPD
using your package manager:
sudo apt install vsftpd
Configure FTP Server
VSFTPD
uses /etc/vsftpd.conf file as main configuration file. So backup this file before modifying it in case we need to restore the default configuration of FTP server:
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
Now open the configuration file and change (uncomment or add) the value of the following directives:
anonymous_enable=NO # Disable anonymous login
local_enable=YES # Permit local logins
dirmessage_enable=YES # Enable showing of messages when users first enter a new directory
xferlog_enable=YES # A log file will be maintained detailing uploads and downloads
connect_from_port_20=YES # Use port 20 (ftp-data) on the server machine for PORT style connections
listen=NO # prevent vsftpd from running in standalone mode
listen_ipv6=YES # vsftpd will listen on an IPv6 socket instead of an IPv4 one
pam_service_name=vsftpd # name of the PAM service vsftpd will use
write_enable=YES # Enable FTP commands which change the filesystem
chroot_local_user=YES # Restrict users to browse only their home directory, otherwise they will have access to the entire filesystem on the server
user_sub_token=$USER # Variable that holds username in /etc/vsftpd.userlist file
local_root=/home/$USER/ftp # Replace the home directory of each user in /etc/vsftpd.userlist file
userlist_enable=YES # Allow or deny access to users in a list
userlist_file=/etc/vsftpd.userlist # List of users to aloow or deny access
userlist_deny=NO # Allow only users listed in the above file
ssl_enable=YES # Enable SSL connection
rsa_cert_file=/etc/ssl/private/vsftpd.pem # SSL certificate
rsa_private_key_file=/etc/ssl/private/vsftpd.pem # SSL certificate's private key
allow_anon_ssl=NO # Deny anonymous user from using SSL connection
force_local_data_ssl=YES # Force all non-anonymous logins to use SSL connection for data transfer.
force_local_logins_ssl=YES # Use ssl connection during logins
ssl_tlsv1=YES # Use TLS instead of SSL because SSL is more secure
ssl_sslv2=NO # Deny SSL version 2
ssl_sslv3=NO # Deny SSL version 3
require_ssl_reuse=NO # All data connection need to prove that they know the same master secret as the control connection
ssl_ciphers=HIGH # SSL ciphers to use for encrypted connection
pasv_enable=YES # Enable passive mode
pasv_min_port=10091 # Port range to use in passive mode
pasv_max_port=10095 # Port range to use in passive mode
pasv_addr_resolve=YES # IP address of the host where the data is located, which will be sent to the FTP client in passive mode in response to the PASV command
pasv_address=<your-domain-name> # FQDN of data host which will be resolved by above line before sending to FTP client
listen_port=<port> # Listen on XXXX for incoming FTP connections. Default to port 21 if not specified
log_ftp_protocol=YES # All FTP requests and responses are logged
Generate SSL certificate
We have enabled SSL in our configuration file but have not yet created an SSL certificate:
sudo openssl req -x509 -nodes -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem -days 365 -newkey rsa:2048
req
– Create a Certificate Signing Request (CSR).-x509
– Certificate format.-days
– Period of validity of the certificate.-newkey
– Create a new private key.-rsa:2048
– 2048 bit length private key.-keyout
– Key file storage location.-out
– Certificate storage location (NOTE: both certificate and key are stored in the same file: /etc/ssl/private/vsftpd.pem)
Create an FTP user
Now create an FTP user on the server which will be used by the FTP client to authenticate to the FTP server:
sudo useradd -m ftpuser
-m
Create a home directory for FTP userftpuser
.
Then add the newly created user to /etc/vsftpd.userlist file in order to allow FTP access to that user:
sudo su -c "echo 'ftpuser' >> /etc/vsftpd.userlist"
And also don't forget to disable login access to ftpuser
, which will prevent ftpuser
from getting an interactive shell.
Chroot FTP Users
We have placed authorized users in a chroot jail, which means the authorized user cannot access directories/files outside of their home directory. But when the chroot_local_user
directive value is set to YES
, the write_enable
directive will not work because the chroot denies writing access. We can enable writing access by setting allowed_writeable_chroot
directive's value to YES
but it can lead to Roaring Beast attack.
We need to create a new home directory for the FTP user to allow write access and at the same time avoid the previously mentioned security issues:
mkdir /home/ftpuser/ftp
chown nobody:nogroup /home/ftpuser/ftp
chmod a-w /home/ftpuser/ftp
mkdir /home/ftpuser/ftp/files
chown ftpuser:ftpuser /home/ftpuser/ftp/files
chmod 0700 /home/ftpuser/ftp/files/
Apply Changes
Before applying changes to FTP server by restarting, check the above configuration file for any errors:
sudo /usr/sbin/vsftpd /etc/vsftpd.conf