Enforcing mailquotas for virtual domains/users
Introduction
What is this tutorial all about
The document focuses on enforcing quotas using maildrop. There is no garantee that this will work for you.
I use Debian unstable on our server, and I am using Debian packages where possible.
The root directory for virtual users is /var/vmail. The mailbox for me (user@domain.tld) looks like:
/var/vmail/domain.tld/user and this setup is used in the rest of the this document. Please change it to match your own setup.
Goals
- Enforcing optional quotas for virtual users.
- Allowing users to see their current usage.
- Warn users if the quota is almost reached.
- Integeration with Chris' pages about Postfix
What will you need?
- A working development environment to compile C++ applicaties
- Existing MySQL based virtual user setup based on Postfix.
- Root access to the system.
- Courier-IMAP or
Courier-POP3
with a working Courier-Authlib
- Quota field in the usertable, it needs to be varchar(20).
- Squirrelmail (optional)
- PostfixAdmin (optional)
Maildrop is part of the Courier distribution and you can get the latest maildrop
there.
I use /usr/src as a base for all programs.
Compiling maildrop
cd /usr/src
# get the latest maildrop from
# http://prdownloads.sourceforge.net/courier/maildrop-2.0.2.tar.bz2
wget
http://heanet.dl.sourceforge.net/sourceforge/courier/maildrop-2.0.2.tar.bz2
tar jxf maildrop-2.0.2.tar.bz2
cd maildrop-2.0.2
./configure --enable-syslog=1 --enable-maildirquota
make -s
cd maildrop
strip maildrop
cp maildrop /usr/bin
chmod a+rx /usr/bin/maildrop
Check if we have a sane maildrop,'maildrop –v' should say something like:
maildrop 2.0.2 Copyright 1998-2005 Double Precision, Inc.
GDBM extensions enabled.
Courier Authentication Library extension enabled.
Enabled Berkeley DB instead of GDBM extensions.
This program is distributed under the terms of the GNU General
Public
License. See COPYING for additional information.
vim /etc/maildroprc
logfile "/var/vmail/maildrop.log"
to "${HOME}"
chmod a+r /etc/maildroprc
Configuring Postfix
vim /etc/postfix/main.cf
virtual_transport = maildrop
maildrop_destination_recipient_limit = 1
vim /etc/postfix/master.cf
maildrop unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/bin/maildrop -w 90 -d ${recipient}
RESTART POSTFIX
Adjustments for scripts
I do not want to patch maildrop so I wrote a script to create maildirs on the fly because maildrop is not capable of doing this. I give users a warning at 90% of the quota.
Edit /etc/sudoers using visudo so it looks like this, change 'malochia'
to the hostname of your server:
root@malochia:/etc# cat /etc/sudoers
www-data malochia = NOPASSWD: /usr/sbin/maildirmake.sh
www-data is the username under which Apache operates, it's defined in httpd.conf file
root@malochia:/etc# cat /usr/sbin/maildirmake.sh
#!/bin/bash
set -e
cd "/var/vmail/$1"
maildirmake $2
chown -R 1008:104 /var/vmail/$1/$2
chmod -R g=s /var/vmail/$1/$2
OLD...
For those who use Postfixadmin, add the sudo script to the Postfixadmin
scripts to allow the automatic creation of Maildirs when a new user is
inserted into the database.
root@malochia:/usr/share/postfixadmin# grep -C 1 "sudo" create-mailbox.php
{
system("sudo /usr/sbin/maildirmake.sh $fDomain ".$fUsername);
db_log ($SESSID_USERNAME, $fDomain, "create
mailbox","$fUsername");
admin/create-mailbox.php can be modified the same way
My layout is as follows:
/var/vmail/domain.tld/username
uid 1008 is uid of vmail, the owner of /var/vmail
gid 104 is gid of postfix.
After running the script, a directory is made:
root@malochia:/var/vmail/domain.tld# ls -al
drwx--S--- 30 vmail postfix 4096 Feb 28 17:18 user
This looks ok, but i am not sure if the S bit is really needed.
Next, we want to see if postfix is working together with maildrop.
Try to mail this user and watch the /var/log/mail.log to see if delivery
is succesful. Keep in mind that no quotas are defined yet, this is just
to make sure maildrop is working before we proceed.
Cat /var/log/mail.log | grep “maildrop” –A 2 should show something like:
Feb 28 11:50:41 malochia postfix/qmgr[7345]: 2875B7823E62: from=<remote@user.nl>, size=3308, nrcpt=1 (queue active)
Feb 28 17:18:05 malochia postfix/pipe[11615]: 04DD57822697: to=<user@domain.tld>, relay=maildrop, delay=0, status=sent (domain.tld)
If not, check if the mail isn't kept in the mailqueue due to a faulty configuration:
mailq
vim /usr/local/etc/quotawarnmsg
From: Postmaster domain.tld <postmaster@domain.tld>
Reply-To: postmaster@domain.tld
To: Valued Customer:;
Subject: Mail quota warning
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 7bit
Your mailbox on the server is now more than 90% full. So that you can continue to receive mail you need to remove some messages from your mailbox.
Setting quotas
Ok, we can give the user a quota. Your script (I prefer postfixadmin) needs to store a quota of 20meg as: ‘20000000S' in the database. Mind the ‘S'. It's short for size. You can use ‘C' as well, 1000C means a quota of 1000 messages.
How you change the scripts is beyond the scope of those mini-howto.
We do it manually now, using the mysql client:
root@malochia:/# mysql -p postfix
Enter password:
mysql> update mailbox set quota='5000000S' where username='username@domain.tld';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> quit
Bye
Try to send this user a message, but don't include any attachments with it. Not yet…
How it works
cd /var/vmail/domain.tld/user
cat maildirsize
The maildirsize is the file that stores quota related info and that's being used by courier-imap too. In our case it looks like:
root@malochia:/var/vmail/domain.tld/user# cat maildirsize
5000000S
42898 9
3403 1
1622 1
2371 1
This means that a quota of 5 megabyte is being active. If you delete it, it will be recreated automaticlly by maildrop if the quota field is empty. Don't make it NULL, just put an empty string in it.
There are 4 messages being count.
Assume that this user uses 3 megabyte of his 5 megabyte quotas.
If a mail arrives that's larger than the remaining 2 megabyte, the mail will be bounced.
If a mail is sent to this user with a 1.7 meg PDF file, the mail following actions are executed:
- maildrop delivers the mail because 3 + 1.7 is less than 5.
- Maildrop updates the maildirsize and the user uses now 4.7 meg of his quota.
- Maildrop sees that it should warn the user because he's more than 90% of his mailquota (the 90% is the –w 90 in /etc/postfix/master.cf.
- Maildrop places a copy of /usr/local/etc/quotawarnmsg in the user's mailbox to warn him.
Courier-IMAP configuration
I presume you have a field called 'quota' in your mailbox table. It's commented by default in /etc/courier/authmysqlrc.
Uncomment it and restart courier-authdaemon.
Squirrelmail configuration
I like my users to see what their quota is and how much of it they are using at the moment.
This can be accomplished by the Squirrelmail plugin called 'quota_plugin'. You can get it
here.
cd /usr/src
wget http://www.squirrelmail.org/plugins/quota_usage-1.3.1-1.2.7.tar.gz
tar xfz quota_usage-1.3-1.2.7.tar.gz
cp -R quota_usage /usr/share/squirrelmail/plugins/
vim /usr/sbin/squirrelmail-configure/quota_usage/config.inc.php
/usr/sbin/squirrelmail-configure
enable the plugin
Start up your webbrowser and logon to webmail. The quota usage should be displayed in the top of the left-frame.
Jasper Slits (last change:
2006-11-12, updated to make it useable with authlib. )