Используем fetchmail для автоматизации разбора почты.

Потребовалось мне принимать емейлы фильтровать их по определённым критериям и обрабатывать скриптами (отделять вложения, выполнять действия над вложениями). С такой задачей мог бы справиться плагин FiltaQuilla для Thunderbird. Однако плагин некорректно работает с моим Thunderbird версии 30 для Linux. Если он выполняется автоматически то сохраняет пустое вложение, хотя при ручном выполнении всё делает корректно. Автор упорно молчит, а править чужой плагин у меня небыло времени.

Итак мне было нужно:

  • периодически проверять наличие писем в специальном почтовом ящике;
  • стягивать их в раздельные файлы;
  • сохранять все вложения из каждого письма;
  • анализировать заголовки и тексты писем;
  • запускать скрипты по манипуляции с текстами писем и вложениями.

Автомат обработки почты с fetchmail я намеренно вывел на отдельный почтовый ящик по нескольким причинам:

  • использование fetchmail требует указания пароля в конфигурационном файле, а я не хотел оставлять в открытом виде пароль для свого почтового эккаунта;
  • получение почты в два ящика даёт возможность оставить ящик автомата полностью без присмотра не опасаясь пропустить важное сообщение;
  • два ящика предоставляют возможность параллельной работы почтового клиента и fetchmail по протоколам pop3 не мешая друг другу. При этом и почтовый автомат и почтовый клиент будут забирать всю почту из своих ящиков без требования взаимной синхронизации. Из соображений безопасности я никогда не оставляю почту на сервере и всегда настраиваю почтовый клиент так чтобы вытянув письмо на локальный диск он удалил его с сервера. Чтобы забирать почту из одного ящика и оставлять его пустым потребовалась бы синхронизация: либо автомат либо почтовый клиент должны бы были успеть посмотреть почту до того как второй заберёт её и удалит из ящика.

Так как вся необходимая для автоматической обработки почта приходит на мой емейл либо его алиасы я настроил необходимые правила фильтрами своей web почты с Roundcube, где проводил необходимый анализ по адресу отправителя, получателя и полю subject с использованием в том числе регулярных выражений.
основной-емейл -> filter -> action[копирование на специальный ящик] Когда вся нужная почта находится в почтовом ящике для почтового автомата можно настраивать fetchmail.

Настройка fetchmail

Установка необходимых утилит

Установим сам fetchmail

# yum install fetchmail

Для обработки почты будем использовать procmail

# yum install procmail

Для извлечения аттачментов из писем и складывания в отдельную папку

# yum install uudeview

Для работы с сертификатами нужно установить openssl

# yum install openssl

и если не установлен c_rehash

# yum install openssl-perl

получим самый первый по очерёдности сертификат и сохраним его в файл

$ echo "quit" | openssl s_client -connect pop.gmail.com:995 -showcerts 2>&1 | awk '/^[\-]+BEGIN CERTIFICATE[\-]+$/,/^[\-]+END CERTIFICATE[\-]+$/ {if (/^[\-]+BEGIN CERTIFICATE[\-]+$/) { count=count+1; flag=1 } if (count==1 && flag==1) { print $0 } if (/^[\-]+END CERTIFICATE[\-]+$/) { flag=0 }}' > gmail.com.pem

Утилиту c_rehash необходимо запускать после каждого добавления или изменения файла сертификата (он создаёт хеш-именной симлинк на каждый файл с сертификатом)

$ c_rehash $HOME/.fetchmailsslcerts/

получить строки для добавления в файл $HOME/.fetchmailrc

$ MYPATH=".fetchmailsslcerts"; openssl x509 -in $HOME/${MYPATH}/gmail.com.pem -noout -md5 -fingerprint | cut -d '=' -f2,2 | awk -v path=${MYPATH} '{print "sslcertpath "path"\nsslfingerprint "$0}'
sslcertpath .fetchmailsslcerts
sslfingerprint 61:D4:A7:53:76:48:CA:84:4B:90:AD:7C:B5:CB:B4:B6

У меня отключен IPv6 поэтому чтобы не раздражала ошибка
Trying to connect to ::1/25…connection failed.
fetchmail: connection to localhost:smtp [::1/25] failed: Connection refused.
мне пришлось в файле /etc/hosts закоментировать строку
#::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

Отладочные ключи.
-a | –all | (с версии v6.3.3) –fetchall – вытягивается вся почта, а не только уже принятая
-k | -keep – почта не удаляется с сервера
-v | –verbose – почта не удаляется с сервера
-N | –nodetach – не отцепляет fetchmail запущенный в режиме демона от терминала
-d0 – дамп ядра программы

Файл $HOME/.fetchids содержит идентификаторы писем после каждого сеанса приёма почты.

$ fetchmail -akNvd0 --nosyslog
Trying to connect to 127.0.0.1/25...connection failed.
fetchmail: connection to localhost:smtp [127.0.0.1/25] failed: No route to host.
fetchmail: Connection errors for this poll:
name 0: connection to localhost:smtp [127.0.0.1/25] failed: No route to host.
fetchmail: SMTP connect to localhost failed

Такая ошибка происходит на системах где не установлен sendmail. Но я использую procmail. Его и укажу в следующем конфиге.

Для работы неоходим файл $HOME/.fetchmailrc вот его содержимое

содержимое файла $HOME/.fetchmailrc
poll pop.gmail.com
port 995
proto POP3
user ‘mailautomat’
pass ‘rw2lGJmBtIf4SXD’
ssl
sslproto ssl3
sslcertpath “.fetchmailsslcerts”
sslfingerprint 61:D4:A7:53:76:48:CA:84:4B:90:AD:7C:B5:CB:B4:B6
mda “/usr/bin/procmail -d %T”
set syslog set logfile “fetchmail/logs/fetchmail.log”
Обратите внимание что если пути не начинаются со слеша подразумевается путь относительно каталога $HOME пользователя от имени которого запускается fetchmail.

Файл лога сам не создаётся поэтому его нужно создать.

$ touch $HOME/fetchmail/logs/fetchmail.log

Ну и последний штрих файл $HOME/.procmailrc

содержимое файла $HOME/.procmailrc
:0
*^content-Type:
{
# сделаем копию принятого письма
:0c:
$HOME/fetchmail/backup

# а здесь будут распакованы все файлы из письма и сложены в каталог
# для этого сделаем форвард в uudeview который распакует вложения в $HOME/fetchmail/attachments
# опция -a создает нумерованные копии файлов если файлы с таким именем уже обнаружены
:0fw
| uudeview -a -p $HOME/fetchmail/attachments –
}

Теперь можно запускать fetchmail

$ fetchmail -ak

и после этого заглянуть в файл
$HOME/fetchmail/logs/fetchmail.log

Когда всё будет отлажено запускайте fetchmail без ключей тогда он удалит файлы с сервера. После всего можно его добавить в cron или запускать как демона.