Добрый день!
Вот такая вот задачка от руководства:1. Имеем postfix+mysql+dovecot+ спам фильтры и антивирус
В данный момент вся входящая и исходящая переписка через hash карты:main.cf:
recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
sender_bcc_maps = hash:/etc/postfix/sender_bcccat /etc/postfix/recipient_bcc
@мой_домен recipient_aliascat /etc/postfix/sender_bcc
@мой_домен sender_aliasСоответственно в /etc/aliases заданы :
recipient_alias: user@мой_домен, backup_input@мой_домен
sender_alias: user@мой_домен, backup_output@дом_доменТ.е через учетку user@мой_домен проходит вся переписка (нужно для внешний программ), вся входящая почта по всему домену летит в backup_input одной кучей и соответственно вся исходящая - в backup_output, также общей кучей
Задача:
Сделать так чтобы вся вход. переписка в backup_input раскидывалась по созданный папкам (пр. arhiv/input_mail/имя_почтового_ящика) и вся исходящая в backup_output также по папкам (пр. arhiv/output_mail/имя_ящика)
Планируется долгосрочное хранение всей корпоративной переписки, с необходимостью быстро найти нужную переписку по пользователю для руководста.Какие есть идеи?
С postfix работаю меньше года
Заранее благодарен!
1. Добавляем в постфикс след строку
[root@bc ~]# cat /usr/local/etc/postfix/main.cf | grep bcc
always_bcc=backup@domen.ru
Теперь ВСЯ почта будет дублироваться этому пользователю.
2. Создаем этого почтового пользователя.
3. Редактируем крон[root@bc ~]# cat /etc/crontab | grep big
57 */2 * * * root /mnt/big/backup_mail/list_mail_users.pl
59 */2 * * * root /mnt/big/backup_mail/all.sh
0 */2 * * * root /mnt/big/backup_mail/mail_backup.pl –qСкрипты выглядят так.(скриптописатель из меня никакой – буду признателен за любые исправления)
4. Тут мы получаем список наших почтовых пользователей и засовываем его во временный файл.
[root@bc /mnt/big/backup_mail]# cat list_mail_users.pl
#!/usr/bin/perl
unlink ("/mnt/big/backup_mail/111");
#`rm /mnt/big/backup_mail/vusers`;
opendir (TEMPDIR,'/var/spool/mail') || die "Не могу открыть каталог /var/spool/mail: $!";
@FILES=grep(!/^\.\.?/, readdir TEMPDIR);
closedir(TEMPDIR);
foreach (@FILES) {
$_="$_ /var/spool/mail/$_";
`echo "$_" >> /mnt/big/backup_mail/111`;
}
5. Тут мы всего лишь меняем слеш в другую сторону ((( ну не умею я кодить((([root@bc /mnt/big/backup_mail]# cat all.sh
#!/bin/sh
sed 's/\(.*\)@/\1\\@/' 111 > vusers6. Тут немного уличной магии (вот этот скрипт уже не мой. Но все замечания только приветствуются)
[root@bc /mnt/big/backup_mail]# cat mail_backup.pl
#!/usr/bin/perl
#
# vars
use Log::LogLite;$LOG_DIRECTORY = "/mnt/big/backup_mail";
$ERROR_LOG_LEVEL = 6;
$CALLER="mail_backup.pl";
# create new Log::LogLite object
$log = new Log::LogLite($LOG_DIRECTORY."/backup.log", $ERROR_LOG_LEVEL);use File::Copy;
$backup_path="/mnt/big/backup_mail/mail"; #куда копируется ВСЯ почта
$bcm_path="/var/spool/mail/backup\@domen.ru/new"; #откуда, с какого ящика
$config_path="/mnt/big/backup_mail/vusers"; #где находятся все пользователи домена
#$banner="E-mail backup & sorting program by ONYX.\n";#print $banner;
#attempt to read postbackup maildir
opendir(MDIR,"$bcm_path") or die "Cant find postbackup maildir! Check $bcm_path for existense.\n";
@files=readdir(MDIR);
closedir(MDIR);
if (scalar(@files)==2) #abort if no mail to backup
{
$log->write("No mails to backup! Aborted.",$CALLER);
die "No mails to backup! Aborted.\n";
}#finded files
print "The following mails will be stored:\n\n";
for ($j=2;$j <= scalar(@files)-1;$j++)
{
print "$files[$j]\n";
}printf("\nTotal: %d mails.\n",scalar(@files)-2);
#yes_no confirmation
if (!defined($ARGV[0]) or $ARGV[0] ne "-q")
{
print "\nConfirm? [y/n]: ";
$yes_no=<STDIN>;
chop($yes_no);
if ($yes_no ne 'y')
{
die "Not confirmed. Type 'y' to confirm! Aborted.\n";
}
}#reading the config file
open(CONF,"$config_path") or die "Cant read postfix config! Check $config_path for existense.\n";
$e=0;
while (<CONF>)
{
if ($_=~m|(\S+)|)
{
$config[$e]=$1;
$e++;
}
}
close(CONF);#ok, here we go
chdir($bcm_path);
$lc=0;
for ($i=2;$i <= scalar(@files)-1;$i++)
{
@content=0;open(MFILE,"$files[$i]") or die "Cant open $files[$i]! checkit.\n";
while ($line=<MFILE>)
{
$content[$lc]=$line;
if ($line=~m|X-Anti-Virus|i)
{
last;
}
$lc++;
}
close(MFILE);for ($q=0;$q <= scalar(@content)-1;$q++)
{
#chop($content[$q]);
if ($content[$q]=~m|^From:.+<(\S+)>|i)
{
if ($il=is_local(@config,$1)) #if sender is local...
{
$ret=backup_mail($files[$i], $1,"out"); #store the mail in his out dir
print "$ret";
}
}
if ($content[$q]=~m|^\tfor <(\S+)>|)
{
if ($il=is_local(@config,$1)) #if recipient is local
{
$ret=backup_mail($files[$i], $1,"in"); #store the mail in his in dir
print "$ret";
}
}
}
unlink($files[$i]) and print " *******$files[$i] deleted.\n";
}$log->write((scalar(@files)-2)." mails backed up OK.",$CALLER);
exit 1;sub backup_mail()
{
mkdir("$backup_path/$_[1]");
mkdir("$backup_path/$_[1]/out");
mkdir("$backup_path/$_[1]/in");
if ($_[2] eq "out")
{
copy("$_[0]","$backup_path/$_[1]/out/$_[0]") or return "Cant copy to $backup_path/$_[1]/out/$_[0]! Check it.\n";
return "$backup_path/$_[1]/out/$_[0]\t\tOK\n";
}
else
{
copy("$_[0]","$backup_path/$_[1]/in/$_[0]") or return "Cant copy to $backup_path/$_[1]/in/$_[0]! Check it.\n";
return "$backup_path/$_[1]/in/$_[0]\t\tOK\n";
}}
sub is_local()
{
for ($r=0;$r <= scalar(@_)-2;$r++)
{
if ($_[scalar(@_)-1] eq $_[$r])
{
return 1;
}
}
return 0;
}Теперь по адресу /mnt/big/backup_mail/mail у нас есть папки со всеми нашими почтовыми пользователями
[root@bc /mnt/big/backup_mail/mail]# ls
abramova@domen.ru lagutina@domen.ru
lebedev@domen.ru
a.melnikov@domen.ru len@domen.ru
abdullin@domen.ru lepeshkina@domen.ru
lipatova@domen.ru
admin@domen.ru logina@domen.ru
в которых есть папки IN и OUT соответственно отправленные и полученные письма.
Если надо вытаскивать почту дата/ин/оут пр. скриптом тоже могу прислать
>[оверквотинг удален]
> abramova@domen.ru lagutina@domen.ru
> lebedev@domen.ru
> a.melnikov@domen.ru len@domen.ru
> abdullin@domen.ru
> lepeshkina@domen.ru
> lipatova@domen.ru
> admin@domen.ru
> logina@domen.ru
> в которых есть папки IN и OUT соответственно отправленные и полученные письма.
> Если надо вытаскивать почту дата/ин/оут пр. скриптом тоже могу прислатьОо..щас буду пробывать, спасибо!!!
1)
> 4. Тут мы получаем список наших почтовых пользователей и засовываем его во
> временный файлУ меня все пользователи хранятся в базе Mysql, применим ли для данной ситуации данный скрипт?
2) $backup_path="/mnt/big/backup_mail/mail"; #куда копируется ВСЯ почта
> $bcm_path="/var/spool/mail/backup\@domen.ru/new"; #откуда, с какого ящика
> $config_path="/mnt/big/backup_mail/vusers"; #где находятся все пользователи доменаНасчет $config_path я так понимаю тож, нужно как то настроить под взаимодействие с БД Mysql ?
3) Да, почту потом нужно будет вытаскивать, пришлите пожалуйста скрипт.
> Оо..щас буду пробывать, спасибо!!!
> У меня все пользователи хранятся в базе Mysql, применим ли для данной
> ситуации данный скрипт?у меня тоже. но почта-то у меня не в мускуле лежит, а в папках вида /вар/спул/маил/пользов@домен
> Насчет $config_path я так понимаю тож, нужно как то настроить под взаимодействие
> с БД Mysql ?никаких связей с мускулом.
> 3) Да, почту потом нужно будет вытаскивать, пришлите пожалуйста скрипт.
Теперь мы хотим вытащить письма за определенный период от определенного пользователя, но хотим это не ручками, а красиво. К тому же мы можем сразу интересующую почту отправить кому-то еще.
Для этого опять есть скрипт (опять мой – все замечания приветствуются)[root@bc ~]# cat watch.sh
#!/bin/sh
echo "Введите Фамилию пользователя полное имя user@domen.ru"
read NAME
echo "Получено (in), Отправлено (out)?"
read ROUTE
echo "Нужны внутренние письма (domen)(1) или внешние(2)?"
read DESTINATION
echo "Введите начальную дату поиска писем в формате YYYY-mm-dd"
read DATE_START
echo "Ведите конечную дату поиска писем в формате YYYY-mm-dd"
read DATE_END
CURRENT_DATE=`date "+%Y-%m-%d"`
# Считываем фамилию пользователя и входящее это сообщение или исходящее
#а также - внутренне это сообщение, или внешнее
PREF="/mnt/big/backup_mail/mail"
#корень, откуда начинаем идти по почтовым ящикам
TOTAL="$PREF/$NAME/$ROUTE"
#конкретная папка , откуда будем всё копировать
TEM="/mnt/big/temp"
#как можно догадаться из названия - временная папка
yday()
{
perl -e '
use POSIX qw(strftime);
$fmt = "%j"; # %j day of year 1 - 366
$mday = substr("$ARGV[0]", 8, 2);
$mon = substr("$ARGV[0]", 5 ,2);
$year = substr("$ARGV[0]", 0 ,4);
$weekday =
strftime($fmt, 0, 0, 0, $mday , $mon - 1, $year - 1900, -1, -1, -1);
print int $weekday;
' "$1"
}
#это какая-то сложная функция на перл для вычисления по днямvery_old=$( yday $DATE_START )
old=$( yday $DATE_END )
q=$( yday $CURRENT_DATE )
FULL_TIME=$(( $q - $very_old ))
# сколько дней от текущей даты до начала выборки
SMALL_TIME=$(( $q - $old ))
# сколько дней от текущей даты до конца выборки
cd $TOTALWATCH=/var/spool/mail/watch@domen.ru/new/
find . -mtime +$SMALL_TIME -mtime -$FULL_TIME -exec cp -p '{}' $TEM ';'cd $TEM
if [ "$ROUTE" = in ]; then
копируем нужные письма
if [ "$DESTINATION" = 1 ]; then
cp -p $(grep -l "^From: .*domen" *) $WATCH
else
cp -p $(grep -L "^From: .*domen" *) $WATCH
fi
else
if [ "$DESTINATION" = 1 ]; then
cp -p $(grep -l "^To: .*domen" *) $WATCH
else
cp -p $(grep -L "^To: .*domen" *) $WATCH
fi
fi
#копируем в папку пользователя watch@domen.ru нужные письма с учётом введенных дат
rm $TEM/*
# очищаем временную папкуВот как-то так. Если приделаете вэб морду для последнего скрипта – честь вам и хвала!
Спасибо за огромную помощь, буду все прикручивать к нашей системе.Есть вопрос
>$config_path="/mnt/big/backup_mail/vusers"; #где находятся все пользователи доменаЗдесь указан путь до файла, содержащего целевых пользователей
В моем случае все учетки лежат в БД Mysql и связь с ними через парамерт в main.cf:
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cfНа
http://z-up.ru/mediawiki/index.php?title=%D0%A0...
есть инфа что обычно этот файл указывают как значение параметра virtual_mailbox_maps в конфигурации postfix для виртуальных пользователей (или другие файлы *_maps).Но пытаюсь указать параметр вида $config_path="mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf" (может как то подругому нужно указывать его?) то скрипт отрабатывает до ошибки:
=======
The following mails will be stored:.
1327185036.M760397P2388.mail-postfix,S=3067,W=3176
1327185079.M579289P2401.mail-postfix,S=1872,W=1935
1327185028.M241687P2383.mail-postfix,S=3067,W=3176Total: 4 mails.
Confirm? [y/n]:y
Cant unlink source file .!
2. Storing: inbox -> Unsorted -> Done.
=======
И создается только папка Unsorted с подпапками in и out (пустые), письма так и остаются нетронутыми на почте, куда все копируется через парамерт always_bccПодскажите, где ошибка. Как адаптировать скрипт под данную ситуацию, чтобы он узнал полный список учеток домена.
Заранее благодарен!