add quota configuration
All checks were successful
/ build (push) Successful in 34s

This commit is contained in:
Christoph Haas 2025-12-30 19:10:08 +01:00
parent d97875ed38
commit c69571740b

View file

@ -5,12 +5,17 @@
#
# License: Creative Commons BY-NC-SA license
#
# Please report bugs at https://github.com/Signum/ispmail-workaround-org/issues
#
# Version 0.1 / 2025-12-14
# First release.
#
# Version 0.2 / 2025-12-28
# Enable plugins (managesieve, password) in Roundcube
#
# Version 0.3 / 2025-12-30
# Add quota setup
#
usage() {
echo "Usage: $0 -f fqdn"
@ -296,7 +301,9 @@ mysql /var/run/mysqld/mysqld.sock {
}
userdb sql {
query = SELECT email as user FROM virtual_users WHERE email='%{user}'
query = SELECT email as user, \
IF(quota > 0, CONCAT(quota, 'B'), NULL) AS quota_storage_size \
FROM virtual_users WHERE email='%{user}'
iterate_query = SELECT email as user FROM virtual_users
}
@ -885,6 +892,159 @@ EOF
echo "✅ Catch-all aliases ready to use."
}
############ Quota config #############
quota_config() {
cat > /etc/dovecot/conf.d/99-ispmail-quota.conf << 'EOF'
# Enable the quota plugin
mail_plugins {
quota = yes
}
# Set global defaults. Keep this outside of a "quota {}" section so that it
# can be overriden with data from the virtual_users table.
# Allow 5 GB of space per default.
quota_storage_size = 5G
# It is important to allow it so that Postfix can deliver an email to
# bring the user above 100% of quota usage. Otherwise you risk that the user
# is at 99.99% of quota but the last email cannot be delivered and gets stuck
# between Postfix and Dovecot. No email should be larger than this.
quota_storage_grace = 50M
# Define two warnings at 80% and 95% of quota usage.
quota "User quota" {
# Set one warning level to 100%
warning warn-100 {
quota_storage_percentage = 100
execute quota-warning {
args = 100 %{user}
}
}
# Set another warning level to 80% for early warnings
warning warn-80 {
quota_storage_percentage = 80
execute quota-warning {
args = 80 %{user}
}
}
# User is no longer over quota
warning warn-under {
quota_storage_percentage = 100
threshold = under
execute quota-warning {
args = below %{user}
}
}
}
# Define what happens if the user goes over quota. Point to a script that
# creates a warning email to the user. The name "quota-warning" corresponds
# to the "execute" statement in the warning definitions.
service quota-warning {
executable = script /usr/local/bin/ispmail-quota-warning.sh
unix_listener quota-warning {
mode = 0660
user = vmail
group = vmail
}
}
# Add a new service so that Postfix can check if a user is over quota.
# It listens on TCP port 13373.
service quota-status {
executable = quota-status -p postfix
inet_listener quota-status {
listen = 127.0.0.1
port = 13373
}
client_limit = 1
}
# Enable the IMAP QUOTA extension, allowing IMAP clients to ask for the
# current quota usage. Roundcube displays the current space usage in
# the lower left corner.
protocol imap {
mail_plugins {
imap_quota = yes
}
}
EOF
# Apply the configuration
systemctl reload dovecot
cat > /usr/local/bin/ispmail-quota-warning.sh << 'EOF'
#!/bin/bash
#
# This script is part of the ISPmail configuration.
# It is called from /etc/dovecot/conf.d/99-ispmail-quota.conf
# and sends an email to the user if the quota is at 80%, over 100%
# or back below 100%.
#
# Christoph Haas <ispmail@christoph-haas.de>
# Version 1.0 2025-12-30
LEVEL=$1
USER=$2
MAIL="From: postmaster@${USER#*@}"
MAIL+="\nSubject: Quota information"
MAIL+="\nX-Priority: 1"
MAIL+="\n\nThis is an automatic email from your friendly mail server.\n\n"
if [ $LEVEL = "below" ]; then
MAIL+="Thanks for making some space. You will now be able to receive emails again."
elif [ $LEVEL -eq 80 ]; then
MAIL+="Your mailbox is currently using up 80% of the maximum space."
MAIL+="\nPlease consider deleting some emails. If your used space reached"
MAIL+="\n100% then you would not be able to receive further emails. I will"
MAIL+="\nhowever send you another email in that case."
MAIL+="\n"
MAIL+="\nThanks for your attention."
elif [ $LEVEL -eq 100 ]; then
MAIL+="I am afraid to tell you that your mailbox is now 100% full."
MAIL+="\nNew emails to your address will be rejected by the server."
MAIL+="\nPlease delete some emails immediately. I will send you another"
MAIL+="\nemail once you have made some space."
MAIL+="\n"
MAIL+="\nThanks for your attention."
fi
echo -e $MAIL | /usr/lib/dovecot/dovecot-lda -d $USER -o quota_enforce=no
EOF
chmod u=rwx,g=rx,o= /usr/local/bin/ispmail-quota-warning.sh
chown vmail:vmail /usr/local/bin/ispmail-quota-warning.sh
# Apply the configuration
systemctl reload dovecot
# Check if Dovecot tells us quota information
lines=$(doveadm quota get -A | grep -c john@example.org)
if [ $lines -ne 2 ]; then
echo "❌ The quota setup is not working. Check 'doveadm quota get -A'."
exit 1
fi
mariadb mailserver -Bse 'update virtual_users set quota=0 where email="john@example.org";'
quota_storage_check=$(dovecot quota get -u john@example.org | grep STORAGE | awk '{print $5}')
if [ $quota_storage_check -ne 5242880 ]; then
echo "❌ The quota storage value for John should be 5 GB. But it's not."
exit 1
fi
mariadb mailserver -Bse 'update virtual_users set quota=1024000 where email="john@example.org";'
quota_storage_check=$(dovecot quota get -u john@example.org | grep STORAGE | awk '{print $5}')
if [ $quota_storage_check -ne 1000 ]; then
echo "❌ The overriden quota storage value for John should be 1000 KB. But it's not."
exit 1
fi
echo "✅ Quotas are ready to use."
}
############ Going-live #############
going_live() {
@ -994,6 +1154,9 @@ dkim_config
banner "Setting up catch-all aliases"
catchall_config
banner "Configuring quotas"
quota_config
banner "Final steps changing dummy passwords"
going_live