**USE THIS TUTORIAL TO INSTALL PURE-FTPD FROM ONLINE PACKAGE** This tutorial will guide you step by step in the replacement of ProFTPD by **Pure-FTPD**. Most importantly, Pure-FTPD will force users to respect their disk quota, moreover, it is filled with loads of interesting options and much more advanced than ProFTPD. This tutorial was successfully tested on a Ubuntu 8.04 LTS Server. Some of the code might need to be adapted for other distributions. ====== Backing up old files ====== Backup all of the files we're going to modify : cp /etc/ispcp/ispcp.conf /etc/ispcp/ispcp.conf.bak cp /var/www/ispcp/engine/quota/ispcp-dsk-quota /var/www/ispcp/engine/quota/ispcp-dsk-quota.bak ====== Removing ProFTPD ====== apt-get remove --purge proftpd Remove any ProFTPD traces : rm -rf /etc/proftpd && rm /etc/proftpd.conf ====== Installing the necessary packages ====== Download the Pure-FTPD package : apt-get install pure-ftpd-mysql pure-ftpd-common Stop PureFTPD before modifying configuration files : /etc/init.d/pure-ftpd-mysql stop ====== Configuring Pure-FTPD ====== Under Ubuntu & Debian, the configuration files are placed in the **etc/pure-ftpd/conf** directory. We need to create the different configuration files that are going to be used : echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone echo "yes" > /etc/pure-ftpd/conf/BrokenClientsCompatibility echo "100" > /etc/pure-ftpd/conf/MaxClientsNumber echo "yes" > /etc/pure-ftpd/conf/Daemonize echo "4" > /etc/pure-ftpd/conf/MaxClientsPerIP echo "yes" > /etc/pure-ftpd/conf/DisplayDotFiles echo "no" > /etc/pure-ftpd/conf/AnonymousOnly echo "yes" > /etc/pure-ftpd/conf/NoAnonymous echo "ftp" > /etc/pure-ftpd/conf/SyslogFacility echo "yes" > /etc/pure-ftpd/conf/DontResolve echo "5" > /etc/pure-ftpd/conf/MaxIdleTime echo "no" > /etc/pure-ftpd/conf/PAMAuthentication echo "no" > /etc/pure-ftpd/conf/UnixAuthentication echo "10000 3" > /etc/pure-ftpd/conf/LimitRecursion echo "no" > /etc/pure-ftpd/conf/AnonymousCanCreateDirs echo "4" > /etc/pure-ftpd/conf/MaxLoad echo "yes" > /etc/pure-ftpd/conf/AntiWarez echo "133 022" > /etc/pure-ftpd/conf/Umask echo "2000" > /etc/pure-ftpd/conf/MinUID echo "yes" > /etc/pure-ftpd/conf/AllowUserFXP echo "no" > /etc/pure-ftpd/conf/AllowAnonymousFXP echo "no" > /etc/pure-ftpd/conf/ProhibitDotFilesWrite echo "no" > /etc/pure-ftpd/conf/ProhibitDotFilesRead echo "no" > /etc/pure-ftpd/conf/AutoRename echo "yes" > /etc/pure-ftpd/conf/AnonymousCantUpload echo "clf:/var/log/pureftpd/transfers.log" > /etc/pure-ftpd/conf/AltLog echo "no" > /etc/pure-ftpd/conf/NoChmod echo "no" > /etc/pure-ftpd/conf/CreateHomeDir echo "95" > /etc/pure-ftpd/conf/MaxDiskUsage echo "yes" > /etc/pure-ftpd/conf/CustomerProof Now, using PhpMyAdmin, create a new user, ISPCP_ftp. Type a strong password, since it will not be encrypted in the following file. Give this new user permissions on the domain and ftp_user tables. In PhpMyAdmin, type : CREATE USER 'ISPCP_ftp'@'localhost' IDENTIFIED BY 'CHOOSE_PASSWORD'; GRANT SELECT ON `ispcp`.`domain` TO 'ISPCP_ftp'@'localhost'; GRANT SELECT ON `ispcp`.`ftp_users` TO 'ISPCP_ftp'@'localhost'; Make sure you replace **CHOOSE_PASSWORD** with the password you want! Now, edit file that will fetch the FTP accounts via MySQL : vim /etc/pure-ftpd/db/mysql.conf Here is a working configuration file : ############################################## # # # Sample Pure-FTPd Mysql configuration file. # # See README.MySQL for explanations. # # # ############################################## # Optional : MySQL server name or IP. Don't define this for unix sockets. # MYSQLServer 127.0.0.1 # Optional : MySQL port. Don't define this if a local unix socket is used. # MYSQLPort 3306 # Optional : define the location of mysql.sock if the server runs on this host. MYSQLSocket /var/run/mysqld/mysqld.sock # Mandatory : user to bind the server as. MYSQLUser ISPCP_ftp # Mandatory : user password. You must have a password. MYSQLPassword SQL_PASSWORD # Mandatory : database to open. MYSQLDatabase ispcp # Mandatory : how passwords are stored # Valid values are : "cleartext", "crypt", "md5" and "password" # ("password" = MySQL password() function) # You can also use "any" to try "crypt", "md5" *and* "password" MYSQLCrypt crypt # In the following directives, parts of the strings are replaced at # run-time before performing queries : # # \L is replaced by the login of the user trying to authenticate. # \I is replaced by the IP address the user connected to. # \P is replaced by the port number the user connected to. # \R is replaced by the IP address the user connected from. # \D is replaced by the remote IP address, as a long decimal number. # # Very complex queries can be performed using these substitution strings, # especially for virtual hosting. # Query to execute in order to fetch the password MYSQLGetPW SELECT passwd FROM ftp_users WHERE userid="\L" # Query to execute in order to fetch the system user name or uid MYSQLGetUID SELECT uid FROM ftp_users WHERE userid="\L" # Optional : default UID - if set this overrides MYSQLGetUID #MYSQLDefaultUID 1000 # Query to execute in order to fetch the system user group or gid MYSQLGetGID SELECT gid FROM ftp_users WHERE userid="\L" # Optional : default GID - if set this overrides MYSQLGetGID #MYSQLDefaultGID 1000 # Query to execute in order to fetch the home directory MYSQLGetDir SELECT homedir FROM ftp_users WHERE userid="\L" # Optional : query to get the maximal number of files # Pure-FTPd must have been compiled with virtual quotas support. # MySQLGetQTAFS SELECT QuotaFiles FROM users WHERE User="\L" # Optional : query to get the maximal disk usage (virtual quotas) # The number should be in Megabytes. # Pure-FTPd must have been compiled with virtual quotas support. MySQLGetQTASZ SELECT domain.domain_disk_limit FROM domain,ftp_users WHERE ftp_users.userid="\L" and ftp_users.uid=domain.domain_uid # Optional : ratios. The server has to be compiled with ratio support. # MySQLGetRatioUL SELECT ULRatio FROM users WHERE User="\L" # MySQLGetRatioDL SELECT DLRatio FROM users WHERE User="\L" # Optional : bandwidth throttling. # The server has to be compiled with throttling support. # Values are in KB/s . # MySQLGetBandwidthUL SELECT ULBandwidth FROM users WHERE User="\L" # MySQLGetBandwidthDL SELECT DLBandwidth FROM users WHERE User="\L" # Enable ~ expansion. NEVER ENABLE THIS BLINDLY UNLESS : # 1) You know what you are doing. # 2) Real and virtual users match. # MySQLForceTildeExpansion 1 # If you upgraded your tables to transactionnal tables (Gemini, # BerkeleyDB, Innobase...), you can enable SQL transactions to # avoid races. Leave this commented if you are using the # traditionnal MyIsam databases or old (< 3.23.x) MySQL versions. # MySQLTransactions On Make sure you replace **SQL_PASSWORD** with the with the password you chose above! ====== Starting Pure-FTPD ====== /etc/init.d/pure-ftpd-mysql start Check your logs for any errors : nano /var/log/syslog From here on, you should be able to connect to the FTP as usual. If not, check your logs, there are probably errors! If you are really sure, that you made no mistakes, but still receive errors like: "[WARNING] Authentication failed for user [user@domain.tld] " without any further details, check out this: http://isp-control.net/ispcp/ticket/1897 Go to /var/www/ispcp/gui/include/calc-functions.php Search for the function "crypt_user_pass_with_salt" and replace the line with $res = crypt($data, generate_rand_salt()); by: $res = crypt($data); If all is ok, we can continue. ====== Editing ispCP Omega files ====== ===== Editing ispcp.conf ===== vim /etc/ispcp/ispcp.conf Find : CMD_DU = /usr/bin/du Add, after : CMD_QUOTACHECK = /usr/sbin/pure-quotacheck ===== Editing ispcp-dsk-quota ===== vim /var/www/ispcp/engine/quota/ispcp-dsk-quota Find : my $sql = "select domain_id, domain_name from domain where domain_status = 'ok';"; Replace by : my $sql = "select domain_id, domain_name, concat('vu',domain_uid) from domain where domain_status = 'ok';"; my $cmd_du = $main::cfg{'CMD_DU'}; my $cmd_quota = $main::cfg{'CMD_QUOTACHECK'}; Find : my $disk_limit = @$_[2]; Replace : my $domain_uid = @$_[2]; my $size = $cmd_du -sb $main::cfg{APACHE_WWW_DIR}/$domain_name; my $quotacheck = $cmd_quota -u $domain_uid -d $main::cfg{APACHE_WWW_DIR}/$domain_name; Restarting Pure-FTPD : /etc/init.d/pure-ftpd restart Restarting ispCP Omega : /etc/init.d/ispcp_daemon restart You're done! FTP should be running fine now ^^ Credits go to : Anonymous ispCP Omega Documentation member, http://forum.nuxwin.com/index.php?topic=1102.0