Бортовой журнал Ктулху

Импорт почты из ящика Gmail, разбор содержимого письма формата *.eml и запись в базу

Есть много причин для скачивания содержимого почтового ящика, кто-то боится за сохранность важной почты, кто-то получает доступ к секретной переписке. Но вопрос сейчай не "для чего" а "как". И дальше я опишу последовательность действий для получения содержимого ящика электронной почты на примере Gmail и то, как получить тело письма и вложения в виде отдельных файлов.

Для решения этой задачи я выбрал две утилиты под Linux, которые занимаются сбором почты: Fetchmal и Getmail. С первой я раньше встречался когда настраивал почтовый сервер с доменным почтовым ящиком

Впрочем, по порядку.

  

Установка и настройка Fetchmail

$ sudo apt-get install fetchmail $ mcedit /home/username/.fetchmailrc

set postmaster "user"
set bouncemail
set no spambounce
set softbounce
set properties ""
poll pop.gmail.com
with no dns
with proto POP3
auth password
username "user[pes]example.com"; is user here 
password "typeyourpasswordhere"
is "user" here
options
warnings 3600
antispam 571 550 501 554
no keep
ssl
sslfingerprint "F1:F2:F3:F4:ES:F1:7A:92:98:C6:0F:01:3E:3F:BD:E1"
sslcertpath /user/local/share/certs
mda "/usr/bin/procmail -d %T"

Вместо тестового емейла нужно подставить свой, вместо user - имя текущего пользователя Linux.

Далее, там есть строки sslfingerprint и sslcertpath, о них чуть ниже, это настройка сертификата ssl для Gmail.

Также, для внутреннего перенаправления почты необходима еще одна программа, в данном случае procmail.
Полученная почта перенаправляется в локальный почтовый ящик: /var/mail/currentusername.

На этотм моменте я понял, что Fetchmail мне не совсем подходит, но было сложно остановиться и об этом также будет дальше.

Настройка SSL сертификата Gmail

Создать директорию для сертификатов или воспользоваться существующей.

$ sudo mkdir /usr/local/share/certs

Получить сертификат:

$ openssl s_client -connect pop.gmail.com:995 -showcerts > /usr/local/share/certs/gmail.pem

Удалить все содержимое файла кроме, собственно, сертификата, т.е., оставить все содержимое между строк -----BEGIN CERTIFICATE----- и -----END CERTIFICATE-----.

Если в файле будет два таких блока, попробовать поэкспериментировать, какой из них оставить.

Это надо делать перед каждой операцией получения нового сертификата.

$ sudo c_rehash /usr/local/share/certs/

Получаем отпечаток ключа (fingerprint) сертификата:

$ openssl x509 -in /usr/local/etc/.sslcerts/gmail.pem -noout -md5 -fingerprint

Эта строку надо вписать в конфиг в значение переменной sslfingerprint:

MD5 Fingerprint=FX:A5:ES:1C:FB:A9:7E:6D:F9:DB:F3:62:B2:9E:F1:A0

без этого будет ошибка:

$ fetchmail: Отпечатки pop.gmail.com не совпадают!

На этом этапе fetchmail подключается к почтовому ящику, я получаю такое сообщение:

$ 447 сообщений для Этот адрес электронной почты защищен от спам-ботов. У вас должен быть включен JavaScript для просмотра. на pop.gmail.com (53971830 октетов).

Настройка getmail

Это аналогичный сборщик почты, мне он больше подошел, я на нем остановился.

$ apt-get install getmail

После установки нужно создать файл конфигурации и директорию программы

$ mkdir .getmail $ cd .getmail $ touch getmailrc

Содержимое getmailrc:

[retriever]
type = SimpleIMAPSSLRetriever
server = imap.gmail.com
mailboxes = ("Inbox", "[Gmail]/Sent Mail") # optional - leave this line out to just grab inbox
username = email[pes]example.com
password = *********
verbose = 2
delete = false
[destination]
type = Maildir
path = ~/getmail/

С этими настройками получает почту в отдельные файлы.

Получение всех входящих:

$ getmail -l -n -i Inbox

Полученные письма в формате *.eml  будут складываться в поддиректорию new указанной в конфиге директории [~/getmail].

Далее, нужно разобрать полученные письма и поможет в этом munpack

Разбор письма формата eml при помощи Munpack

$ apt-get install munpack

На самом деле, ничего сложного. Просто выполнив команду

$ munpack filename.eml

получим в этой же папке несколько файлов: part1 - текстовую версию тела письма, part2 - html-версию тела письма и прочие файлы вложений.

Настройка подключения к базе данных

Хранение полученных писем я организовал в БД.

Для этого использую консольного клиента MS SQL - sqlcmd.

Для добавления репозиториев Microsoft используем следующий пакет:

$ wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb $ sudo dpkg -i packages-microsoft-prod.deb

Затем, ставим клиента:

$ apt-get install mssql-tools

После этого необходима небольшая настройка:

$ root@khtulhu:~/getmail$ sqlcmd

Если после попытки запуска sqlcmd на экране:

$ sqlcmd: команда не найдена

Нужно следующее:

$ sudo ls /opt/mssql-tools/bin/sqlcmd*

На экране будет:

$ /opt/mssql-tools/bin/sqlcmd

Выполнить:

$ sudo ln -sfn /opt/mssql-tools/bin/sqlcmd /usr/bin/sqlcmd

Проверить:

$ sqlcmd

Работает.

Упорядочивание полученной почты

Для того, чтобы все было разложено по полочкам, я написал небольшой скрипт

#!/bin/bash
mailfiles="/home/user/mail/$(date +'%m%d%Y')" # директория для почтовых вложений
for fname in new/*.*; do
test -f "$fname" || continue # если пусто, выходим из цикла
EMLTO=$(grep "^To" < $fname | sed -e "s/To://g" | grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b")
EMLFROM=$(grep "^From" < $fname | sed -e "s/From://g" | grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b")
EMLSUBJ=$(grep "^Subject" < $fname | sed -e "s/Subject://g" | sed -e 's/=?UTF-8?B?//g' | sed -e 's/==?=/==/g' | awk '{$1=$1};1' | base64 -d)
EMLDATE=$(grep "^Date" < $fname | sed -e "s/Date://g")
mv -- "$fname" "$fname".eml # пишем расширение каждому файлу чтобы корректно открывался через munpack
munpack -t "$fname".eml
unlink "$fname".eml
# проверить наличие директории с текущей датой, создать при отсутствии
[ ! -d "$mailfiles" ] && mkdir -p "$mailfiles"
ATTACH=""
# получить все вложения и тело письма
for attach in *; do
[[ $attach == "mail.sh" ]] && continue
[[ $attach == "new" ]] && continue
[[ $attach == "tmp" ]] && continue
[[ $attach == "cur" ]] && continue
EMAILBODY=$(cat part2 | sed -e 's|["'\'']||g' | awk '{$2=$2};1')
# пути к вложениям в MS SQL
NEW_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 5 | head -n 1) # уникальные имена файлов
NEW_FILE_NAME="$mailfiles/$NEW_UUID""$attach"
ATTACH+=",$NEW_UUID""$attach"
mv -- "$attach" "$NEW_FILE_NAME" # переносим вложения в папку
done
# тело письма и пути к вложениям запихнуть в SQL
QUERY="INSERT INTO mail (date, email, body, attachments) VALUES(getdate(), '$EMLTO', '$EMAILBODY', '$ATTACH')"
sqlcmd -S 192.168.1.1 -d MYBASE -U user -P secretpass -Q "$QUERY"
done

Вот таким нехитрым способом можно усложнять себе жизнь.