ProFTPd - Install with Virtual Users and Web Admin support on CentOS 5.x

ProFTPD is a high-performance, extremely configurable, and secure FTP server, featuring Apache-like configuration and great performance. This post describes how to install a Proftpd server that uses virtual users from a MySQL database instead of real system users. Using virtual users is far more efficient as it allows you to setup and manage literally thousands of ftp users on a single host.

To simplify end-user account creation and management, we will be using a web-based tool called proFTPd Administration. The tool, with some additional programming, also automates the creation of individual directories for each account that is created.


Base server setup for CentOS 5.x with LAMP installed.

Install Software

  1. Remove default vsftpd server and install proftpd with mysql support:
    yum -y remove vsftpd
    yum -y install proftpd proftpd-mysql

  2. Download and install proftpd admin.
    tar -xzvf proftpd_admin_v1.2.tar.gz
    mv proftpd_admin_v1.2 /usr/share/proftpd_admin

Configure ProFTPD

  1. Backup the default proftpd config file and create a new file
    mv /etc/proftpd.conf /etc/proftpd.conf.old
    nano -w /etc/proftpd.conf
  2. Copy the following into the proftpd.conf file:
    # This is the ProFTPD configuration file
    # Load modules for sql support
    LoadModule mod_sql.c
    LoadModule mod_sql_mysql.c
    ServerName                      "Servername"
    ServerType                      standalone
    ServerIdent                     on              "Servers identifying string"
    DeferWelcome                    off
    DefaultServer                   on
    DefaultRoot                     ~ !adm
    AllowOverwrite                  on
    UseReverseDNS                   off
    IdentLookups                    off
    Port                            21
    Umask                           022
    MaxInstances                    15
    MaxClientsPerHost               3               "Only %m connections per host allowed"
    MaxClients                      10              "Only %m total simultanious logins allowed"
    MaxHostsPerUser                 1
    User                            ftp
    Group                           ftp
    ScoreboardFile                  /var/run/proftpd.score
    # Some logging formats
    LogFormat                       default         "%h %l %u %t \"%r\" %s %b"
    LogFormat                       auth            "%v [%P] %h %t \"%r\" %s"
    LogFormat                       write           "%h %l %u %t \"%r\" %s %b"
    # Define log-files to use
    TransferLog                     /var/log/proftpd/xferlog
    ExtendedLog                     /var/log/proftpd/access_log    WRITE,READ write
    ExtendedLog                     /var/log/proftpd/auth_log      AUTH auth
    ExtendedLog                     /var/log/proftpd/paranoid_log  ALL default
    SQLLogFile                      /var/log/proftpd/mysql
    # Set up authentication via SQL
    # ===========
    AuthOrder                       mod_sql.c
    SQLAuthTypes                    Backend
    SQLConnectInfo                  proftpd_admin@localhost proftpd <database_password>
    SQLUserInfo                     usertable userid passwd uid gid homedir shell 
    SQLGroupInfo                    grouptable groupname gid members 
    SQLUserWhereClause              "disabled=0 and (NOW()<=expiration or expiration=-1 or expiration=0)"
    #SQLHomedirOnDemand  on (depreciated, use following with new systems)
    CreateHome on
    # Log the user logging in
    SQLLog PASS counter
    SQLNamedQuery counter UPDATE "lastlogin=now(), count=count+1 WHERE userid='%u'" usertable
    # logout log
    SQLLog EXIT time_logout
    SQLNamedQuery time_logout UPDATE "lastlogout=now() WHERE userid='%u'" usertable
    # display last login time when PASS command is given
    SQLNamedQuery login_time SELECT "lastlogin from usertable where userid='%u'"
    SQLShowInfo PASS "230" "Last login was: %{login_time}"
    # xfer Log in mysql
    SQLLog RETR,STOR transfer1
    SQLNamedQuery  transfer1 INSERT "'%u', '%f', '%b', '%h', '%a', '%m', '%T', now(), 'c', NULL" xfer_stat
    SQLNamedQuery  transfer2 INSERT "'%u', '%f', '%b', '%h', '%a', '%m', '%T', now(), 'i', NULL" xfer_stat
    AllowStoreRestart               on
    AllowRetrieveRestart            on
    RequireValidShell               off
    #RootLogin off
    # Normally, we want users to do a few things.
      AllowOverwrite yes
      <Limit ALL SITE_CHMOD>
    Change <database_password> to your desired password for the MySQL user "proftpd".

Configure ProFTPD Administrator

  1. Create the apache config file and restart apache. The file has been set to only allow access from the local host. Change the access to meet your needs.
    nano /etc/httpd/conf.d/proftpd_admin.conf
  2. Copy the following into the file:
    alias /ftpadmin /usr/share/proftpd_admin
    <Location /ftpadmin>
        Order deny,allow
        Deny from all
        Allow from
        Allow from ::1
        # Allow from
  3. Restart Apache Service
    service httpd restart
  4. Edit the db_structure.sql file. Go to the end of the file. Replace <database_password> with the password used above in the last three lines.
    nano /usr/share/proftpd_admin/misc/database_structure_mysql/db_structure.sql
  5. Create the database and tables. Type the following.
    mysql -u root -p < /usr/share/proftpd_admin/misc/database_structure_mysql/db_structure.sql
  6. Set the configuration file to read/write
    chmod o+w /usr/share/proftpd_admin/configuration.xml
  7. Create the ftp root folder where we'll place our files (if you want to place it somewhere else you'd need to reconfigure both proFTPd and proFTPd Administrator):
    cd /
    mkdir ftp
    cd ftp
    mkdir incoming
    chmod o+w incoming
  8. Start proftpd service and ensure it starts at boot
    service proftpd start
    chkconfig --levels 235 proftpd on
  9. Bring up the web interface configuration screen:
  10. You will need to configure database access and some other settings.


If proftpd gives an error starting up, it is usually with the config file or connecting to the database. Look under /var/log for information.


proFTPd Administrator

1 comment:

  1. thanks a lot, very usefull tutorial especially for non daily centos user like me :)
    well done sir, pray the best for you :)