vsftpd (“Very Secure FTP Daemon”) is an FTP server for Linux and supports PAM (“pluggable authentication modules”). A virtual user cannot login to the Linux system and is considered more secure than using a “real” user whom can login to a Linux system. This guide offers a script that demonstrates yet another way to setup a vsftpd server using PAM to connect to the MySQL server for the database while using virtual users.
While there are many guides offering techniques to install vsftpd, not many offer guides that include the use of SELinux. While most disable SELinux or do not discuss SELinux, leaving the installation somewhat incomplete resulting in end user errors, this guide incorporates SELinux by setting SELinux boolean values. While on the subject of SELinux, a guide or two have suggested using setsebool -P allow_ftpd_full_access on, which would (the way I understand it) open up the system to ftp, however using allow_ftp_home_dir (again the way I understand it), vsftp will have access not to the entire file system, but limited to /home. So this script will use the /home directory.
This script should work as is, however, you may want to make changes to usernames and passwords to fit your needs.
This script is made possible through the efforts of many throughout the years. They are referenced at the bottom of the script. The script has successfully been tested on a CentOS 6.4 on January 4, 2014 and was developed using the following application versions.
# CentOS release 6.4 (Final) # kernel-version 2.6.32-358.el6.x86_64 # vsftp-version 2.2.2-11.el6_4.1 # mysql-server-version 5.1.71-1.el6 # pam_mysql-version 1:0.7-0.12.rc1.el6
Here is the script.
#!/bin/bash # install-vsftpd.sh debugval=1 # debugval=0 A test ftp account is not created. # debugval=1 [default] A test ftp account is created. clear #---------------------------------------------------------------------------------------- # USER INPUT #---------------------------------------------------------------------------------------- echo -e "Give the root user a password for MySQL [password123]. \c" read -s MYSQL_PASS if $MYSQL_PASS; then MYSQL_PASS=password123 fi &> /dev/null echo "" #---------------------------------------------------------------------------------------- # Install vsFTPd, MySQL, and pam_mysql #---------------------------------------------------------------------------------------- # Install EPEL Repository for pam_mysql which authenticates users against MySQL rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm yum install -y vsftpd mysql-server pam_mysql #---------------------------------------------------------------------------------------- # Configure MySQL #---------------------------------------------------------------------------------------- # Enable autostart chkconfig mysqld on && service mysqld start mysql <<"EOF" CREATE DATABASE vsftpd; GRANT SELECT ON vsftpd.* TO 'vsftpd'@'localhost' IDENTIFIED BY 'vsftpdpassword'; FLUSH PRIVILEGES; USE vsftpd; CREATE TABLE `accounts` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `username` VARCHAR( 30 ) NOT NULL , `pass` VARCHAR( 50 ) NOT NULL , UNIQUE ( `username` ) ) ENGINE = MYISAM ; EOF if [[ $debugval == 1 ]]; then # Create a test account mysql <<"EOF" USE vsftpd; INSERT INTO accounts (username, pass) VALUES('user1', md5('secret')); EOF fi # Provide a root password for MySQL mysqladmin -u root password $MYSQL_PASS #---------------------------------------------------------------------------------------- # Configure vsFTPd #---------------------------------------------------------------------------------------- # Enable autostart chkconfig vsftpd on && service vsftpd start [ -d /home/users ] || mkdir -p /home/users ln -s /home/users /mnt/ftpusers # Create a non-priviledged user called 'vsftpd' with access to /mnt/ftpusers useradd -G users -s /sbin/nologin -d /mnt/ftpusers vsftpd usermod -G users -s /sbin/nologin -d /mnt/ftpusers vsftpd # Backup the vsftpd.conf file cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf-orig # Customize the vsftpd.conf file sed -i "s/^.*anonymous_enable.*/anonymous_enable=NO/g" /etc/vsftpd/vsftpd.conf sed -i "/^xferlog_std_format*a*/ s/^/#/" /etc/vsftpd/vsftpd.conf sed -i "s/#idle_session_timeout=600/idle_session_timeout=900/" /etc/vsftpd/vsftpd.conf sed -i "s/#nopriv_user=ftpsecure/nopriv_user=vsftpd/" /etc/vsftpd/vsftpd.conf sed -i "/#chroot_list_enable=YES/i\chroot_local_user=YES" /etc/vsftpd/vsftpd.conf echo " # Here the vsftpd will allow the 'vsftpd' user to login into '/mnt/ftpusers/$USER directory guest_enable=YES guest_username=vsftpd local_root=/mnt/ftpusers/$USER user_sub_token=$USER virtual_use_local_privs=YES user_config_dir=/etc/vsftpd/vsftpd_user_conf" >> /etc/vsftpd/vsftpd.conf # Create the vsftpd_user_conf directory if it does not exist. [ -d /etc/vsftpd/vsftpd_user_conf ] || mkdir -p /etc/vsftpd/vsftpd_user_conf #---------------------------------------------------------------------------------------- # Configure PAM #---------------------------------------------------------------------------------------- mv /etc/pam.d/vsftpd /etc/pam.d/vsftpd-orig echo "#%PAM-1.0 session optional pam_keyinit.so force revoke auth required pam_mysql.so user=vsftpd passwd=vsftpdpassword host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3 account required pam_mysql.so user=vsftpd passwd=vsftpdpassword host=localhost db=vsftpd table=accounts usercolumn=username passwdcolumn=pass crypt=3" > /etc/pam.d/vsftpd #---------------------------------------------------------------------------------------- # Firewall Exceptions and SeLinux Modifications #---------------------------------------------------------------------------------------- #Add vsFTPd exception to the firewall sed -i "/-A INPUT -j REJECT --reject-with icmp-host-prohibited/i -A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT" /etc/sysconfig/iptables #Append ip_conntrack_ftp to the IPTABLES_MODULE line in /etc/sysconfig/iptables-config, separated by a space. If not exists. grep -q ip_conntrack_ftp /etc/sysconfig/iptables-config 2> /dev/null || sed -i "s/IPTABLES_MODULES=\"/IPTABLES_MODULES=\"ip_conntrack_ftp /" /etc/sysconfig/iptables-config service iptables restart echo "Setting the SELinux boolean values, may take a minute." setsebool -P ftpd_connect_db on setsebool -P ftp_home_dir on restorecon -R -v /home/users service vsftpd restart #---------------------------------------------------------------------------------------- # Post-Installation Comments #---------------------------------------------------------------------------------------- echo "The installation is complete." chown -R vsftpd:users /mnt/ftpusers/ chmod -R 700 /mnt/ftpusers/ #---------------------------------------------------------------------------------------- # DEBUG: Create a test account #---------------------------------------------------------------------------------------- if [[ $debugval == 1 ]]; then echo "# dirlist_enable=YES download_enable=YES # full path to the directory where 'user1' will have access, change to your needs local_root=/mnt/ftpusers/user1 write_enable=YES" > /etc/vsftpd/vsftpd_user_conf/user1 mkdir -p /mnt/ftpusers/user1 chmod 700 /mnt/ftpusers/user1 chown -R vsftpd:users /mnt/ftpusers #chown vsftpd:users /mnt/ftpusers/user1 echo "" LOCAL_IP_VALUE=`ifconfig eth0|awk '/inet addr/ {split ($2,A,":"); print A[2]}'` echo "-------------------------------------" echo "FTP Address: " $LOCAL_IP_VALUE echo "Username: user1" echo "Password: secret" echo "-------------------------------------" fi # Source(s) # http://www.unix.com/shell-programming-scripting/152714-mysql-bash.html # http://stackoverflow.com/questions/5285485/bash-user-input-mysql-login # http://nixcraft.com/shell-scripting/13225-comment-out-lines-htaccess-using-sed-command.html # http://www.linuxquestions.org/questions/linux-newbie-8/sed-append-text-to-end-of-line-if-line-contains-specific-text-how-can-this-be-done-684650/ # http://beginlinux.com/blog/2008/11/vsftpd-and-selinux-on-centos/ # https://bugzilla.redhat.com/show_bug.cgi?id=592805 # http://gordonazmo.wordpress.com/2011/05/11/selinux-vsftpd-and-you/ # https://www.centos.org/forums/viewtopic.php?t=5012