Virtual Hosting With Proftpd And MySQL (Incl. Quota) On Fedora 11 - Page 2
5 Configure Proftpd
Open /etc/proftpd.conf and comment out the AuthPAMConfig and AuthOrder lines:
vi /etc/proftpd.conf
[...] # Use pam to authenticate (default) and be authoritative #AuthPAMConfig proftpd #AuthOrder mod_auth_pam.c* mod_auth_unix.c [...] |
Further down in same file, add the following lines right below the
# Define the log formats
LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth "%v [%P] %h %t \"%r\" %s"
stanza:
[...] LoadModule mod_sql.c LoadModule mod_sql_mysql.c LoadModule mod_quotatab.c LoadModule mod_quotatab_sql.c SQLBackend mysql # The passwords in MySQL are encrypted using CRYPT SQLAuthTypes Plaintext Crypt SQLAuthenticate users groups # used to connect to the database # databasename@host database_user user_password SQLConnectInfo ftp@localhost proftpd password # Here we tell ProFTPd the names of the database columns in the "usertable" # we want it to interact with. Match the names with those in the db SQLUserInfo ftpuser userid passwd uid gid homedir shell # Here we tell ProFTPd the names of the database columns in the "grouptable" # we want it to interact with. Again the names match with those in the db SQLGroupInfo ftpgroup groupname gid members # set min UID and GID - otherwise these are 999 each SQLMinID 500 # create a user's home directory on demand if it doesn't exist CreateHome on # Update count every time user logs in SQLLog PASS updatecount SQLNamedQuery updatecount UPDATE "count=count+1, accessed=now() WHERE userid='%u'" ftpuser # Update modified everytime user uploads or deletes a file SQLLog STOR,DELE modified SQLNamedQuery modified UPDATE "modified=now() WHERE userid='%u'" ftpuser # User quotas # =========== QuotaEngine on QuotaDirectoryTally on QuotaDisplayUnits Mb QuotaShowQuotas on SQLNamedQuery get-quota-limit SELECT "name, quota_type, per_session, limit_type, bytes_in_avail, bytes_out_avail, bytes_xfer_avail, files_in_avail, files_out_avail, files_xfer_avail FROM ftpquotalimits WHERE name = '%{0}' AND quota_type = '%{1}'" SQLNamedQuery get-quota-tally SELECT "name, quota_type, bytes_in_used, bytes_out_used, bytes_xfer_used, files_in_used, files_out_used, files_xfer_used FROM ftpquotatallies WHERE name = '%{0}' AND quota_type = '%{1}'" SQLNamedQuery update-quota-tally UPDATE "bytes_in_used = bytes_in_used + %{0}, bytes_out_used = bytes_out_used + %{1}, bytes_xfer_used = bytes_xfer_used + %{2}, files_in_used = files_in_used + %{3}, files_out_used = files_out_used + %{4}, files_xfer_used = files_xfer_used + %{5} WHERE name = '%{6}' AND quota_type = '%{7}'" ftpquotatallies SQLNamedQuery insert-quota-tally INSERT "%{0}, %{1}, %{2}, %{3}, %{4}, %{5}, %{6}, %{7}" ftpquotatallies QuotaLimitTable sql:/get-quota-limit QuotaTallyTable sql:/get-quota-tally/update-quota-tally/insert-quota-tally RootLogin off RequireValidShell off [...] |
Make sure that you replace the string password with the real password for the MySQL user proftpd in the line SQLConnectInfo!
Then we create the system startup links for Proftpd and start it:
chkconfig --levels 235 proftpd on
/etc/init.d/proftpd start
6 Populate The Database And Test
To populate the database you can use the MySQL shell:
mysql -u root -p
USE ftp;
First we create an entry in the table ftpgroup. It contains the groupname, the groupid and the username of the ftp group/user we created at the end of step two (replace the groupid appropriately if you use another one than 2001):
INSERT INTO `ftpgroup` (`groupname`, `gid`, `members`) VALUES ('ftpgroup', 2001, 'ftpuser');
Now we are done with the table ftpgroup. We do not have to create further entries here. Whenever you create a new virtual ftp user, you do this in the tables ftpquotalimits and ftpuser. So let us create our first user exampleuser with a quota of 15MB and the password secret (we are still in the MySQL shell):
INSERT INTO `ftpquotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES ('exampleuser', 'user', 'true', 'hard', 15728640, 0, 0, 0, 0, 0);
INSERT INTO `ftpuser` (`id`, `userid`, `passwd`, `uid`, `gid`, `homedir`, `shell`, `count`, `accessed`, `modified`) VALUES (1, 'exampleuser', 'secret', 2001, 2001, '/home/www.example.com', '/sbin/nologin', 0, '', '');
quit;
(Do not forget to replace the group- and userid 2001 appropriately in the last INSERT statement if you are using other values than in this tutorial!)
Now open your FTP client program on your work station (something like WS_FTP or SmartFTP if you are on a Windows system or gFTP on a Linux desktop) and try to connect. As hostname you use server1.example.com (or the IP address of the system), the username is exampleuser, and the password is secret.
If you are able to connect - congratulations! If not, something went wrong.
Now, if you run
ls -l /home/
you should see that the directory /home/www.example.com (exampleuser's home directory) has been automatically created, and it is owned by ftpuser and ftpgroup (the user/group we created at the end of step two):
[root@server1 log]# ls -l /home/
total 4
drwx------ 2 ftpuser ftpgroup 4096 2009-10-13 19:23 www.example.com
[root@server1 log]#
7 Database Administration
For most people it is easier if they have a graphical front-end to MySQL; therefore you can also use phpMyAdmin (in this example under http://server1.example.com/phpmyadmin/) to administrate the ftp database.
Whenever you create a new user, you only have to create entries in the tables ftpquotalimits and ftpuser so I will explain the columns of these tables here:
ftpuser Table:
The important columns are these (the others are handled by MySQL or Proftpd automatically, so do not fill these manually!):
- userid: The name of the virtual Proftpd user (e.g. exampleuser).
- passwd: The unencrypted (i.e., clear-text) password of the user.
- uid: The userid of the ftp user you created at the end of step two (e.g. 2001).
- gid: The groupid of the ftp group you created at the end of step two (e.g. 2001).
- homedir: The home directory of the virtual Proftpd user (e.g. /home/www.example.com). If it does not exist, it will be created when the new user logs in the first time via FTP. The virtual user will be jailed into this home directory, i.e., he cannot access other directories outside his home directory.
- shell: It is ok if you fill in /sbin/nologin here by default.
ftpquotalimits Table:
The important columns are these (the others are handled by MySQL or Proftpd automatically, so do not fill these manually!):
- name: The name of the virtual Proftpd user (e.g. exampleuser).
- quota_type: user or group. Normally, we use user here.
- per_session: true or false. true means the quota limits are valid only for a session. For example, if the user has a quota of 15 MB, and he has uploaded 15 MB during the current session, then he cannot upload anything more. But if he logs out and in again, he again has 15 MB available. false means, that the user has 15 MB, no matter if he logs out and in again.
- limit_type: hard or soft. A hard quota limit is a never-to-exceed limit, while a soft quota can be temporarily exceeded. Normally you use hard here.
- bytes_in_avail: Upload limit in bytes (e.g. 15728640 for 15 MB). 0 means unlimited.
- bytes_out_avail: Download limit in bytes. 0 means unlimited.
- bytes_xfer_avail: Transfer limit in bytes. The sum of uploads and downloads a user is allowed to do. 0 means unlimited.
- files_in_avail: Upload limit in files. 0 means unlimited.
- files_out_avail: Download limit in files. 0 means unlimited.
- files_xfer_avail: Tranfer limit in files. 0 means unlimited.
The ftpquotatallies table is used by Proftpd internally to manage quotas so you do not have to make entries there!
8 References
Mandrake 10.1 - Proftpd + MySQL authentication + Quotas Howto: http://www.khoosys.net/single.htm?ipg=848
9 Links
- Proftpd: http://www.proftpd.org/
- MySQL: http://www.mysql.com/
- phpMyAdmin: http://www.phpmyadmin.net/
- Fedora: http://fedoraproject.org/