I want to have all mails stored in the external location.
However changing Dovecot’s mail_location in /etc/dovecot/conf.d/10-mail.conf does the job but incoming email always delivered to user’s home directory ~/Maildir by Postfix.
Actually changing manually changing user directory actually works but it required me to change each of them. So might be somewhere to configure in the Postfix but I have no ideas and have been googling for few days.
Things I have done is trying to use LMTP protocol with Sieve to filter and deliver incoming mail to the external location with invidual directory. Unfortunately, I almost got LMTP to works but end up stuck at “User’s doesn’t” exist error.
I not sure does dovecot supports keep all incoming mails in local (~/Maildir) and move read and old mails to alternative storage (/mnt/data/%d/%n). If this possible I might gaining benefits on performance on reading new mail.
Otherwise I’m keen for any possible workaround!
/etc/dovecot/conf.d/10-mail.conf
...
# mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
#mail_location = maildir:~/Maildir
mail_location = /mnt/data/%d/%n
# If you need to set multiple mailbox locations or want to change default
...
Do you have experience with virtualmin as mail directories are done a virtual server basis (different locations). What you trying to do can break virtualmin.
No and today I found an alternative workaround with “Command to run after making changes to an alias” under “System Settings > Virtualmin Configuration > Actions upon server and user creation”.
So I wrote a very simple script without any checking conditions for testing purposes. This script is to change home dir for any new user is created. However, I got stuck on passing the variables during the user creation.
I not sure if this is the permanent solution for me.
The above post with Command to run after making changes to an alias is not working for me. I couldn’t pass the variables when creating user or I do not know how to pass it.
? say It can make use of the environment variables ALIAS_FROM, ALIAS_TO and ALIAS_ACTION to determine what alias is being changed and what is happening to it. I thought it is like if [ $VIRTUALSERVER_ACTION == MODIFY_DOMAIN ] then and I try with if [ ALIAS_ACTION == ADD_UER ] then or something. But it just don’t work and 2 problems here, lack of documentation and it will excute 2 times.
So I’ve created another bash script with more tasks like remove the old directory and so on. Then hardcoded and pass the variables to run the script everytime when I create new users in save-user.cgi under /usr/share/webmin/virtual-server/. I place it after &release_lock_mail($d) because I’ve encountered problem on changing dir with usermod -h -d.
save-user.cgi
...
&release_lock_unix($d);
&release_lock_mail($d);
&webmin_log($in{'new'} ? "create" : "modify", "user",
&remove_userdom($user->{'user'}, $d), $user);
}
# Somewhere around here
if ($in{'new'} && $d) {
system("/home/user/custom.sh", $user->{'mailbox'} , $user->{'email'}, $user->{'home'});
}
...
custom.sh
#!/bin/sh
# Get current date and time
datetime="$(date +'%m %d %Y %H:%M:%S'):"
# Initialize
echo "" >> /var/log/custom-script.log
echo "" >> /var/log/custom-script.log
echo "" >> /var/log/custom-script.log
echo "$datetime Script loaded!" >> /var/log/custom-script.log
# Variables
username="$1" # Username
email="$2" # Email
domain="$(echo $email | cut -d '@' -f 2)" # Domain name
home="$3" # Directory
# Print
echo "$datetime Variables received: $username, $email, $domain!" >> /var/log/custom-script.log
echo "$datetime New user created: $2!" >> /var/log/custom-script.log
# Define the new directory path
new_directory="/mnt/data/$domain/$username"
# Print
echo "$datetime Directory is now set to $new_directory" >> /var/log/custom-script.log
# Change the user's home directory
usermod -m -d $new_directory $email
# Print
echo "$datetime User $username's directory changed to $(cat /etc/passwd | grep $email | cut -d ':' -f 6 )" >> /var/log/custom-script.log
# Move existing data to new directory (If any)
rsync -az --progress --partial "$home/" "$new_directory"
# Print
echo "$datetime Rsynced data to $new_directory" >> /var/log/custom-script.log
echo "$datetime $(ls $new_directory)" >> /var/log/custom-script.log
# Delete old directory
rm -r $home
# Print
echo "$datetime Removed $username's old directory $home" >> /var/log/custom-script.log
echo "$datetime Completed!" >> /var/log/custom-script.log
Correct me if I’m wrong and if there’s a better approach.
I haven’t read everything on this topic, but since you’re using the postfix local delivery agent (rather than the usual Virtualmin default of procmail), have you read the documentation for it? Postfix manual - local(8)
You can set mail_spool_directory to determine where mail ends up, though you’re trying to do very unusual stuff. I dunno if the very basic delivery agent provided by Postfix will do what you want. There are many delivery agents to choose from; Dovecot has one that’s pretty good and flexible, procmail is the one we use in Virtualmin.
I would really love to have the ability to use Cyrus as the delivery agent. It has so many features including a central mail store, built in replication and load balancing, caldav and cardDAV. It doesn’t even need local users, everything can be purely virtual. 20 years ago I was using ispman. It used ldap and Cyrus and was wonderful but the group supporting it ended up folding. Imagine built in address book and calendar support! Crazy right? Oh and also server side filtering with sieve no extra work needed.