Мне приходится много работать с почтовыми серверами на базе postfix с базой почты формата maildir. За несколько лет работы накопилось множество различных приемов по оптимизации работы и настройке. Сегодня решил собрать в кучу все более ли менее универсальные и полезные скрипты по автоматической очистке почтовой базы в postfix.
Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном онлайн-курcе по администрированию MikroTik. Автор курcа – сертифицированный тренер MikroTik Дмитрий Скоромнов. Более 40 лабораторных работ по которым дается обратная связь. В три раза больше информации, чем в MTCNA.
Содержание:
Введение
Данная статья будет актуальна для тех, кто сам выполнил установку и настройку postfix или воспользовался готовой сборкой на базе iredmail. Это что касается материалов моего сайта. А в целом все описанное ниже будет актуально для любого почтового сервера, который хранит почту в формате maildir.
Скажу пару слов, почему именно maildir. Лично я этот формат использую за его удобство. В нем каждое письмо это отдельный файл, который можно посмотреть любым текстовым редактором. Эти файлы удобно бэкапить, анализировать содержимое, сортировать по каким-то признакам. В общем, с ними можно работать как с обычными текстовыми файлами. На основе этих плюсов и выполняется вся дальнейшая работа в статье. Из минусов вижу только один - огромное количество мелких файлов создают большую нагрузку на дисковую подсистему.
Приведу для наглядности пример, который позволит оценить нагрузку на диски. Для синхронизации с помощью rsync почтовой базы объемом примерно 1 терабайт, расположенной на raid10 обычных 3.5 sata дисков, на одиночный такой же диск для бэкапа, уходит где-то пару часов в основном на сравнение файлов между источником и приемником. Само копирование файлов проходит быстро, но чтобы сравнить изменения за день, приходится выполнять длительную операцию. При этом в целом работа пользователей (~30-40 человек) с этой базой вполне комфортна, каких-то тормозов не наблюдается.
То есть по сути, для такого количества пользователей, сервером может быть обычный десктопный компьютер с 2-4 обычными sata дисками. Хватит производительности любого процессора и примерно 2-4 гигабайта оперативной памяти. Отдельный вопрос, конечно, к надежности обычного системника. Я сервера на них не рекомендую собирать, но при большом желании можно.
Перейдем теперь к конкретным примерам.
Простое удаление старых писем из ящика
Начнем с самого простого примера. Допустим, у вас есть какой-то ящик, хранить письма в котором старше определенного срока не имеет смысла. К примеру, это может быть ящик для оповещений системы мониторинга. После того, как оповещение было прочитано, оно теряет актуальность. Все события и так фиксируются и хранятся на самом сервере, поэтому хранить долго письма нет никакого смысла. Очистим этот ящик, удалив из него все письма, старше 30 дней.
/usr/bin/find /data/mail/virtual/zabbix@mailsrv.ru/Maildir/*/ -type f -mtime +30 -exec rm {} \;
/usr/bin/find | Путь до утилиты find. Проверьте его актуальность в своем дистрибутиве. |
/data/mail/virtual/reports@eme.ru/Maildir/*/ | Путь до конкретного ящика. Конструкция /*/ позволяет сразу проверить обе папки new и cur. |
-type f | Говорим find, что ищем только файлы. |
-mtime +30 | Указываем срок более 30 дней с последнего изменения файла. То есть все файлы старше 30-ти дней. |
-exec rm {} \; | Выполняем удаление. |
В данном случае мы просто используем стандартный синтаксис утилиты для поиска файлов find. Подробности ее использования можно найти в интернете, примеров масса. Во время отладки я рекомендую не использовать удаление, а просто направить вывод в файл, чтобы можно было оценить, что утилита нашла и собирается удалить. В простых примерах, как этот, может показаться, что нет смысла проверять, но в более сложных конструкциях рекомендую всегда это делать, например, вот так.
/usr/bin/find /data/mail/virtual/zabbix@mailsrv.ru/Maildir/*/ -type f -mtime +30 >> /root/dellist.txt
После этого смотрите файл /root/dellist.txt и проверяйте, что собираетесь удалить. После того, как проверили, не обязательно заново выполнять поиск по базе и лишний раз нагружать диски. Можно удалить все указанные в dellist.txt письма следующим скриптом.
#!/bin/bash cat /root/dellist.txt | while read i ; do rm -f "$i" done
Сам процесс поиска по почтовой базе postfix не такой длительный, как поиск и удаление. На сильно нагруженных базах я рекомендую выполнять удаление, когда сервер нагружен меньше всего, а поиск в любое время. Конечно, искать тоже лучше в нерабочее время, но мне не нравится работать ночью, поэтому все, что можно, я делаю днем, а на ночь оставляю по возможности минимум работы.
Массовая очистка корзин в почтовой базе postfix
Рассмотрим более сложный пример. Нам нужно автоматически очистить все корзины пользователей от писем, старше 30-ти дней. Я рекомендую всегда настраивать такую очистку. Дело в том, что если сервер сильно нагружен, то он не всегда корректно удаляет содержимое корзины. Например, пользователь отправил в корзину очень много писем (десятки тысяч), нажал "очистить корзину" и закрыл почтовый imap клиент. Есть вероятность, что реально письма не удалятся, а так и будут висеть в корзине. Imap сервер dovecot не удаляет мгновенно письма, а ставит их в очередь и потихоньку удаляет. Иногда этот процесс прерывается и удаление не происходит. Можно попытаться это сделать снова и рано или поздно они таки удалятся.
Есть пользователи, которые сами не чистят корзины, за годы работы у них накапливается там солидное количество бесполезных писем, которые только занимают место на сервере и замедляют работу тех же бэкапов или скриптов очистки. Надо помочь расстаться с этой почтой раз и навсегда.
Сложность с очисткой корзин в том, что названий папок для удаленной почты может быть много. Каждый почтовый клиент создает какую-то свою папку, имя которой может не совпадать с уже существующими. Сейчас могут использоваться одновременно 3 вида почтовых клиентов: web, десктопная или мобильная программа. Каждая из них создает свой набор папок. Ко всему прочему, русские имена imap папок хранятся в кодировке UTF-7, что осложняет работу скриптов. Необходимо экранировать спецсимволы и пробелы.
Вот мой список возможных названий папок для удаленной почты.
Удаленные | .&BCMENAQwBDsENQQ9BD0ESwQ1- |
Удаленные элементы | .&BCMENAQwBDsENQQ9BD0ESwQ1- &BE0EOwQ1BDwENQQ9BEIESw- |
Корзина | .&BBoEPgRABDcEOAQ9BDA- |
Deleted Messages | .Deleted Messages |
Deleted Items | .Deleted Items |
Trash | .Trash |
Я обычно выполняю поиск по такому набору папок. Если у вас есть дополнение этого списка, прошу поделиться. А вот скрипт для автоматической очистки корзин с указанными именами папок.
#!/bin/bash # текущая дата в формате Год-месяц-день data=`date +"%Y-%m-%d"` # формируем список почтовых ящиков для поиска mailbox=`ls -l /data/mail/virtual | grep vmail | awk '{print $9}'` for box1 in $mailbox do /usr/bin/find /data/mail/virtual/$box1/Maildir/'.&BCMENAQwBDsENQQ9BD0ESwQ1-'/*/ -type f -mtime +30 | while read a ; do ls "$a" >> /root/mailclean/trashclean-log/$data.txt done done for box2 in $mailbox do /usr/bin/find /data/mail/virtual/$box2/Maildir/'.Deleted Messages'/*/ -type f -mtime +30 | while read b ; do ls "$b" >> /root/mailclean/trashclean-log/$data.txt done done for box3 in $mailbox do /usr/bin/find /data/mail/virtual/$box3/Maildir/.Trash/*/ -type f -mtime +30 | while read c ; do ls "$c" >> /root/mailclean/trashclean-log/$data.txt done done for box4 in $mailbox do /usr/bin/find /data/mail/virtual/$box4/Maildir/'.&BCMENAQwBDsENQQ9BD0ESwQ1- &BE0EOwQ1BDwENQQ9BEIESw-'/*/ -type f -mtime +30 | while read d ; do ls "$d" >> /root/mailclean/trashclean-log/$data.txt done done for box5 in $mailbox do /usr/bin/find /data/mail/virtual/$box5/Maildir/'.&BBoEPgRABDcEOAQ9BDA-'/*/ -type f -mtime +30 | while read e ; do ls "$e" >> /root/mailclean/trashclean-log/$data.txt done done for box6 in $mailbox do /usr/bin/find /data/mail/virtual/$box6/Maildir/'.Deleted Items'/*/ -type f -mtime +30 | while read f ; do ls "$f" >> /root/mailclean/trashclean-log/$data.txt done done cat /root/mailclean/trashclean-log/$data.txt | while read i ; do rm -f "$i" done
Конечно, тут для компактности можно было сделать еще один вложенный цикл и перебирать имена папок. Я не стал этого делать для наглядности. К тому же список небольшой, можно оставить так. Некоторые комментарии к скрипту.
Конструкция
mailbox=`ls -l /data/mail/virtual | grep vmail | awk '{print $9}'`
формирует список ящиков для очистки. В данном случае берутся все существующие ящики. vmail тут владелец директорий с ящиками. Получить список актуальных ящиков можно разными способами. Я сделал это вот так. Вы можете вручную составить список ящиков в текстовом файле в формате один ящик в каждой новой строке и работать по своему списку. Примерно вот так:
mailbox=/root/mailclean/mailboxlist.txt
Возможно путь к файлу нужно взять в кавычки, сейчас точно не помню, надо проверять. Я логирую списки удаленных писем на всякий случай, чтобы можно было из архива быстро восстановить удаленные письма, если вдруг это будет необходимо. Во время отладки я рекомендую закомментировать последний этап работы скрипта, где выполняется удаление. Для начала просто сформируйте списки файлов на удаление и убедитесь, что там не попало ничего лишнего, что поиск по папкам прошел корректно.
Аналогичным образом можно очистить папки со спамом. Вот мой список для таких папок.
Нежелательная почта | .&BB0ENQQ2BDUEOwQwBEIENQQ7BEwEPQQwBE8- &BD8EPgRHBEIEMA- |
Spam | .Spam |
Junk E-mail | .Junk E-mail |
Junk | .Junk |
Более подробно вопрос автоматического удаления спама рассмотрим отдельно.
Удаление писем на основе содержимого письма
Перейдем к еще более сложному примеру, но в самой простой его модификации. Допустим, вам нужно удалить все письма, адресованные на какой-то адрес. Это может быть актуально в тех случаях, если используется алиас, а с него идет перенаправление на множество ящиков. В итоге, письма, адресованные на этот алиас распространяются по всей почтовой базе в разные ящики. При этом данные письма теряют актуальность со временем, и хранить их нет необходимости.
В данном примере я сделаю еще одно усложнение. Мало того, что мы будем логировать все удаления писем из базы, мы еще будем их сохранять и раскладывать по папкам с названиями ящиков, из которых они были удалены. Дополнительно, удаленные письма будут складываться в директории с именами в виде даты удаления. Таким образом мы полностью застрахуем себя от удаления нужного письма. Даже если это произойдет, то быстро сможем найти это удаленное письмо. Дополнительно будем записывать в лог файл время начала и завершения поиска и удаления. Так как процесс поиска по содержимому достаточно длительный, рекомендую следить за временем его выполнения, чтобы укладываться в окна с малой нагрузкой сервера.
#!/bin/bash # формируем список ящиков для очистки mailbox=`ls -l /data/mail/virtual | grep vmail | awk '{print $9}'` # дата в формате Год-месяц-день_час-минута-секунда data_full=`date +"%Y-%m-%d_%H-%M-%S"` # дата в формате Год-месяц-день data=`date +"%Y-%m-%d"` # директория для хранения копий удаленных писем copydir=/backup/mailclean # адрес лог файла с информацией о времени работы скрипта logfile=/backup/mailclean/log.txt echo "============`date +"%Y-%m-%d"`============" >> $logfile echo "`date +"%H-%M-%S"` Start mail clean" >> $logfile for box in $mailbox do # создаем директории с именами ящиков и текущей даты для копий удаленных писем mkdir -p $copydir/$box/mail/$data # формируем список всех писем в ящике /usr/bin/find /data/mail/virtual/$box/Maildir -type f -name "*mailsrv*" -mtime +30 -daystart | while read a ; do # ищем в содержимом письма адрес получателя zabbix@mailsrv.ru и записываем имена таких писем в индивидуальный файл для каждого ящика grep -E -R -l -I "*for <zabbix@mailsrv.ru>;*" "$a" >> $copydir/$box/copy-$data_full.txt done # пишем название ящика в общий лог файл echo "=========$box=========" >> $copydir/$data_full-all.txt # записываем в общий лог файл все удаленные письма каждого ящика за конкретную дату очистки cat $copydir/$box/copy-$data_full.txt >> $copydir/$data_full-all.txt # формируем список писем ящика на удаление cat $copydir/$box/copy-$data_full.txt | while read i ; do # копируем письмо из реального ящика в папку архива (рекомендую использовать во время отладки) cp -p "$i" $copydir/$box/mail/$data # перемещаем письмо из реального ящика в архив (использовать после отладки) # mv "$i" $copydir/$box/mail/$data done done # записываем время завершения работы скрипта echo "`date +"%H-%M-%S"` End mail clean" >> $logfile echo "==================================" >> $logfile
Поясню основные моменты. В строке с поиском писем по всему ящику есть маска:
/usr/bin/find /data/mail/virtual/$box/Maildir -type f -name "*mailsrv*" -mtime +30 -daystart | while read a ; do
В данном случае mailsrv это часть имени сервера. В формате maildir в именах файлов писем всегда присутствует имя сервера. Эта маска позволяет найти только файлы почты, отбросив остальные служебные файлы, которые могут там быть. А они там точно будут, например, индексы dovecot, правила sieve и др. Не забудьте поменять эту маску на свою в соответствии с именем сервера.
Строка для поиска получателя письма *for <zabbix@mailsrv.ru>;* именно в таком виде взята из служебных заголовков. Даже если письма различными фильтрами будут перемещаться в другие ящики, первоначальный получатель писем все равно будет зафиксирован этой строкой.
Если вам нужно автоматом удалить в почтовом архиве все спам письма, которые ваша антиспам система помечает как спам, то можете взять служебный заголовок, который ставит эта система и использовать его. Например, Касперский антиспам вот так помечает все спамовые письма:
X-KLMS-AntiSpam-Status: spam
Соответственно я ищу все письма с таким служебным заголовком и что-то с ними делаю. Например, перемещаю в папку spam или удаляю. Но тут нужно быть внимательным и делать все аккуратно. Например, если какое-то письмо фильтр по ошибке пометил спамом, у пользователя не будет никакой возможности его сохранить, если вы будете автоматически удалять эти письма. Тут нужно думать в конкретной ситуации как поступить. На текущий момент я не использую подобные правила для удаления или перемещения почты, только для поиска, чтобы оценить объем спамовой почты. Если он слишком велик и его чистка позволит высвободить значительные объемы дискового пространства, то я начинаю что-то делать с ящиками пользователей. Чаще всего напрягать админов на местах, чтобы они стимулировали пользователей к самостоятельной ручной очистке спама. Если же спама не много, то я просто ничего не делаю.
Фильтрация писем на основе темы письма
Рассмотрим более сложный вариант предыдущего скрипта. Там мы фильтровали письма на основе содержимого служебных заголовков. Но если мы захотим отфильтровать почту по теме письма, то сходу у нас ничего не получится. С темой письма возникают сложности из-за того, что она закодирована в base64, если в ней используются русский язык. Вот простой пример. У нас есть письмо с темой "Как дела?". Используем base64 декодер и смотрим, как будет выглядеть тема сообщения в исходнике письма.
Как дела? - 0JrQsNC6INC00LXQu9CwPw==
А вот, что вы увидите в заголовке письма со всеми служебными добавлениями:
Subject: =?UTF-8?B?0JrQsNC6INC00LXQu9CwPw==?=
Вам нужно будет отбросить сначала кодировку =?UTF-8?, потом не знаю, что означающие символы B?, затем в конце еще вот это ?=. Так вы получаете искомую фразу. Теперь представьте, что кто-то ответит на это письмо. Тема сообщения станет Re: Как дела?. В base64 эта фраза будет выглядеть совершенно по-иному:
Re: Как дела? UmU6INCa0LDQuiDQtNC10LvQsD8=
И вот как в реальном заголовке:
Subject: =?UTF-8?B?UmU6INCa0LDQuiDQtNC10LvQsD8=?=
Сложность добавляет еще то, что разные почтовые клиенты используют разную кодировку в теме письма. Мне встречались как UTF-8, так и WIN-1251. То есть для того, чтобы нормально раскодировать и читать тему сообщения, вам нужно сделать обработку на декодирование, на отбрасывание служебных символов. Еще в процессе тестирования я заметил, что если вы используете не весь текст темы, а только ее часть, то закодированная строка поиска может немного не совпадать с той, что будет в теме письма. Изменения могут возникнуть из-за заглавных/строчных букв, пробелов, запятых и т.д. В общем, я не осилил эту тему, так как надо очень плотно погрузиться в предмет и написать много различных проверок и условий. У меня просто не хватило терпения все сделать красиво, чтобы скрипт работал надежно.
Поступил я в итоге по-другому, более просто и топорно, зато надежно. Допустим, вам нужно, чтобы какая-то переписка не хранилась на сервере дольше определенного времени. Это может быть конфиденциальная информация. Например, вы сканируете документы с отправкой на почту и вам нужно, чтобы сканы там не хранились бесконечно долго. Настраиваете на МФУ шаблон темы сообщения, добавляя в начало такую строку - !del. Затем переводите его в base64, добавляя еще фразы с Re: и Fwd: на случай, если эти письма могут куда-то пересылаться или писаться ответы. Конечно, сканеру вряд ли кто-то будет отвечать, но, возможно, для вашей темы сообщения это будет актуально.
!del | IWRlbA== |
Re: !del | UmU6ICFkZWw= |
Fwd: !del | RndkOiAhZGVs |
Дальше берете скрипт из предыдущего примера и меняете там строку поиска на новую:
grep -E -R -l -I "Subject:.*IWRlb.*|Subject:.*RndkOiAhZGVs.*|Subject:.*UmU6ICFkZWw.*" "$a" >> $copydir/$box/copy-$data_full.txt
Эта строка найдет во всех письмах, сформированных в список предыдущей командой, темы сообщения !del, Re: !del, Fwd: !del и скопирует пути и имена файлов в список. Потом вы можете на свое усмотрение работать с этим списком.
Еще несколько примеров работы с почтовой базой
Этот пример будет актуален, если вы используете почтовые ящики, куда копируется абсолютно вся переписка вашего сервера. Допустим, у вас есть ящик out@mailsrv.ru, куда сохраняется вся уходящая корреспонденция. Если на сервере идет активная переписка, то писем в ящике будет много и искать с помощью какого-то imap клиента будет неудобно, так как он может либо тормозить на большом списке писем, либо вообще отваливаться по таймауту и поиск или сортировка будут невозможны с его помощью. Тогда на помощь придут простые скрипты в консоли сервера. Найдем в этом ящике все письма, отправленные в период между первым и седьмым сентября 2017 года и скопируем их в отдельный ящик.
find /data/mail/virtual/out@mailsrv.ru/Maildir/*/ -newerBt '2017-09-01 00:00' -and -not -newerBt '2017-09-07 00:00' -and -type f | cpio -pdmv /data/mail/virtual/user@mailsrv.ru/Maildir/new
По сути тут просто использовались ключи к команде find. У нее их так много, что я для всех прикладных задач всегда храню готовые конструкции, чтобы заново не вспоминать все ключи и возможности.
Еще полезно бывает посмотреть размер почтовых ящиков. Некоторые пользователи имеют в разы больший объем ящика, чем все остальные. Есть любители хранить в почте презентации, пересылать разбитые на части архивы и т.д. Иногда приходится вручную проверять размеры ящиков, чтобы отдать команду на очистку заполненных сверх меры. Сделать это можно простой командой в директории с ящиками:
# du --max-depth=1 | sort -n -r
Команда выведет размеры всех ящиков и отсортирует их по мере увеличения объема, но при этом объем покажет в байтах, что не очень удобно. Можно вывести директории по алфавиту, но с размером в привычных мегабайтах или гигабайтах, но уже без сортировки.
# du -h --max-depth=1
Еще удобнее отправить сразу вывод в текстовый файл с датой в имени файла, чтобы потом было удобно сравнить с тем, что получилось после чистки почтовой базы.
# du -h --max-depth=1 >> "dirsize_`date +"%Y-%m-%d_%H:%M"`.txt"
Тут можно придумать много всяких способов отсортировать данные для более удобного восприятия, или потом автоматически сравнить размеры ящиков. Я не занимался этим.
Заключение
Поделился тем, что использовал последнее время в работе с почтовыми серверами. По большому счету - ничего особенного. Почтовые сервера на postfix + dovecot чаще всего не требуют частого присмотра. Работают надежно, не требуют к себе повышенного внимания. Достаточно настроить мониторинг postfix и следить за свободным местом, периодически очищая почтовую базу, которая представляет из себя набор обычных файлов.
Так же рекомендую обязательно бэкапить почтовую базу тем или иным способом (можно простым rsync по директории с ящиками) и настроить мониторинг размера бэкапа, чтобы беглым взглядом можно было оценить динамику изменения размера почтовой базы. При желании, можно настроить триггер, реагирующий на те или иные значения базы.
Если у вас есть свои наработки, примеры или замечания к тому, что делаю я, прошу поделиться информацией в комментариях. Если есть вопросы по настройке почтового сервера, создавайте тему на форуме.
Научиться настраивать MikroTik с нуля или систематизировать уже имеющиеся знания можно на углубленном онлайн-курcе по администрированию MikroTik. Автор курcа – сертифицированный тренер MikroTik Дмитрий Скоромнов. Более 40 лабораторных работ по которым дается обратная связь. В три раза больше информации, чем в MTCNA.
Доброго времени суток.
Столкнулся еще с одной "проблемой".
Критерий "-mtime +30" фильтрует письма (файлы), которые были модифицированы последний раз более 30 дней назад.
Если я правильно понял, перемещения файла (письма) из одного каталога ("cur") пользователем в другой (".Trash"), является ни чем иным, как создание НОВОГО файла в каталоге ".Trash". Что в свою очередь должен присваивать файлу (письму) признак модификации, и, "отсчет" модифицированности файла (письма) для критерия "-mtime" начинается "с нуля". Но это при условии, что индекс файла (письма) будет изменен. Насколько я понимаю, при данной операции, индекс не меняется. Вот тут и возникает "проблема".
Пример: Пользователь во "Входящих" имеет некоторый список писем. Он может месяцами их "пролистывать" не открывая, зная, что находится в каждом из них. Через 50 дней пользователю надоедает пролистывать эти письма, и, он перемещает их в "Корзину" не открывая. Еще через пару дней, пользователь все-таки решает, что одно из перемещенных в корзину писем ему нужно, НО... его уже там не будет. Скрипт, который очищает "Корзину" каждый день с критерием удалять письма старше 30 дней его уже удалил в первый же день, т.к. по критерию "-mtime" будет вести отсчет от времени получения письма.
Провел множественные тесты - результат совпадает с вышеописанным.
Вопрос: Как сделать так, чтобы удалялись письма, которые ПОПАЛИ В "Корзину" 30 и более дней назад?
Или может я что-то напутал ..., тогда буду БЛАГОДАРЕН за правильное направление.
СПАСИБО!
P.S. Критерии "-atime" тоже не подходит, пользователь может переместить в корзину письмо не открывая.
"-cmin" - также не подходит... Других критериев я не знаю...
Еще раз СПАСИБО!
А других критериев и нет. Для более интеллектуального удаления нужно постоянно сканировать список писем и вести по ним базу данных в каком-то виде. Простых вариантов тут нет. Либо найти какой-то почтовый клиент, где реализована подходящая логика удаления писем.
СПАСИБО в очередной раз за отклик.
Только начал поиски решения. Пока есть вот такой вариант:
Использовать работу с метаданными.
При перемещении в "Корзину" изменяется "File Inode Change Date/Time". С помощью утилиты "exiftool", в цикле, также перебираем все файлы в "Корзине", но, только не используем -mdate. Используем условие, по которому параметр "File Inode Change Date/Time" меньше (т.е. старше) на 30 дней текущей даты. Отобранные файлы попадают в список на удаление и удаляются.
Думаю вариант рабочий, но, скорее всего, нагруженный (медленный). Надо тестировать на больших количествах файлов. У меня максимум будет 40-60 пользователей, один филиал, которые ночью не работают. Возможно мне данный вариант подойдет... Если нет, будем думать.
Как-то так ...
C "exiftool" я конечно погорячился )))
Вот, что у меня получилось в итоге:
#!/bin/bash
# текущая дата в формате Год-месяц-день
data=`date +"%Y-%m-%d"`
# формируем список почтовых ящиков для поиска
mailbox=`ls -l /mnt/mail/nb-test.ru | grep vmail | awk '{print $9}'`
# Обходим все найденные почтовые ящики
for box in $mailbox
do
# Обходим все возможные названия "Корзин"
for trash in '.&BCMENAQwBDsENQQ9BD0ESwQ1-' '.Deleted Messages' .Trash '.&BCMENAQwBDsENQQ9BD0ESwQ1- &BE0EOwQ1BDwENQQ9BEIESw-' '.&BBoEPgRABDcEOAQ9BDA-' '.Deleted Items'
do
# Если каталог с такой корзиной существует, ищем файлы старше 30 дней - помещаем их в отчет удаления, и, производим само удаление
if [ -e /mnt/mail/nb-test.ru/"$box"/"$trash"/ ]
then
/usr/bin/find /mnt/mail/nb-test.ru/"$box"/"$trash"/*/ -type f | while read a ; do
inodetime="$(date -d "$(stat -c "%z" "$a")" +%s)"
realtime="$(date +%F)"
daysdelete=30
testtime="$(date --date="${realtime} -${daysdelete} day" +%s)"
if [ $testtime -gt $inodetime ]
then
ls "$a" >> /home/ruser/post/log/trash-clean-log/$data.txt
rm -f "$a"
fi
done
fi
done
done
Еще раз доброго времени суток.
Возник еще один вопрос ...
В выборку (-type f) на удаление попадают такие файлы, как "dovecot.index.cache", "dovecot.index.log", "dovecot-uidlist", "maildirfolder" и т.д. Их можно удалять? Если нет, как сделать выборку без них?
Спасибо.
Насчёт maildirfolder не помню, что это такое, а всё, что касается dovecot, не только можно, но и нужно удалять, так как это его индексы. После чистки их в любом случае надо обновлять. Он это сделает при работе пользователя с ящиком. Нужно, кстати, иметь ввиду, что перестроение индексов - трудоёмкий процесс, который нагружает сервер. Лишний раз без надобности удалять письма не надо таким способом.
Еще раз СПАСИБО!
Доброго времени суток.
Очередной раз СПАСИБО за статьи.
Настроил почтовый сервер по Вашей статье "Настройка postfix + dovecot + postfixadmin + roundcube + dkim на Debian". Все отлично работает. Дошел до момента очистки папок ... В каждом из почтовых ящиков у меня есть директории "new", "cur", "shared" + отдельные "служебные" файлы. Всё, больше директорий нет Не могу найти, где все остальные папки ("Корзина", "Спам" и т.д.). При этом письма в "Корзину" попадают, в "Спам" попадают, вообщем все работает штатно. Переместив письмо из входящих в корзину - из "cur" письмо пропадает, но куда? Буду благодарен, если дадите направление для решения данной, так сказать, "проблемы". Спасибо
Скорее всего эти директории создал локально почтовый клиент. В них же он и помещает письма. Вообще, это нетипичное поведение клиента. Так сделать можно, но по умолчанию обычно всё же на сервере всё это хранится. Так что надо смотреть настройки почтового клиента. Там обычно можно настроить сопоставление локальных папок с серверными, чтобы письма хранились и на сервере тоже.
Спасибо за Ваше участие.
Недостаточное знание Linux, пока, подводит. Все есть, только, это скрытые директории (.например ".Trash") ))))
Еще раз СПАСИБО
Добрый день. Спасибо боьшое за ваши статьи. Настраивал почтарь по вашей стетье для debian, только на убунте. Проблема следующая: если удалить ящик в postfixadmin - ящик удалется из sql, но почтовый католог остается. Его необходимо удалять руками. Пробовал подправит в скрипте postfixadmin_postdeletion.sh пути к mailbase - не помогло. Возможно не хватает прав. Насколько я понимаю postfixadmin не создает почтовые папки, этим занимается dovecot. Не подскажете как можно выйти из ситуации?
Я никогда не прорабатывал этот вопрос. В моём представлении почту лучше оставлять физически на диске, даже когда ящик удалён. Она может пригодиться. Я так всегда и поступал. Если точно надо удалить письма после удаления ящика, делал это вручную.
решил добавив две строчки в /etc/sudoers
Defaults:www-data !requiretty
www-data ALL=(vmail) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh
в conf.local.php выставил путь к /usr/local/bin/postfixadmin-mailbox-postdeletion.sh ну и скопировал туда этот скрипт.
chmod x /usr/local/bin/postfixadmin-mailbox-postdeletion.sh
В скрипте можно раскоментить удаление, но поумолчанию он перемещает нужные папки ящика в папку trashmailfolders.
Я счастлив. так как через два года пользования почтой, пойди сыщи актуальные... а пилить скрипты с перебором папок и проверкой в sql наличия учетки не хочу
Спасибо за информацию. Надо будет добавить в статью. Мне самому не нужно было, даже не было мыслей писать об этом.
Спасибо за статью! Настроили отчистку ящиков по ней. Но столкнулись с проблемой: У сотрудников пользующихся почтовыми клиентами(Outlook? Thunderbird...) всё ок, письма пропадают, Но при входе в этот же ящик через Roundcube, все письма что должны быть удалены, там отображаются и доступны к прочтению. Подскажите как чистить базу Roundcube аналогично с письмами в postfix?
Roundcube это обычный почтовый клиент. Если письма удалить из ящика, они никак не могут остаться в roundcube. Своей базы писем у него нет.
у меня почтовая база на 1к пользователей, письма хранятся за 2-4 месяца, есть ли готовый инструмент для поиска в базе по названию/содержанию??(нужно оперативно находить нежелательную почту) проблема в том что если я ищу по всей базе то на поиск уходит много часов, как можно ускорить этот процесс? Если есть готовый скрипт буду признателен!
Столкнулся "наконец" с тем что забился почтовый сервак. Подскажите как сделать архив писем по какую-то дату, то бишь оставить например последние 2 года, и удалить их из почты. Для каждого ящика есть свой срок необходимой активной почты (у кого-то год, у кого-то 3) поэтому планирую это делать в ручную, ибо надо сроки с каждым сотрудником согласовывать. Хотелось бы чтоб все письма были именно в архиве (zip, rar, gz и т.п.)
Если у вас формат ящика maildir, то письма это обычные файлы на диске. Можете командой, например find, искать по дате эти файлы и переносить. Я обычно так и делаю.
а можно сделать как-то лог от кого и когда было письмо. что бы потом проще было искать?
Этот лог и так ведется средствами postfix и dovecot.
Снова вернулся к данному вопросу. Я знаю что лог. Но от предыдущих спецов досталось наследство с глубиной лога в 2 месяца, более глубокого нет. Почта же у нас не очищалась с 2011 года, тобишь 7 лет. Сейчас из-за распоряжения директора увеличить объем почтовых отправлений с 15 мб до 100 мб, никак не смог оспорить - директору пофиг на все, быстро забили почтовик. Теперь передо мной стоит вопрос как без лога 7-ми летней давности выдрать весь список писем, что бы можно было понять что подкидывать при восстановлении переписки. Можете что-то порекомендовать?
Provisioned 128 GB
Uncommitted 90.98 GB
Not-shared 167.28 GB
Used 167.28 GB
Помогите разобраться. Это виртуалка в vmware. Как я понимаю выдано 128 GB а занято 167 GB. Если с памятью все нормально как понять почему почта не приходит, главное уходит сообщения моментально
Спасибо за Ваши статьи, очень помогают в работе! С нетерпением жду статью о реализации резервного копирования в почтовом сервере. Работаю в городской больнице и возникла задача реализовать свой почтовый сервер. на сервере места маловато и место для писем хочу подключить с внешнего носителя. Как предпочтительнее реализовать это? Средствами NFS или iSCSI? Машина стоит на гипервизоре и бэкап с ней решён, а вот отдельно резервировать носитель... Одним словом думаю о бэкапе.
Можно монтировать диск по nfs по использовать для почтового архива. Я так делаю иногда. А бэкап можно делать как угодно. У postfix письма это обычные файлы. Их можно перемещать, копировать, сжимать как угодно и чем угодно. У меня есть статья с примерами, как я работаю с почтовой базой https://serveradmin.ru/ochistka-i-obsluzhivanie-pochtovoy-bazyi-postfix/
спасибо
У меня существует проблема с сообщениями на почту о блокировках средствами fail2ban. При перезагрузке системы сервис пытается мне отправить сообщения о всех блокированных ip и так как их много в логах появляется ошибка. Очистить очередь удается командой " postsuper -d ALL " . Скажите как можно сделать чтобы при перезагрузке системы происходила очистка всей очереди?
Очищать всю очередь после перезагрузки это неправильно, хотя сделать нетрудно. Достаточно активировать работу скрипта /etc/rc.local и добавить туда команду на очистку очереди. Но я бы так делать не стал. Надо разобраться с настройками fail2ban и сделать все аккуратно, что бы не было спама.
-exec rm {} \; необязателен, у команды find есть ключик -delete.
man find :-)
С этим ключиком удаляет дольше, чем через -exec rm {} \; На больших количествах файлов это становится очень заметно. Но спорить на тему не буду, так как могу ошибаться. Я в какой-то момент стал использовать эту конструкцию, но если надо что-то по быстрому удалить, использую -delete. С find я хорошо знаком, постоянно его использую.
Понял, спасибо за статью.