Last updated on November 30, 2020 by Dan Nanni
FTP or File Transfer Protocol is one of the widely used services on the Internet, mainly for transferring files from one host to other. FTP itself was not designed as a secure protocol, and as such, the classic FTP service is vulnerable to common attacks such as man in the middle and brute force attacks.
Many applications with security features can be used to set up secure FTP services. For example, FTPS (FTP Secure) uses SSL/TLS certificates to encrypt end to end data. Based on client-side requirements, FTPS can be configured to support encrypted and/or unencrypted connections. SFTP (SSH File Transfer Protocol) is another method of ensuring security of transit data. SFTP is built as an extension of SSH, and can be used with other security protocols as well.
This tutorial will focus on setting up and securing FTP service using
vsftpd with SSL/TLS enabled.
Just a bit of background: A typical FTP server listens on TCP ports
20 for data and
21 for command (also known as control port). Connection establishment and exchange of command parameters are done over port
21. FTP connections support two methods: active and passive modes. During connection establishment in active mode, the server initiates a connection from its port
20 (data) to the client. In passive mode, the server dedicates a random data port for each client session, and notifies the client about the port. The client then initiates a connection to the server's random port.
According to RFC 1635, FTP supports public access through a special user
anonymous without any password and/or user
ftp with password
ftp. In addition to such public users,
vsftpd also supports logins from local Linux users. Linux users can access their home directories i.e.,
/home/user by connecting to the server using FTP and providing their login credentials.
vsftpdon Ubuntu, Debian or Linux Mint
vsftpd on a Debian-based system, use
apt-get command. The
vsftpd service will automatically launch upon boot.
$ sudo apt-get install vsftpd
vsftpdon CentOS, Fedora or RHEL
vsftpd on a Red Hat-based system, we can easily do it using
yum. The service is started and add to system startup as well.
# yum install vsftpd # service vsftpd start # chkconfig vsftpd on
The most basic form of FTP services using
vsftpd is now ready to be used. We can access FTP service by pointing our browser to the URL
ftp://[ServerName/IP] or by connecting using FTP client like FileZilla with username
anonymous and no password OR username
ftp and password
vsftpd is installed, a system user
ftp with home directory
/var/ftp is added in the system. Whenever an anonymous FTP connection is established, the session always defaults to
/var/ftp directory. So, we can use this directory as the home directory for FTP public users. Any file/directory put in under
/var/ftp is accessible via
The location of
vsftpd configuration file is found in the following locations:
In the rest of the tutorial, use
vsftpd.conf file in the corresponding location on your Linux system.
To disable public access, we explicitly disable the user
vsftpd.conf. Only commenting out the line will not work since
vsftpd will be already running using default values. You need to restart
vsftpd as well.
# service vsfptd restart
Mandatory authentication is thus enabled, and only existing Linux users will be able to connect using their login credentials.
To enable/disable local users, we can modify
vsftpd.conf file. If we disable local users, we have to make sure that the user
anonymous is granted access.
# service vsfptd restart
To connect to the system using a specific user, we simply modify the URL as
ftp://[email protected][ServerName/IP]. The home directory of the respective user is accessible via FTP using this method.
When a user accesses a remote server using FTP, the user can navigate the entire system as long as files/directories are readable. This is not recommended at all since any user will be able to read and download system files under
/usr and other locations through a FTP session.
To make local users restricted to only their home directories during FTP sessions, we can modify the following parameter.
# service vsftpd restart
Now, local users will only be able to access their home directories, but no other files or directories in the system.
FTP is by design a clear text protocol which means anyone can easily snoop on file transfer traffic between a client and a remote FTP server. To encrypt FTP communication, you can enable SSL/TLS in
The first step is to create an SSL/TLS certificate and a private key as follows. It will store the generated certificate/key in a target
$ sudo openssl req -x509 -days 365 -newkey rsa:2048 -nodes -keyout /etc/vsftpd.pem -out /etc/vsftpd.pem
$ sudo openssl req -x509 -days 365 -newkey rsa:2048 -nodes -keyout /etc/vsftpd/vsftpd.pem -out /etc/vsftpd/vsftpd.pem
Then add the following parameters in
vsftpd.conf configuration file.
# enable TLS/SSL ssl_enable=YES # force client to use TLS when logging in allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO require_ssl_reuse=NO ssl_ciphers=HIGH # specify SSL certificate/private key (Debian/Ubuntu) # For CentOS/Fedora/RHEL, replace it with /etc/vsftpd/vsftpd.pem rsa_cert_file=/etc/vsftpd.pem rsa_private_key_file=/etc/vsftpd.pem # define port range for passive mode connections pasv_max_port=65535 pasv_min_port=64000
# service vsftpd restart
vsftpd offers several methods to control connections and user bandwidth. We will use a couple of them to tune our FTP server.
## bandwidth allocation per anonymous session is set to roughly 30 KB/s ## anon_max_rate=30000 ## each local user is granted roughly 30 KB/s bandwidth ## local_max_rate=30000 ## client session is terminated after being idle for 300 seconds ## idle_session_timeout=300 ## maximum number of connections per source IP, which can help secure against DoS and DDoS attacks ## max_per_ip=50
Finally, if you are running
iptables firewall on your system (e.g., CentOS), make sure to adjust firewall rules to allow FTP traffic. The following rules should help you get started.
# iptables -I INPUT -p tcp --dport 20 -j ACCEPT # iptables -I INPUT -p tcp --dport 21 -j ACCEPT # iptables -I INPUT -p tcp --dport 64000:65535 -j ACCEPT
The first two rules allow traffic on FTP data/control ports. The last rule allow passive mode connections whose port range is already defined in
In case you encounter any issue during the setup in this tutorial, you can enable logging by modifying the following parameter in
xferlog_enable=YES xferlog_std_format=NO xferlog_file=/var/log/vsftpd.log log_ftp_protocol=YES debug_ssl=YES
# service vsftpd restart
There are several FTP clients which support SSL/TLS, notably, FileZilla. To connect to an SSL/TLS-enabled FTP site on FileZilla, use the following setting for the FTP host.
The first time you are connecting to an SSL/TLS-enabled FTP server, you will be presented with the site's certificate. Go ahead and trust the certificate to log in.
1. If you are getting the following error while connecting to a FTP server, it may be because your firwall is blocking FTP traffic. Make sure that you opened your firewall for necessary FTP ports as described above.
ftp: connect: No route to host
2. If you are getting the following error when connecting to a
chroot-ed FTP server running on CentOS/RHEL, disabling SELinux is one option.
500 OOPS: cannot change directory:/home/dev Login failed.
While turning off SELinux is a quick solution, it may not be safe to do so in a production environment. So instead, turning the following boolean on in SELinux can fix the problem.
$ sudo setsebool -P ftp_home_dir on
3. If you are getting the following errors while accessing an SSL/TLS-enabled FTP server on FileZilla, make sure to add
vsftpd.conf. The default cipher (
DES-CBC3-SHA) is not supported by FileZilla.
Trace: GnuTLS alert 40: Handshake failed Error: GnuTLS error -12: A TLS fatal alert has been received.
"SSL_accept failed: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher"
To sum up, setting up a FTP server using
vsftpd is not difficult. The default installation with user
anonymous should be able to support small classic FTP services.
vsftpd has many tunable parameters that make it versatile.
Hope this helps.