Linux especially Ubuntu have many FTP server applications. And PureFTPd is one of the most stable and good FTP server application. We can configure PureFTPd to use virtual user stored on MySQL database rather than using system user.
This is much more performance and allows to have thousands of ftp users on a single machine. In addition to that I will show the use of quota and upload/download bandwidth limits with this setup. Passwords will be stored encrypted as MD5 strings in the database.
Please follow this steps to install PureFTPd, MySQL and PhpMyAdmin:
- Open your terminal and login as root.
su
- Install MySQL, PhpMyAdmin and Apache, if you have this skip this step
apt-get install mysql-server mysql-client phpmyadmin apache2
Please follow the wizard, you will be ask for the MySQL root password and configuration.
- Install PureFTPd
apt-get install pure-ftpd-mysql
- Create ftpgroup and ftpuser
groupadd -g 2001 ftpgroup useradd -u 2001 -s /bin/false -d /bin/null -c "pureftpd user" -g ftpgroup ftpuser
- Login to your mysql with this command:
mysql -u root -p
You will be asked root password
- Create pureftpd database and pureftpd user, run this script
CREATE DATABASE pureftpd; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost' IDENTIFIED BY 'ftpdpass'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON pureftpd.* TO 'pureftpd'@'localhost.localdomain' IDENTIFIED BY 'ftpdpass'; FLUSH PRIVILEGES;
Please change ftpdpass to password you like
- Change your active database to pureftpd:
USE pureftpd;
- Create ftpd table
CREATE TABLE ftpd ( User varchar(16) NOT NULL default '', status enum('0','1') NOT NULL default '0', Password varchar(64) NOT NULL default '', Uid varchar(11) NOT NULL default '-1', Gid varchar(11) NOT NULL default '-1', Dir varchar(128) NOT NULL default '', ULBandwidth smallint(5) NOT NULL default '0', DLBandwidth smallint(5) NOT NULL default '0', comment tinytext NOT NULL, ipaccess varchar(15) NOT NULL default '*', QuotaSize smallint(5) NOT NULL default '0', QuotaFiles int(11) NOT NULL default 0, PRIMARY KEY (User), UNIQUE KEY User (User) ) TYPE=MyISAM;
- Quit from the mysql, by run this command
quit;
- Configure PureFTPd. First create mysql.conf under pureftpd. Run this command:
cp /etc/pure-ftpd/db/mysql.conf /etc/pure-ftpd/db/mysql.conf_orig cat /dev/null > /etc/pure-ftpd/db/mysql.conf vim /etc/pure-ftpd/db/mysql.conf
11. Open /etc/pure-ftpd/db/mysql.conf, It should like this:
MYSQLSocket /var/run/mysqld/mysqld.sock #MYSQLServer localhost #MYSQLPort 3306 MYSQLUser pureftpd MYSQLPassword ftpdpass MYSQLDatabase pureftpd #MYSQLCrypt md5, cleartext, crypt() or password() - md5 is VERY RECOMMENDABLE uppon cleartext MYSQLCrypt md5 MYSQLGetPW SELECT Password FROM ftpd WHERE User="L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MYSQLGetUID SELECT Uid FROM ftpd WHERE User="L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MYSQLGetGID SELECT Gid FROM ftpd WHERE User="L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MYSQLGetDir SELECT Dir FROM ftpd WHERE User="L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MySQLGetBandwidthUL SELECT ULBandwidth FROM ftpd WHERE User="L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MySQLGetBandwidthDL SELECT DLBandwidth FROM ftpd WHERE User="L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MySQLGetQTASZ SELECT QuotaSize FROM ftpd WHERE User="L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R") MySQLGetQTAFS SELECT QuotaFiles FROM ftpd WHERE User="L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "R")
Make sure that you replace the string ftpdpass with the real password for the MySQL user pureftpd in the line MYSQLPassword! Please note that we use md5 as MYSQLCrypt method, which means we will store the users’ passwords as an MD5 string in the database which is far more secure than using plain text passwords!
- Create the file /etc/pure-ftpd/conf/ChrootEveryone which simply contains the string yes:
echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone
- Create the file /etc/pure-ftpd/conf/CreateHomeDir which again simply contains the string yes:
echo "yes" > /etc/pure-ftpd/conf/CreateHomeDir
- Create the file /etc/pure-ftpd/conf/DontResolve which again simply contains the string yes:
echo "yes" > /etc/pure-ftpd/conf/DontResolve
- Restart PureFTPd
/etc/init.d/pure-ftpd-mysql restart
- Open Your PhpMyAdmin by open your browser and type: http://localhost/phpmyadmin
- Select pureftpd database, and add new user to ftpd table. Run this query:
INSERT INTO `ftpd` (`User`, `status`, `Password`, `Uid`, `Gid`, `Dir`, `ULBandwidth`, `DLBandwidth`, `comment`, `ipaccess`, `QuotaSize`, `QuotaFiles`) VALUES ('ivan', '1', MD5('ivan123'), '2001', '2001', '/home/ivan', '100', '100', '', '*', '50', '0');
- Now open your FTP client program on your work station (example FileZilla) and try to connect. As hostname you use localhost (or the IP address of the system), the username is ivan, and the password is ivan123.
- If it is connected, Congratulation! Please check all the steps again if you have something wrong.
You can add, edit or delete user by go to the PhpMyAdmin, or make a simple web application to do user management for your FTP server.
Read more about PureFTPd.
sorry to sound stupid, but can you explain the last query in phpadmin? i am unclear on bandwidth and quota size and quota file
thanks
Hi,
That query is for add a virtual user into ftp server.
QuotaFiles is the maximal number of files a user can store in his home directory
QuotaSize is the maximal file size (in MB) of one file a user can store in his home directory
Thank you very much. Got another issue. I cannot create folders on the ftp account I create following your guide. Any Idea where I messed up?
Please check the permission of the home folder for the ftp account.
I prefer to create my own user management system for large projects and corporate applications. It’s vital that it is flexible as well as secure in those cases.
Well.. your are in the wrong place then.. I guess this is cain of beginners tutorial… Not many experts like your Eminence around here..
Anyway good tuto Ivan.
Note that the standard table name is users, not ftpd like in this example. Otherwise a nice guide. Thanks!
YES, IT WORKED !!! Thanks for this guide !!!
Great to hear that
thanks om…. artikel yang mantap….
thanks bro… 🙂
Yeah it really worked… Thanks man… 😉
Has anyone a webinterface to manage this users??
What do you mean..?
Use any script for registering your users (point your script to save data into ftp tables).. after that, use any web-based system configuration tool (like webmin) to access and manage your Mysql Data Base's..
Otherwise, dont really know what exatcly do you need..
I can't install succefully as this topic said.
Please follow the steps carefully mate.
I'm having a problem when I get to step 4. When I try to create a group I get the response "groupadd: cannot lock /etc/grroup; try again later"
What can I do to fix this?
are you using Ubuntu and have root access?
yes and yes
Is not recommended, but you tried to edit your / etc / group manually?
following Ivan's tutorial, is supposed to appear at the end of the list something like ftpgroup: x: 2001:
Great tutorial!!
Maybe a nice adition: you use md5 hash to save the password. To make a md5 hash via commandprompt:
echo -n plainpassword | md5sum
Another thing: to test your ftp (firewall settings) from outside, you can use a web ftp like net2ftp.com or webftp.co.uk
Thank for the tips. Using md5 to store password indeed improve the security.
Hi Ivan,
Nice guide. When I get to step 16 I can not access phpmyadmin. See here http://50.56.71.179/phpmyadmin
It is installed. What am I doing wrong!
Have you tried http://localhost/phpmyadmin
Thanks guys! I found it!
phpmyadmin directive should be set in apache httpd.conf
Hallo,
Step 16 gives me trouble. Got into the phpmyadmin before I restarted my box (did the query). Now I get the error: Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly. Where do I begin searching to correct this? I'm running Ubuntu 10.04 LTS. PS. Before I restarted I got the error when trying to log in via filezilla: ECONNREFUSED -connection refused by server.
please get the error_log to pastebin and paste the link here.
Hi Ivan, guys and girls ;), is me again ..
My doubt is not about this tutorial … which works perfect .. Thanks
The problem is this: I have a registration form call register.php, which enters and validated the data into ftpd table .. right through a registration form named exec.php… In the register.php form, I do have "active" fields (by "active" i meant to be filled by user) for: Name, Lastame, User, QuotaSize, Password… etc, and hiden values (field values) for STATUS, Uid, Gid, Dir ( I set this value="/home/"), ULBandwidth, DLBandwidth, comment, QuotaFiles, etc… OK Now: i have all that mess just to Sanitize all values through exec.php, everything works perfect… but in (exec.php) i want to make the registered-user "Dir" look like (/home/User) .. (where "User" is the login name).. I know soungs a silly question.. i have tried
INSERT INTO ftpd (Name, Lastname, User, Dir, etc, etc, etc…) VALUES('$Name', '$Lastname', '$User', '.$_POST['Dir'].' / '.$_POST['User'].', etc, etc, etc…)
And just cant… that exatcly part where I wanna make Dir entry by ( /"Dir Value goes here"/"User Value goes here"/ )… Any idea?.. Thanks
try create the dir outside the query, it is probably that single quote mess your query:
$userdir = $_POST['Dir'].'/'.$_POST['user'];
INSERT INTO ftpd (Name, Lastname, User, Dir, etc, etc, etc…) VALUES('$Name', '$Lastname', '$User', '$userdir', etc, etc, etc…)
thanks Iva… will be back with results.. 😉
Hey guess what?… it works.. thanks a lot… here is what i did:
Fist i fixed value on register.php for Dir:
name="Dir" value="/home" id="Dir"
(take a llok that have just one /.. not to one / ends)
Second: because I have declared a function clean.. like :
function clean($str) {
$str = @trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
So I did include (declared):
$Userdir = clean($_POST['Dir'].'/'.$_POST['User']);
Next (as you you said) I did create the dir outside the query:
$Userdir = $_POST['Dir'].'/'.$_POST['login'];
(Ivan take a look that it was suposse to be 'login'.. not 'User' since User is for MySql table.. but entry value from str is $login)
Last (as you you said):
INSERT INTO ftpd (Name, Lastname, User, Dir, etc, etc, etc…)
VALUES('$Name', '$Lastname', '$User', '$Userdir', etc, etc, etc…)
It works charm… thanks a lot body… I really appreciate your interest, help and clarification in this matter.
Glad to hear that it is working. Good luck 🙂
When over everthing… twice..
I can't login. I can create the user but the users directory doesn't get created
thanx a lot Ivan, very useful article..
@MatusSynJaromira My pleasure.
Please check all permission and you done it step by step. I did this more than once.