ProFTPD Quotas

A busy FTP server handles hundreds to thousands of files belonging to hundreds
to thousands of users. There is not an infinite capacity on the disks of
the server, however, and eventually those files will take up too much space.
Thus many sites have a pressing need to set limits on just how much can
be stored on the server by their users.

Most Unix systems have support for OS- or fileystem-level quotas. These
have the advantage of being transparent to applications like
proftpd, which means that the applications need not worry
about maintaining and enforcing quotas. The kernel/filesystem will handle
that. One disadvantage these OS-level quotas have, though, is that they
are strictly tied to OS and/or filesystem, and not all Unix kernels and
filesystems are the same. They also rely on each user having their own
separate user ID. In the case of
virtual users for proftpd, it is
possible for many users to have the same user ID, which causes problems for
these traditional Unix quotas.

For these reasons, the mod_quotatab module was developed for ProFTPD. This module, being part of the
application, applies to all the Unix kernels and filesystems which support
ProFTPD, and easily handles virtual users. The mod_quotatab
documentation covers how to configure proftpd for quotas.

Note: This howto is a work-in-progress. Please contact me with
suggestions, questions, requests, etc for what you would like to see
covered here. Thanks!

Example Configuration
Here is an example mod_quotatab configuration for supporting
quotas via file tables and SQL tables. This is an example only.

Question: How do I set the disk space limit for a user?Answer: The short answer is to use the "upload bytes limit" setting.

It's true that the various limits maintained by mod_quotatab,
for either bytes or files (or both), are confusing. When designing
the module, I anticipated administrators wanting to limit download as well
as upload transfers; in reality, most administrators wish to limit the
disk space for their users. The bytes uploaded limit doubles as the
disk space limit, for there is no effective difference between them; any
bytes uploaded via FTP are automatically stored on disk.

Question: mod_quotatab only tracks changes
made using proftpd, and my users can add/remove files other ways.
What am I supposed to do?Answer: As the mod_quotatab documentation
states, the module was designed only to track changes done via FTP; it
made implementation of quotas simpler.

This question is also often posed as "Why can't mod_quotatab just calculate
the amount of space used by a user?" The module could do this,
but there are some considerations with this kind of approach.

The primary consideration is the time cost of having to recurse a directory.
If the directory is relatively small, the time needed is small. For very
large/deep directories, however, the time needed to do the scan could be
long, possibly long enough for users to notice and complain. Another
complication is the disk space used by a given user is not confined to
their home directory. Many sites have home directories for users, and
have a shared directory that all users can use. Somehow
mod_quotatab would need to know to scan these shared directories.

As of proftpd-1.3.1rc1, the mod_quotatab supports
this feature via the ScanOnLogin parameter of the
QuotaOptions directive.

Question: If I use this ScanOnLogin option, how do I tell it to ignore certain files?
Answer: Use the new
QuotaExcludeFilter directive. For example, if you wanted to exclude all files
that ended in ".log" from the automatic quota calculation, you might use:

<IfModule mod_quotatab.c>
...
# Automatically calculate the used quota on login
QuotaOptions ScanOnLogin
# Do not include files ending in ".log" in the automatically
# calculated quota
QuotaExludeFilter \.log$
</IfModule>

Question: If mod_quotatab does not
automatically scan for disk space usage, how will it know about my existing
users?Answer: By default, mod_quotatab
indeed knows nothing about what disk space is already occupied by your
users; the tally table starts out blank.

which will display the number of bytes owned by a given user (or group) within
a list of directories. The parameters needed for running
diskuse.pl are documented
here.

Once you've run diskuse.pl to find out the current usage for
your users, you can enter those numbers into your tally table. Unfortunately
diskuse.pl cannot read your proftpd.conf file
to know whether you are using a file- or SQL-based tally table, so it cannot
automatically update your tally table.

Question: How can I set a default quota for all of my users?Answer: Unfortunately, there is no way currently
to do this. The mod_quotatab module was designed such that
the administrator would have to explicitly create limits for every user.

However, a mod_quotatab_default module could be written to
provide default quotas. I simply do not know if this would be desirable
enough to users for writing the module.

Question: What is a "tally table"?Answer: Tally tables, and limit tables, are
covered in the mod_quotatabdocumentation.

Question: How do I construct the limit and tally files for file-based quotas?Answer: There is a Perl script called ftpquota which
can create the necessary files. This script can also be found under the
contrib/ directory of the proftpd source
distribution.

Question: Is there a SQL script for the SQL quota tables used by mod_quotatab_sql?Answer: No. However, the mod_quotatab_sqldocumentation contains example schema for the necessary tables.

Question: How do I set a limit on the size of a
directory?Answer: Currently, you cannot.

Traditional Unix quotas are implemented in terms of ownership: the
thing that counts is not where a file is located on the filesystem, but
which user and/or group owns the file. Asking about directory quotas
assumes a different basis for quotas, based on location rather than
ownership (such quotas are often called tree-based quotas). The
mod_quotatab module followed the example of traditional Unix
quotas, but I have started designing how location-based quotas might be
implemented.

One possibility is that the per session flag in the limit in
effect is set to true, which means that the limits will only
be applied to this session. When this happens, mod_quotatab
will not update the tally table.

Another possibility is that your configured limits are "unlimited" (i.e.
zero). As it states in the mod_quotatab documentation:

For any quota limit that is set as "unlimited", mod_quotatab will not keep the tally.
Many site administrators might want this ability, for accounting purposes. However,
that ability is outside of the intended design of this module; other logging modules
are much better suited for accounting purposes (e.g. mod_sql's SQLLog directive).

If the above cases are not applicable, then consider looking in the
QuotaLog file for more information.

Question: Can I use mod_quotatab to set
monthly quotas?Answer: Sort of. mod_quotatab itself
has no concept of time, so this sort of capability is not built-in. However,
it can be approximated by having some other process, such as a cron job,
periodically (such as once a month) clear the tally table, yielding the
effect of monthly quotas.

Question: How can users see their current quota?Answer: There are two ways to show the current quota
to users. There is the SITE QUOTA command. And there are
certain Display variables that are supported by the
mod_quotatab module.

Question: What if I want to set limits on the size of
individual files being transferred?Answer: For this, you do not need the
mod_quotatab module. ProFTPD has the
MaxRetrieveFileSize and
MaxStoreFileSize directives.

Question: Why do I see the following error?

QuotaLimitTable: unsupported table source type: 'sql'

Answer: The mod_quotatab module acts
as a general quota managing front-end; it relies on other backend modules
to handle the specifics of storage formats. Every backend module
(e.g.mod_quotatab_file, mod_quotatab_sql, mod_quotatab_ldap) registers a supported table type with the main
mod_quotatab module. The error above indicates that the
mod_quotatab_sql module has not been compiled/loaded into
proftpd.

Question: How do group quotas work? If a user is in multiple groups, what happens?Answer: The mod_quotatab module
searches for applicable
quotas, by type, in the following order:

user quotas

group quotas

class quotas

the "all" quota

Thus if there is a user-specific quota, it will be used; the search stops there.
The mod_quotatab module does not combine multiple different
quotas.

What happens, then, if a user belongs to multiple different groups, and there
are different quotas set for those different groups? First, the primary
group of the user is checked; this is the group that is included, for example,
in the entry for the user in the /etc/passwd file. If no quota
for the primary group is found, the module then checks against each of
the user's supplemental groups. The order in which these groups
are checked is dependent up on the order in which the groups are returned
from the auth module providing them, e.g.mod_sql,
mod_ldap, or perhaps mod_auth_unix.

Question: Does mod_quotatab handle the case where a client might append to/overwrite an existing file, in terms of tracking bytes?Answer: Yes. The mod_quotatab module
checks the size of the file before the upload/append starts, and then checks
the size of the file again after the upload/append completes. The difference
in file sizes is used for tracking the byte-related tallies.