В очереди, увы, может накапливаться всякая дрянь... Кто-то неправильное мыло в веб-форме указал, где-то спамеры с несуществующего адреса что-то прислали. От этого нужно избавляться, желательно по крону. Нижеприведенный скрипт предназначен для чистки очереди Exim'а на cPanel серверах, но cPanel здесь необязательна. Настоятельно рекомендую все пути к бинарникам прописать абсолютными -- для верности. Пользователь от которого запускается скрипт должен быть доверенным для Exim'а (в общем случае, просто добавте его в группу mail).
Кроме того, объясню шаманскую строчку. По непонятным для меня причинам (кто объяснит?!) экзим иногда теряет тела писем после доставки. В следствие чего, в выводе списка писем (exim -bp) объем тела не указан. exiqgrep такое не понимает и падает с подобной ошибкой:
Line mismatch: 4h 1Kg6sa-0454TM-Tu <sender@domain.com>
Поэтому и была написана "шаманская строчка", которая таких "призраков" изгоняет.
Рекомендую очень хорошо понять, что делает скрипт перед тем как пихать его в крон. Почта удаляется из очереди навсегда.
#!/bin/bash
# Определяем qualify_domain -- он нужен для удаления всякой лажи domain=`exim -bP | grep -i "^qualify_domain" | sed -e s/.*\=\ //g`
# если скрипту передан параметр c, то включается более агрессивный режим if [ "$1" == "c" ]; then
# Удаляем все баунсы старше 10 минут exiqgrep -o 600 -if '^<>$' |xargs exim -Mrm # Удаляем сообщения с адресами начинающимися с подчерка, минуса или вертикальной черты exiqgrep -f '^<\_|^<\-|^<\|' -i | xargs exim -Mrm exiqgrep -r '^\_|^\-|^\|' -i | xargs exim -Mrm #Удаляем сообщения отправленные скриптами на китайские домены старше 10 минут exiqgrep -f "$domain" -r '.cn$' -o 600 -i | xargs exim -Mrm # Удаляем любые сообщения отправленные скриптами, если они не доставлись за 12 часов exiqgrep -f "$domain" -o 43200 -i | xargs exim -Mrm exit fi
# В мягком режиме удаляем только frozen баунсы и письма с невозможными адресами в заголовках exiqgrep -zif '^<>$' |xargs exim -Mrm exiqgrep -f '^<\_|^<\-|^<\|' -i | xargs exim -Mrm exiqgrep -r '^\_|^\-|^\|' -i | xargs exim -Mrm
Одним из главных плюсов Exim'а, без сомнения, являются утилиты, которые поставляются вместе с ним. Они могут значительно упростить рутинные операции, сократить ваши однострочники раз в 5, и дают возможность составлять сложные sh-скрипты для некоторых часто повторяемых действий с очередью и/или логами. exiqgrep – Выборка из очереди.
Без опций будет идентично exim -bp Самая главная опция это -h, которая выводит список всех опций.
-f <regexp> – регэксп совпадения с адресом отправителя -r <regexp> – регэксп совпадения с адресом получателя -s <regexp> – регэксп совпадения с полем размера (именно с полем размера, в том виде как оно указывается при выводе exim -bp) регэкспы не надо заключать в //
-y <seconds> – выводит сообщения "младше" заданного количества секунд -o <seconds> – выводит сообщения "старше" заданного количества секунд -z – только frozen сообщения -x – все кроме frozen -c – Показать только количество совпадений (в зависимости от версии показывает либо просто число, либо фразу типа "15 matches out of 78 messages" -l – Показывает полную информацию, как её выводит exim (включено по умолчанию) -i – Показывает только IDs совпавших сообщений -b – Показывает совпадения в "кратком" формате. Одна строка: ID, From и To -R – Выводит сообщения в обратном порядке
Разумеется, опции можно комбинировать и делать вещи типа: exiqgrep -zif '^<>$' что выводит нам ID замороженных баунсов…
На основе этого можно написать такой вот скрипт
#!/bin/sh
if ! [ `which exim 2>/dev/null` ]; then echo "Sorry, exim binary not found! Exit now." exit fi
if ! [ `which exiqgrep 2>/dev/null` ]; then echo "Sorry, exiqgrep binary not found! Exit now." exit fi
if [ "$1" == "cf" ]; then num_of_frz_mes=`sudo exiqgrep -zif '^<>$|wc -l` sudo exiqgrep -zif '^<>$'|xargs sudo exim -Mrm > /dev/null echo "$num_of_frz_mes frozen bounces deleted" exit fi
if [ "$1" == "c" ]; then num_of_mes=`sudo exiqgrep -if '^<>$'|wc -l` sudo exiqgrep -if '^<>$'|xargs sudo exim -Mrm > /dev/null echo "$num_of_mes bounces deleted" exit fi
num_of_mes=`sudo exiqgrep -if '^<>$'|wc -l` num_of_frz_mes=`sudo exiqgrep -zif '^<>$'|wc -l` echo "$num_of_mes bounces currently in the queue" echo "$num_of_frz_mes frozen bounces currently in the queue"
Запуск без опций показывает количество баунсов в очереди. с – удалить все баунсы (не надо так делать!) cf – удалить все frozen баунсы
А можно ускорить доставку для определённого домена (-v можно убрать, разумеется): exiqgrep -i -r 'domain.com$' | xargs exim -v -M
Иногда, при использовании exiqgrep появляется такое Line mismatch: 236d 1HOnvz-00069X-8w <info@lischer.com> Лечится так exim -bpr | grep "^[0-9][0-9][0-9]d" | awk ‘{print $2}' | xargs exim -Mrm Я не буду рассасывать, что это значит и как такое получается потому, что это "выходит за рамки статьи".
exipick – показывает сообщения из очереди по разным критериям и в разных форматах
Создана как замена exiqgrep'у. Лично мне хватает последнего, но если захочется чего-нибудь помощнее читайте exipick --help или perldoc exipick
exiqsumm – Анализ очереди
Сама по себе эта утилита ничего не делает. На вход ей обязательно надо подать очередь exim'а. exim -bp | exiqsumm
Вывод программы по умолчанию состоит из пяти колонок: количество сообщений на домен, их общий объем, время жизни самого старого, самого нового, и собственно домен назначения. В конце вывода есть суммарные значения.
По умолчанию вывод сортируется по доменам в алфавитном порядке. Есть и другие опции -a – сортирует по возрасту самого старого сообщения -c – сортирует по количеству сообщений -b – показывает баунсы отдельно, строчки помечаются (b). Т.е. для тех доменов где есть баунсы будет две строки, одна с b, другая без нее. -f – показывает "замороженные" сообщения -s – показывает и домен с которого отправлено и письмо, и домен получатель. Соответсвенно каждая "пара" считается отдельно.
А вот так можно выявлять спамеров. exim -bp | exiqsumm -c -s | head В выводе появится что-то типа
root@domain.ru [~]# exim -bp | exiqsumm -c -s | head
Разумеется вместо server.ru будет qualify domain (подробнее см. опцию -f коммандной строки), или домен отправителя если шлют через SMTP. Узнаем, что это за негодяй exiqgrep -b -f 'server.ru' -r 'mail.ru' | awk '{print $3}' | sort | uniq -c | sort -n | tail Самый нижний он и есть.
Хотя все это можно сделать проще и за один заход, с помощью exiqgrep exiqgrep -b | awk '{print $3}' | sort | uniq -c | sort -n | tail
Ну и соответственно удалить всю очередь от него exiqgrep -i -f '<spamer@server.ru>' | xargs exim -Mrm
Хорошо бы только сначала посмотреть для пары наугад выбранных сообщений полную информацию. Или можно такое использовать (это уже извращение, разумеется) MID=`exiqgrep -i -f '<spamer@server.ru>'|tail -1`;exim -Mvl $MID; exim -Mvh $MID
Но вернемся к exiqsumm. У этой утилиты есть пара важных нюансов. Во-первых, считает она не сами сообщения а "доставки". И если некоторые сообщения имеют более одного получателя, то доставок будет больше чем сообщений. Во-вторых, домены на которые доставляется письмо в результате альясинга или форвардинга – не включаются (если не использовалась опция "one_time" роутера "redirect" для конвертации из в адреса "верхнего уровня"). Поэтому всегда надо смотреть логи.
exigrep – Выборка из логов
Утилита позволяющая банально "грепать" логи. От обычного грепа отличается тем, что выдет все строки для сообщения, у которого хотя бы в одной строке встречается паттерн. Иногда это удобно, иногда такое количество информации может быть излишним.
Использование exigrep [-I] [-l] [-t ] [-v] []… -I – включает регистрозависимость -l – отключает обработку регулярных выражений в паттерне (все символы начинают обрабатываться "как есть") -t<n> – в качестве n нужно указывать количество секунд. Выводятся только сообщения, которые провели в очереди больше чем n секунд. -v – опция идентична grep'овской. Выводит только строки не содержащие паттерн (вернее, строки относящиеся к сообщениям у которых ни в одной строке нет паттерна).
Логи можно подавать на стандартный ввод или через пробел после всех опций. Логи могут быть в архиве (вообще говоря, все это дело определяется опциями сборки ZCAT_COMMAND и COMPRESS_SUFFIX в файле Local/Makefile).
eximstats – Статистика на базе логов
Утилита парсит логи экзима (или syslog'а) и выводит статистический анализ по всем содержащимся сообщениям. Вывод может быть в трех форматах: txt, html, xls (Excel).
Использование eximstats [Output] [Options] mainlog1 mainlog2
По умолчанию скрипт выведет статистику в STDOUT в формате txt. Например можно сделать так eximstats mainlog1 mainlog2 ... > report.txt но лучше так eximstats -txt=report.txt mainlog1 mainlog2 Вместо txt можно указать html или xls, чтобы вывод был в соответствующем формате.
Уже готовые отчеты можно объединить в один. eximstats -merge -html [Options] report.1.html ... > weekly_rep.html
У программы масса опций, посмотреть их можно так eximstats -help или так perldoc eximstats Если отчеты в html, то можно даже png-графики выводить.
Описывать, что получается в отчете, смысла, думаю, нет. Стоит просто попробовать и посмотреть. Статистика очень мощная, если есть проблемы, они винды сразу.
exim_checkaccess – проверка приема для адреса с IP
Очень простая программа для проверки Relay. Заменяет "exim -bh". Используем так: exim_checkaccess <IP address> <email address> [exim options] IP – IP отправителя email address – адрес который будет указываться в RCPT TO Обе опции обязательные (к сожалению, я не нашел как проверить "с любого IP"). После опций можно добавить любые опции экзима. Т.к. утилита использует <> в качестве отправителя удобно использовать её так: exim_checkaccess 10.9.8.7 A.User@a.domain.example -f himself@there.example
Это не все утилиты, которые идут с exim'ом. Описал только те, которые считаю наиболее полезными. Остальные утилиты просто перечислю:
eximon – показывает в X'ах информацию о состоянии очереди exim'a, и о том, что exim делает
Есть сторонние утилиты, типа exilog – обеспечивает визуализацию логов от многих серверов exim'a. Lire – аналог eximstats, но на самом деле это более глобальная программа которая анализирует логи многих программ и выводит статистику.
Командная строка Exim'а использует стандартный для Unix-систем способ задания опций. Каждая начинается с дефиса, после каждой может следовать несколько аргументов. Опции совместимы с основными опциями Sendmail и частично Smail. Количество опций Exim'а просто огромно. В данной статье перечислены и описаны только прикладные, полезные для администрирования уже настроенной и работающей почтовой системы среднего по масштабам почтового сервера. Для некоторых опций приведены примеры эффективного использования. exim -d – отладка. Крайне полезная опция. Специально начал с нее, потому что её можно комбинировать с любыми другими. Например exim -bd -d запускает exim как демон, выводя на консоль всю отладочную информацию. Чтобы уменьшить количество выдаваемой информации, можно использовать -dd (имеет смысл только с -bd) пропускает информацию по подпроцессам. Или -v, простое описание того, что делает exim (при использовании -d включена по умолчанию). На самом деле, эта опция гораздо сложнее чем кажется (вообще одна из самых сложных у Exim'а), можно включать и выключать целую кучу информации по категориям, но об этом уже в документации (см. Ссылки ниже).
exim -bP – выводит все значения установленные в конфиге. У этой команды тоже есть куча параметров, но дефолтное использование + grep достаточно в 90% случаев.
exim -bp – запрашивает список содержимого почтовой очереди на стандартный вывод. Вывод сортируется в хронологическом порядке по прибытию сообщений. Если опция сопровождается списком идентификаторов сообщений, то показываются только эти сообщения. Это одна из важнейших опций exim'а, вернее это даже не одна опция, а целый класс. Рассмотрим их подробнее.
Первая строка содержит 4 колонки: сколько сообщение находится в очереди, размер сообщения, ID сообщения, отправитель, как он указан в "конверте" (для баунсов "<>"). Если сообщение заморожено (приостановлена попытка его доставки), в конце этой строки показывается текст "*** frozen ***". Получатели сообщения (взятые из конверта, не из заголовков) показаны в последующих строках. Адреса по которым сообщение уже доставлено отмечены символом "D". Если оригинальный адрес раскрывается в несколько адресов через файл альясов или форвардов, оригинальный показывается с "D" только когда завершены доставки для всех дочерних адресов.
exim -bpc – выводит общее количество сообщений в очереди.
exim -bpr – идентична -bp, но вывод не сортируется. Полезно, когда в очереди много сообщений, а сортировка совсем не нужна (например для передачи exiqsumm).
exim -bV – кроме того, что выдает версию и некоторую информацию о бинарнике, проверяет exim.conf на ошибки (А скорее, на опечатки. Если эта опция говорит, что все хорошо, то это еще не значит, что ВСЁ хорошо).
У опций вывода очереди есть еще некоторые комбинации предназначенные для отделения и отсеивания форвардинга и алиасинга, но здесь я их рассматривать не буду.
Дальше две очень важные опции, которые должны знать все веб-программисты, но почти никто из них не использует (и, видимо, не знает), а потом удивляются, почему их письма с сайта падают в спам. Опции управляют некоторыми полями "конверта" сообщения составленного локально (в наше время, в 99 случаях из 100, это сообщения составленные скриптами). exim -F <string> – устанавливает имя отправителя. Если опция не указана, подставляется значение поля "gecos" из данных пароля пользователя. exim -f <address> – устанавливает адрес отправителя. Обычно, она может использоваться только доверенными пользователями, но директива "untrusted_set_sender" может разрешить её использование недоверенным пользователям.
Если не понятно, в чем разница между опциями, объясню: приходит письмо от Vasya Pupkin <admin@server.ru>. Vasya Pupkin – это имя отправителя (опция -F) admin@server.ru – адрес (опция -f)
Относительно доверенных/недоверенных пользователей, если кто не в курсе. Пользователю root и пользователю exim'а (это не обязательно пользователь exim) доверяют всегда. Остальных можно задать в конфиге директивами "trusted_users" и "trusted_groups". Если "-f" не определена, или определена пользователем, которому не доверяют, отправитель как логин_пользователя@домен.по.умолчанию (определяется директивой qualify_domain, если не определена используется hostname сервера). Существует исключение из этого ограничения: пустой отправитель может быть задан любым пользователем. Пустой отправитель может быть указан как пустая строка, или как пара угловых скобок без чего-либо между ними: exim -f '<>' user@domain exim -f "" user@domain
При чем же здесь программисты? В отношении php приведу такой пример "правильного" кода (кстати, взято из официальной документации к PHP)
<?php mail('nobody@example.com', 'the subject', 'the message', null, '-fwebmaster@example.com'); ?>
Есть другие способы определять заголовки средствами PHP, но это статья не о PHP.
Дальше вероятно самый важный "класс" опций для администрирования почтового сервера. Опции управления сообщениями.
exim -Mvl <message id> – Посмотреть лог сообщения exim -Mvb <message id> – Посмотреть тело сообщения exim -Mvh <message id> – Посмотреть заголовки сообщения exim -Mrm <message id> ... – Удалить сообщения и не посылать никаких ошибок (в логах упоминание будет). exim -Mg <message id> ... – Удалить сообщение и отослать отлуп (cancelled by administrator). exim -M <message id> ... – Ускорить доставку для сообщения с данным messageID (безусловно немедленно доставляет сообщение) exim -Mar messageID <address> <address> ... – Добавить адрес в список получателей сообщения. exim -Mes <message id> <address> – Изменить адрес отправителя в сообщении на заданный адрес. exim -Mf <message id> <message id> ... – Отметить перечисленные сообщения как "frozen". Любые попытки доставки прекращаются, пока сообщение не будет разморожено вручную, или пока не пройдет время указанное в "auto_thaw". exim -Mt <message id> <message id> ... – "разморозить" сообщение. exim -Mmad <message id> <message id> ... – пометить все адреса получателей в сообщениях как уже доставленные. Никогда (!) не надо так делать. Сами же запутаетесь. exim -Mmd <message id> <address> <address> ... – пометить заданные адреса как уже доставленные. Адреса регистрозависимы. Вот это уже полезнее, если какие-то адреса недоступны.
Если сообщение находится в состоянии "попытки доставки", следующие опции на него не повляют: -Mrm, -Mg, -Mar, -Mes, -Mf, -Mt, -Mmad, -Mmd.
Для сообщений, которые подозреваются в спаме удобно сначала массово, сделать -Mf, потом -Mvl, -Mvh и -Mvb для пары выбранных наугад сообщений. Если все еще невозможно с консоли определить спам ли это (например, проблемы с кодировками или есть вложения), то можно с помощью -Mar добавить себя в список получателей, и ускорить данное сообщение с помощью -M. Когда все наконец станет ясно, то либо -Mrm, либо -Mt.
exim -q – просто запускает один процесс обработчика очереди; очередь сканируется и сообщения доставляются в том, порядке в котором бы доставлялись обычно (вообще, порядок случаен, здесь имеется ввиду, что учитываются все заморозки и т. п.). Для каждого процесса обработчика очереди одно SMTP соединение (это справедливо для всех опций этого класса). После одного прохода по сообщениям процесс завершается (т.о. сообщения, у которых не подошло время доставки даже не попытаются доставиться), если не указана опция Читать далее