FTP - vsftpd in RHEL 7

FTP

FTP uses a client-server architecture to transfer files using the TCP network protocol. Because FTP is a rather old protocol, it uses unencrypted user name and password authentication. For this reason, it is considered an insecure protocol and should not be used unless absolutely necessary. However, because FTP is so prevalent on the Internet, it is often required for sharing files to the public. System administrators, therefore, should be aware of FTP’s unique characteristics.

Active FTP vs Passive FTP

Active mode

In Active mode FTP client doesn’t make the actual connection to the data port of the server, it simply tells the server what port it is listening on and the server connects back to the specified port on the client. From the client side firewall this appears to be an outside system initiating a connection to an internal client, something which is usually blocked and need to take care of.

Active FTP is beneficial to the FTP server admin, but detrimental to the client side admin. The FTP server attempts to make connections to random high ports on the client, which may be blocked by a firewall on the client side.

Flow-Graph:

  1. FTP client connects from a random unprivileged port (N > 1023) to the FTP server’s command port 21.
  2. Server then sends an “ACK” back to the client’s command port.
  3. Server initiates a connection on its local Data port to the Data port the client specified earlier in step-1.
  4. Finally client sends an ACK.

Passive mode

Passive mode FTP solves many of the problems from the client side, while it opens up a whole range of problems on the server side. The biggest issue is the need to allow any remote connection to higher numbered ports on the server.

Passive FTP is beneficial to the client, but detrimental to the FTP server admin. The client will make both connections to the server, but one of them will be to a random high port, which may be blocked by a firewall on the server side.

Flow-Graph:

  1. FTP client contacts from a random unprivileged port (N > 1023) on the server’s command port 21 and issues the PASV command.
  2. Server then opens a random unprivileged port (P > 1023) and sends P back to the client in response to the PASV command.
  3. The client then initiates the data connection from its (N+1 > 1023) data port to the specified server data port in step-2.
  4. Finally, the server sends back an ACK in step 4 to the client’s data port.

The vsftpd Server

The Very Secure FTP Daemon (vsftpd) is designed from the ground up to be fast, stable, and, most importantly, secure. vsftpd is the only stand-alone FTP server distributed with Red Hat Enterprise Linux, due to its ability to handle large numbers of connections efficiently and securely.

Installing, Starting and Stopping vsftpd

  • Verify that the vsftpd package is installed.
# rpm -qa | grep vsftpd
  • If it is not installed, please install it as follows:
# yum install vsftpd
  • Using an editor, open the file ‘/etc/vsftpd/vsftpd.conf’.

If you would like the FTP server to be accessed by anonymous, make sure the following lines are uncommented:

anonymous_enable=YES

If you would like the FTP server to be accessed by local user, make sure the following lines are uncommented:

local_enable=YES
  • To start the vsftpd service in the current session, type the following at a shell prompt as root:
# systemctl start vsftpd.service
  • To stop the service in the current session, type as root:
# systemctl stop vsftpd.service
  • To configure the vsftpd service to start at boot time, type the following at a shell prompt as root:
# systemctl enable vsftpd.service

ftp commands

  • Connect to FTP Server via Command Line
$ ftp 10.66.192.120
  • Upload Single File to FTP Server
ftp> cd uploads
ftp> put mariadb.dump
  • Download Single File from FTP Server
ftp> get readme.txt

A Java Example Of FTPClient

Create a FTPClient

FTPClient client = new FTPClient();
client.setControlEncoding(FTP.DEFAULT_CONTROL_ENCODING);

client.connect("localhost", 21);
if (!FTPReply.isPositiveCompletion(client.getReplyCode())){
    throw new Exception("Failed to connect to ftp server");
}

if (!client.login("kylin", "AWSDRDS")) {
    throw new Exception("Failed to login to ftp server");
}

client.changeWorkingDirectory("/home/kylin/vsftpd");
client.enterLocalActiveMode();
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setBufferSize(2048);

Download file from ftp Server

ByteArrayOutputStream output = new ByteArrayOutputStream();
client.retrieveFile("marketdata-price.txt", output);
byte[] bytes = output.toByteArray();
System.out.println(new String(bytes));

Note that, above code download file to byte arrays, and output the file contents.

Add a file to ftp server

client.storeFile("marketdata-price2.txt", new ByteArrayInputStream(bytes));
InputStream in = client.retrieveFileStream("marketdata-price2.txt");
byte[] newBytes = convert(in);
if(!Arrays.equals(bytes, newBytes)) {
    throw new Exception("Should equals");
}
in.close();
client.completePendingCommand();

Above code add a marketdata-price2.txt to remote ftp server

Delete ftp server file

boolean success = client.deleteFile("marketdata-price2.txt");
if(!success) {
    throw new Exception("Delete Failed");
}

Above code will delete file marketdata-price2.txt from ftp server.

Configuring vsftpd with SSL/TLS on RHEL 7

  • In order to use SSL/TLS encryption, FTP server requires a certificate to be installed, use openssl to generate a self-signed x509 certificate
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes

NOTE: without the -nodes option, the resulting private key will be encrypted with a passphrase supplied by the user.

  • Place a certificate in /etc/pki/tls/certs/cert.pem
mv cert.pem /etc/pki/tls/certs/cert.pem
  • Place a private key in /etc/pki/tls/private/key.pem
mv key.pem /etc/pki/tls/certs/key.pem
  • Modify owner and permission it so that root is the only user that can read this file:
chmod 777 /etc/pki/tls/certs/cert.pem
chown root:root /etc/pki/tls/certs/cert.pem
  • Edit the vsftpd configuration file /etc/vsftpd/vsftpd.conf, append or modify the options as shown below:
## SSL/TSL configuration
ssl_enable=YES

# To allow anonymous  users to use SSL
allow_anon_ssl=YES

# To force anonymous users to use SSL
force_anon_data_ssl=YES
force_anon_logins_ssl=YES

# To force local users to use SSL
force_local_data_ssl=YES
force_local_logins_ssl=YES

# The following option depend of the authentication mode you require
ssl_tlsv1=YES     for TLS
ssl_sslv2=YES    for SSL Version 2
ssl_sslv3=YES    for SSL Version 3

# This values must be adjust according with you environment    
rsa_cert_file=/etc/pki/tls/certs/cert.pem
rsa_private_key_file=/etc/pki/tls/private/key.pem
  • Restart vsftpd
systemctl restart vsftpd.service