[HowTo] Install FTP Server With User Management In Ubuntu

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:

  1. Open your terminal and login as root.
    su
  2. 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.

  3. Install PureFTPd
    apt-get install pure-ftpd-mysql
  4. Create ftpgroup and ftpuser
    groupadd -g 2001 ftpgroup
    useradd -u 2001 -s /bin/false -d /bin/null -c "pureftpd user" -g  ftpgroup ftpuser
  5. Login to your mysql with this command:
    mysql -u root -p

    You will be asked root password

  6. 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

  7. Change your active  database to pureftpd:
    USE pureftpd;
  8. 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;
  9. Quit from the mysql, by run this command
    quit;
  10. 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!

  11. Create the file /etc/pure-ftpd/conf/ChrootEveryone which simply contains the string yes:
    echo "yes" > /etc/pure-ftpd/conf/ChrootEveryone
  12. Create the file /etc/pure-ftpd/conf/CreateHomeDir which again simply contains the string yes:
    echo "yes" > /etc/pure-ftpd/conf/CreateHomeDir
  13. Create the file /etc/pure-ftpd/conf/DontResolve which again simply contains the string yes:
    echo "yes" > /etc/pure-ftpd/conf/DontResolve
  14. Restart PureFTPd
    /etc/init.d/pure-ftpd-mysql restart
  15. Open Your PhpMyAdmin by open your browser and type: http://localhost/phpmyadmin
  16. 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');
  17. 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.
  18. 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.

Comments

  1. Info says:

    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

  2. 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

  3. Info says:

    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?

  4. Please check the permission of the home folder for the ftp account.

  5. 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.

    • Cubausatony says:

      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.

  6. Johan says:

    Note that the standard table name is users, not ftpd like in this example. Otherwise a nice guide. Thanks!

  7. YES, IT WORKED !!! Thanks for this guide !!!

  8. thanks om…. artikel yang mantap….

  9. Ashish says:

    Yeah it really worked… Thanks man… 😉

  10. Martin says:

    Has anyone a webinterface to manage this users??

    • Cubausatony says:

      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..

  11. YeuHost says:

    I can't install succefully as this topic said.

  12. 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?

  13. General Failure says:

    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

  14. Po says:

    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!

  15. Qobcc says:

    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.

  16. Cubausatony says:

    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…)

      • Cubausatony says:

        thanks Iva… will be back with results.. 😉

      • Cubausatony says:

        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.

  17. User4572 says:

    When over everthing… twice..
    I can't login. I can create the user but the users directory doesn't get created

  18. MatusSynJaromira says:

    thanx a lot Ivan, very useful article..

  19. @MatusSynJaromira My pleasure.

  20. Please check all permission and you done it step by step. I did this more than once.

Give me your feedback

This site uses Akismet to reduce spam. Learn how your comment data is processed.