## Pre-Install notes The "Very Secure FTP Daemon" is highly configurable package in many aspects. These include virtual users, SSL transfers, chrooting, and so on. This guide sets up VSFTP with the following features: * A modified FTP root at `/tempftpdir` * A sample virtual user called `tempuser` * The user will be chrooted to `/tempftpdir/tempuser` * All transactions will take place over implicit SSL * The daemon will run as a standalone service (i.e. will not involve xinetd) ## Download and install VSFTPD and associated packages yum install vsftpd db4-utils db4 The last two packages are for the Berkeley DB which PAM uses to look up virtual users and their passwords. ### Basic configuration The config file is found at `/etc/vsftpd/vsftpd.conf` Here are the pertinent directives which have changed from the original file (which I'm assuming you will back up before trying this stuff.) anonymous_enable=NO dirmessage_enable=NO xferlog_file=/var/log/vsftpd.xferlog.tempftpdir.log ftpd_banner=Welcome to the CLCG FTP droppoint. Please note that all activity is logged. # Comment this directive (we will be using another for virtual users) pam_service_name=vsftpd ## Managing virtual users ### Create the database You will need to create a text file which has the usernames and passwords on newlines. E.g. user1 password1 user2 password2 In this case, I'm going to create a user called **tempuser** with the password **tempuserpass**. So I create a file called "userlist.txt" with the following contents: tempuser tempuserpass Now I can create the database for the PAM using this: db_load -T -t hash -f userlist.txt vsftpd-virtual-user.db ### Configure the home directory Since the FTP root is `/tempftpdir`, you will need to add a home directory that `tempuser` can be chrooted to. mkdir /tempftpdir/tempuser chown -R ftp:ftp /tempftpdir It should be obvious why `ftp:ftp` owns this directory; `tempuser` is a *virtual* user and so does not have any entry in `/etc/passwd`! ### Tell PAM about the database Head over to `/etc/pam.d/` and create a file called `vsftpd.withvirtualusers` The filename can be anything you want. You will need to remember it later! Add the following to the new file: #%PAM-1.0 auth       required     pam_userdb.so db=/etc/vsftpd/vsftpd-virtual-user account    required     pam_userdb.so db=/etc/vsftpd/vsftpd-virtual-user session    required     pam_loginuid.so ### Configuring VSFTPD to have virtual users Append the following to the configuration file: ```bash # Allow virtual users virtual_use_local_privs=YES guest_enable=YES user_sub_token=$USER # Change the FTP root  local_root=/tempftpdir/$USER chroot_local_user=YES hide_ids=YES # Use the new file we just created; this is why it was commented earlier! pam_service_name=vsftpd.withvirtualusers # Define passive ports pasv_min_port=12000 pasv_max_port=12003 ``` At this point, you should be ready to start the service. However, you need to poke a hole in your firewall to allow FTP connections ## Configuring IPTABLES to allow FTP # Allow VSFTPD and associated passive connections -A INPUT -m state --state NEW,ESTABLISHED -p tcp --dport 21 -j ACCEPT -A INPUT -m state --state NEW,ESTABLISHED -p tcp --dport 12000:12003 -j ACCEPT Restart the iptables service (do it properly and use `iptables-save` and `iptables-restore`) ## Start the service service vsftpd start Check if it's listening to port 21 by trying this... netstat -tulpn | grep :21 ... and seeing something like this: tcp        0      0 0.0.0.0:21                  0.0.0.0:*                   LISTEN      29790/vsftpd Try it out by logging in as `tempuser` with `tempuserpass`. All should go well :) ## Securing VSFTPD with SSL Assuming things have been amazing thus far, you can now SSL enable the service for logins and transfers. ### Generate an RSA certificate cd /etc/vsftpd openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout vsftpd.pem -out vsftpd.pem Here's the standard output of this command: ``` Generating a 1024 bit RSA private key .......++++++ ........................................++++++ ## writing new private key to '/etc/vsftpd/vsftpd.pem' You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, ## If you enter '.', the field will be left blank. Country Name (2 letter code) [GB]:US State or Province Name (full name) [Berkshire]:Iowa Locality Name (eg, city) [Newbury]:Iowa City Organization Name (eg, company)  [My Company Ltd]:Coordinated Laboratory for Computational Genomics Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:ftp.example.com Email Address []:clcg.it@gmail.com ``` ### SSL-enable VSFTPD Open up `/etc/vsftpd/vsftpd.conf` and append the following: # Enable SSL ssl_enable=YES force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO rsa_cert_file=/etc/vsftpd/vsftpd.pem Your certificate must be in PEM format and include *both* the public and private keys. Here's an example of what it would look like: -----BEGIN CERTIFICATE----- MIIEHTCCA4agAwIBAgIBFjANBgkqhkiG9w0BAQUFADCB1zELMAkGA1UEBhMCVVMx DTALBgNVBAgTBElvd2ExEjAQBgNVBAcTCUlvd2EgQ2l0eTEfMB0GA1UEChMWVGhl IFVuaXZlcnNpdHkgb2YgSW93YTE+MDwGA1UECxM1VGhlIENvb3JkaW5hdGVkIExh Ym9yYXRvcnkgZm9yIENvbXB1dGF0aW9uYWwgR2Vub21pY3MxHjAcBgNVBAMTFXN1 cHBvcnQuZW5nLnVpb3dhLmVkdTEkMCIGCSqGSIb3DQEJARYVc3VwcG9ydEBlbmcu dWlvd2EuZWR1MB4XDTEyMDQyNzE4MDgwMFoXDTIyMDQyNTE4MDgwMFowgb8xCzAJ BgNVBAYTAlVTMQ0wCwYDVQQIEwRJb3dhMR8wHQYDVQQKExZUaGUgVW5pdmVyc2l0 eSBvZiBJb3dhMT4wPAYDVQQLEzVUaGUgQ29vcmRpbmF0ZWQgTGFib3JhdG9yeSBm b3IgQ29tcHV0YXRpb25hbCBHZW5vbWljczEaMBgGA1UEAxMRcWluLmVuZy51aW93 DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANCYdLYqvSJ4XYiJwl2Bcmc7A/bs 7RbmeEqmdCBEF/ORZ1Qz3PZkAgDiaSNCdNU8/Z1RMzK8yxQpNTlUO0rTTxmEpCkl TLMfvGL5+ef8dry9+dT9VZZTncW9GizQpAlKd9Bix3I7XHN/1MdjWs4zmvjgxARX qYGKCLrwBX8VueimV2h1ac50ngAxMHMjQGF6LvdqkGJcwOfg/ArWU5dlu1U9DkAI 1QvhTqu0+GfvPKbdVp3VdxPJwbCxBFRbiao7QgrnHBSwnhExR6engcPMMcto3b+R N+1CJ5RyMmpPVRF9dx+ey3WsZkZBmpCpMMUM8UqMrGyRE36OVnloOPRC3WkCAwEA AaOBijCBhzAJBgNVHRMEAjAAMDoGCWCGSAGG+EIBDQQtFitDTENHIEdlbmVyYXRl ZCBDZXJ0aWZpY2F0ZSAoT3BlblNTTCB2MC45LjYpMB0GA1UdDgQWBBTKWGxGUSgn VW1NrP/04akS1qXtBDAfBgNVHSMEGDAWgBSMMdfJB8d71bkJ62WSA8T2X2GrBTAN BgkqhkiG9w0BAQUFAAOBgQAhJpwbcbUS7pLYEahppPin5+6DDtPNqTjVvpHHjpL0 ZMYEw1E8STzc96FlWO1r/NrHrB1R3qqn5Ptynk7hEH0IrIJjWhv36GCDEvTxpQri Kir4Qt3i5hFWiSJnB5/BrRcqnHFYKhcwZvF72Da3B1oxQPI9J0eaAxHLiYfUVfys IA== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA0Jh0tiq9InhdiInCXYFyZzsD9uztFuZ4SqZ0IEQX85FnVDPc 9mQCAOJpI0J01Tz9nVEzMrzLFCk1OVQ7StNPGYSkKSVMsx+8Yvn55/x2vL351P1V llOdxb0aLNCkCUp30GLHcjtcc3/Ux2NazjOa+ODEBFepgYoIuvAFfxW56KZXaHVp znSeADEwcyNAYXou92qQYlzA5+D8CtZTl2W7VT0OQAjVC+FOq7T4Z+88pt1WndV3 E8nBsLEEVFuJqjtCCuccFLCeETFHp6eBw8wxy2jdv5E37UInlHIyak9VEX13H57L daxmRkGakKkwxQzxSoysbJETfo5WeWg49ELdaQIDAQABAoIBAQCPiakeRXCajKsI LouB3naD1JdYzhYjoPn7nGjiXxkAMPkidwHAxnaedy4T5kIRDgQSwfJyInm36NdI GM8oIRoYHC7+ZT1PMTJoBU3TNeXa4PtOdfj0FZvGmuatGfEWt5iU27QUxgZLMBaS ++8Joqb6k5M3pfbuA0wtf083EN/mz20pIC2q/EEWd7Za8PPb7+t8iWMnLECg5Ulp urSj37X9p7M5b3Spf3FksL5YKG/tzvHa7+9hRFScpldt+dKDtN5SKxanlObD10Dv RRFqzVwBAoGBAO1YJRnTfYFqCl+Bt311Vtm8TDqYRBNlfaZjX+dG20zEX8LjLbXl YumrdD62uii+KhJVzLyIwh++cKB5MCR2PZZwPX+WAJ5vGk7pfHEi+/5dPttM5k0q gtirDlwaGJjTa4lVQTP/x0uxGMT03b8+q9qzDcdisx+7EMtS3EZuNWvpAoGBAOD9 042RpbyTNXfa38Bl2Or2wuuB5Z2T9Zu9+WlnqdwrXNx9ocRl2XyYJVwfL7DY9nSr 9VJF/aWe5Bmc9/um6/IGry0auw7M4vGBSRNIFFx5411DIheVdsuZPZT+Hop6woUk Xr91AtJhpOci4uErmgq9HM8OA3NAWShRLDIDFnWBAoGBAMhGOcBKMrxyQ2CF79SA oBHJDzXeaItJd7ZgYnug0co8ZmXoFxlG/6kXkVaeEAXzOUMRfVqVt+DbbOQsftA1 qhB4k5xGci0+qR9vbB93mtXvzut0P11cAt9bsBlNt/W1aSeQdh2vtncLcFA6I6eN 9avsrTLS+T1MN4aqW89ejduJAoGBAKrTLa+cOQkvf/YrYZ1z9rmXd7FWI997uoxw NhE4mvhGmC/010EFz5ZQ8nS6XPxaDu3Qree0qnv4Ytmrm4EfYJ+XQaPuWr5HA7w3 3CLepE7+YImr8hOT8OluxRn9w3SC9nQehC27itPvPUQc8cPi1gd3RItU6Xu1DLyW vQaP35qBAoGAbfJUtnAk/FuFFQ3bUmOyqC44lURYXqpDBWlTCiA6cXoZ5ciudcW3 vhIGg1EPda+fliy1LolV1AjG73+vnDgykggu8H1fOKEv7MfvsaLwGUovsz5MeXN+ xTI8WOKyrAg8ON1DI3uWVhb07HBUGcWS1vUxESXqa9K4+bAbRYFT/9U= -----END RSA PRIVATE KEY----- ### Restart the service service vsftpd condrestart You can now use an FTP client which supports implicit SSL (Transmit and Fugu for OS X, FileZilla, etc) and try out the connection. The ordinary `ftp` won't work and will give you the following error: Connected to ftp.example.com. 220 Welcome to the FTP droppoint. Please note that all activity is logged. Name (ftp.example.com:tech): tempuser 530 Non-anonymous sessions must use encryption. If you're a command-line freak like I am, you can always use `ftp-ssl` ## Other notes * The passive ports *must* be defined! Not doing so will result in a very long delay between initiating a connection and viewing a directory listing. * VSFTPD can be configured for anonymous logins whereby a user can download a file but not upload anything (like the CentOS mirrors.) * Add `listen_address=127.0.0.1` to listen on a given address. ## Resources ### Script to add users to database ```bash #!/bin/bash # Add a virtual FTP user to VsFTPd's Berkeley DB # by Nikhil Anand, Mon Feb 22 09:30:45 CST 2010 # Paths to config path and custom FTP directory VSFTPDPATH="/etc/vsftpd" DROPPOINT="/data/ftp" # Usage information if [ $# -ne 2 ]; then echo -e "USAGE: `basename $0` \n" echo -e " Using this without the parameters will refresh the DB used by the VsFTP daemon" db_load -T -t hash -f $VSFTPDPATH/userlist.txt $VSFTPDPATH/vsftpd-virtual-user.db echo -e " Database refreshed." echo -e " Edit $VSFTPDPATH/userlist.txt to make any changes to virtual users." echo -e " Run this script again when you're done." exit fi # Define username and password USERNAME="$1" PASSWORD="$2" # Add username and password to flat text file echo $USERNAME >> $VSFTPDPATH/userlist.txt echo "$PASSWORD" >> $VSFTPDPATH/userlist.txt echo -e "Added ( $USERNAME : $PASSWORD ) to $VSFTPDPATH/userlist.txt" # Refresh the Berkeley DB to reflect these additions db_load -T -t hash -f $VSFTPDPATH/userlist.txt $VSFTPDPATH/vsftpd-virtual-user.db echo -e "Reloaded database \"vsftpd-virtual-user.db\"" # Create a home directory inside the FTP directory mkdir $DROPPOINT/$USERNAME chown -R ftp:ftp $DROPPOINT/$USERNAME echo -e "Created and changed permissions for $DROPPOINT/$USERNAME" ``` ### Relevant web URIs * [Good explanation of Active and Passive mode FTP](http://slacksite.com/other/ftp.html) * [VSFTPD documentation](http://www.redhat.com/docs/manuals/enterprise/RHEL-5-manual/Deployment_Guide-en-US/s2-ftp-servers-vsftpd.html)