Compare commits
No commits in common. "2186d0af02f31828824d6786045840a56cd51bae" and "f6059e58045f3cbe989cf4abe24f4524890a601c" have entirely different histories.
2186d0af02
...
f6059e5804
3 changed files with 16 additions and 198 deletions
|
|
@ -5,17 +5,12 @@
|
||||||
#
|
#
|
||||||
# License: Creative Commons BY-NC-SA license
|
# 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
|
# Version 0.1 / 2025-12-14
|
||||||
# First release.
|
# First release.
|
||||||
#
|
#
|
||||||
# Version 0.2 / 2025-12-28
|
# Version 0.2 / 2025-12-28
|
||||||
# Enable plugins (managesieve, password) in Roundcube
|
# Enable plugins (managesieve, password) in Roundcube
|
||||||
#
|
#
|
||||||
# Version 0.3 / 2025-12-30
|
|
||||||
# Add quota setup
|
|
||||||
#
|
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
echo "Usage: $0 -f fqdn"
|
echo "Usage: $0 -f fqdn"
|
||||||
|
|
@ -301,9 +296,7 @@ mysql /var/run/mysqld/mysqld.sock {
|
||||||
}
|
}
|
||||||
|
|
||||||
userdb sql {
|
userdb sql {
|
||||||
query = SELECT email as user, \
|
query = SELECT email as user FROM virtual_users WHERE email='%{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
|
iterate_query = SELECT email as user FROM virtual_users
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -892,159 +885,6 @@ EOF
|
||||||
echo "✅ Catch-all aliases ready to use."
|
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 #############
|
||||||
|
|
||||||
going_live() {
|
going_live() {
|
||||||
|
|
@ -1154,9 +994,6 @@ dkim_config
|
||||||
banner "Setting up catch-all aliases"
|
banner "Setting up catch-all aliases"
|
||||||
catchall_config
|
catchall_config
|
||||||
|
|
||||||
banner "Configuring quotas"
|
|
||||||
quota_config
|
|
||||||
|
|
||||||
banner "Final steps – changing dummy passwords"
|
banner "Final steps – changing dummy passwords"
|
||||||
going_live
|
going_live
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,19 +59,13 @@ server.
|
||||||
|
|
||||||
## What this is not about
|
## What this is not about
|
||||||
|
|
||||||
If you just want to have a working mail server and do not care how it works then this guide may not be for you. There is
|
If you just want to have a working mail server and do not care how it works then this guide is not for you. Check out
|
||||||
an [automated installation script](/ispmail-trixie/automated-installation/) that does all the steps of this guide
|
ready solutions like [mailinabox](https://mailinabox.email/) or [iRedMail](http://www.iredmail.org/) or
|
||||||
automatically for you. But that is no replacement for reading this guide and understanding how the server works. It is
|
[Mailcow](https://mailcow.email/). Be aware that running a mail server requires some technical understanding. And that’s
|
||||||
merely meant to help you save time if you want to set up multiple servers.
|
what the ISPmail guide is for. Experience from giving support to other sysadmins shows that most problems appear because
|
||||||
|
some detail in a complex setup goes wrong and they have no idea how to fix it. Email has evolved a lot over the past 40
|
||||||
Be aware that running a mail server requires some technical understanding. And that’s what the ISPmail guide is for.
|
years. Go with ready solutions if you like. But I have a feeling that we meet again. And you will probably not save time
|
||||||
Experience from giving support to other sysadmins shows that most problems appear because some detail in a complex setup
|
either taking the supposedly easy route.
|
||||||
goes wrong and they have no idea how to fix it. Email has evolved a lot over the past 40 years. Go with ready solutions
|
|
||||||
if you like. But I have a feeling that we meet again. And you will probably not save time either taking the supposedly
|
|
||||||
easy route.
|
|
||||||
|
|
||||||
There are also other projects that give you a ready solution like [mailinabox](https://mailinabox.email/),
|
|
||||||
[iRedMail](http://www.iredmail.org/) or [Mailcow](https://mailcow.email/).
|
|
||||||
|
|
||||||
## What's new
|
## What's new
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,6 @@ import { Aside } from "@astrojs/starlight/components";
|
||||||
This feature is completely optional. If you are eager to get finished then skip this page and maybe come back later.
|
This feature is completely optional. If you are eager to get finished then skip this page and maybe come back later.
|
||||||
</Aside>
|
</Aside>
|
||||||
|
|
||||||
<Aside type="danger" title="Potential breakage with virtual_aliases">
|
|
||||||
There is an unsolved issue with `virtual_aliases` if one of the recipients is over quota. I am currently investigating
|
|
||||||
that. See [Julien's
|
|
||||||
comment](https://workaround.org/ispmail-trixie/quotas/#comentario-e1cdd47e-fa21-4213-83c3-1eb4fbd030f5).
|
|
||||||
</Aside>
|
|
||||||
|
|
||||||
Quotas are size limits for users. You can make sure that users do not waste arbitrary amounts of disk space but are
|
Quotas are size limits for users. You can make sure that users do not waste arbitrary amounts of disk space but are
|
||||||
forced to clean up old emails every now and then.
|
forced to clean up old emails every now and then.
|
||||||
|
|
||||||
|
|
@ -52,14 +46,6 @@ quota_storage_grace = 50M
|
||||||
|
|
||||||
# Define two warnings at 80% and 95% of quota usage.
|
# Define two warnings at 80% and 95% of quota usage.
|
||||||
quota "User quota" {
|
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
|
# Set another warning level to 80% for early warnings
|
||||||
warning warn-80 {
|
warning warn-80 {
|
||||||
quota_storage_percentage = 80
|
quota_storage_percentage = 80
|
||||||
|
|
@ -68,12 +54,11 @@ quota "User quota" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# User is no longer over quota
|
# Set one warning level to 95%
|
||||||
warning warn-under {
|
warning warn-95 {
|
||||||
quota_storage_percentage = 100
|
quota_storage_percentage = 95
|
||||||
threshold = under
|
|
||||||
execute quota-warning {
|
execute quota-warning {
|
||||||
args = below %{user}
|
args = 95 %{user}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -163,6 +148,8 @@ chmod u=rwx,g=rx,o= /usr/local/bin/ispmail-quota-warning.sh
|
||||||
chown vmail:vmail /usr/local/bin/ispmail-quota-warning.sh
|
chown vmail:vmail /usr/local/bin/ispmail-quota-warning.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Please change `@domain.com` to your main domain.
|
||||||
|
|
||||||
### Global versus local
|
### Global versus local
|
||||||
|
|
||||||
By default you will probably allow all users to use a certain amount of disk space for their emails. That would be the
|
By default you will probably allow all users to use a certain amount of disk space for their emails. That would be the
|
||||||
|
|
@ -277,8 +264,8 @@ After a few emails you will see the rejection message:
|
||||||
|
|
||||||
These are things you should consider if quotas do not seem to work properly:
|
These are things you should consider if quotas do not seem to work properly:
|
||||||
|
|
||||||
- Check that your `/etc/dovecot/conf.d/99-ispmail-sql.conf` file looks as
|
- Check that your `/etc/dovecot/conf.d/99-ispmail-sql.conf` file looks as [described]
|
||||||
[described](/ispmail-trixie/dovecot#99-ispmail-sqlconf). Earlier version of this Trixie guide did not contain the
|
(/ispmail-trixie/dovecot#99-ispmail-sqlconf). Earlier version of this Trixie guide did not contain the
|
||||||
`quota_storage_size` field in the `userdb sql` query.
|
`quota_storage_size` field in the `userdb sql` query.
|
||||||
- Run `tcpdump -Ai lo port 13373` on the server to see if Postfix talks to the `quota-status` service.
|
- Run `tcpdump -Ai lo port 13373` on the server to see if Postfix talks to the `quota-status` service.
|
||||||
- Your users may complain that they have deleted many emails but are still over quota. Let them check if they actually
|
- Your users may complain that they have deleted many emails but are still over quota. Let them check if they actually
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue