Почтовая система в стиле UNIX-way
Для чего, по-твоему, предназначен почтовый клиент?
Правильно, читать почту. А ты никогда не задумывался,
почему все современные MUA (Outlook Express, Thunderbird,
Sylpheed), кроме выполнения своих непосредственных
задач, еще и сортируют почту, получают и отправляют
письма, обрабатывают спам, в общем, занимаются всем, чем
угодно, разве что кофе не варят? Так уж повелось в
современном мире «дружелюбных к пользователю» систем,
что все связанное с определенным кругом задач (в нашем
случае - с почтой) делает Одна Большая Программа. И
пользователь даже не задумывается, что тем самым сильно
себя ограничивает. Зачем, например, мне держать эту
Программу запущенной, если я хочу всего лишь
автоматически забирать новую почту с сервера. Или
автоматически пересылать определенные сообщения на
другой ящик. Или отправлять почту не сразу, а в
определенное время. К счастью, есть путь, способный
освободить нас от рамок одной программы. И имя ему -
UNIX-way.
[ингредиенты]
Для приготовления нашей почтовой пользовательской
системы нам понадобятся следующие компоненты: mutt,
getmail, procmail, spamassassin, msmtp, а также vim,
gnupg, antiword и mairix - по вкусу. Я использую FreeBSD,
поэтому весь софт будем ставить из портов. Разумеется,
нетрудно спроецировать процесс установки и на твой
любимый дистрибутив.
Mutt - превосходный консольный почтовый клиент,
способный творить с письмами невероятные вещи.
Расписывать все его достоинства не имеет смысла,
достаточно сказать, что это самый популярный MUA среди
разработчиков из opensource-сообщества, кернел-хакеров и
просто крутых юниксоидов ;-). Мы будем ставить его
devel-версию 1.5.х («стабильная» ветка имеет сейчас
номер 1.4.х), которая имеет такие преимущества, как
скорость работы, поддержку SMIME-расширений (1.4.х умеет
только PGP-шифрование), и в то же время достаточно
стабильна. Мы научим mutt читать news-конференции.
# cd /usr/ports/mail/mutt-devel
# make WITH_MUTT_MAILDIR_MTIME_PATCH=yes
WITH_MUTT_NNTP=yes WITH_MUTT_IMAP_HEADER_CACHE=yes
WITH_MUTT_MAILDIR_HEADER_CACHE=yes
WITH_MUTT_EDIT_THREADS=yes install clean
Как видно, вместо традиционного mbox я собираюсь
использовать Maildir-формат почтового ящика. Для меня
основным преимуществом Maildir является формат «одно
письмо - один файл».
Getmail - программа для доставки почты с удаленных
POP3/IMAP-серверов с множеством удобств и приятностей
(поддержка SSL, доставка в Maildir-style ящики, докачка
сообщений после разрыва сессии и т.п.), написанная на
Питоне. Более популярный вариант - fetchmail.
# cd /usr/ports/mail/getmail
# make install clean
Также нам не обойтись без procmail. Она будет
обрабатывать, модифицировать (если нужно) и выполнять
сортировку сообщений по папкам.
# cd /usr/ports/mail/procmail
# make install clean
Msmtp - это легковесный почтовый агент, созданный для
машин, на которых нет запущенного SMTP-демона.
Исторически (так сказать, by design) подразумевается,
что на каждой *nix-машине работает почтовый сервер (хотя
бы для обработки локальных отчетов администратору, см.
periodic(8)), настроенный, при необходимости, на релей
«внешнего» почтовика. Но часто на desktop-машинах это
совсем не так: periodic tasks убирают из crontab(5), а
почтовый сервер выключают. В этом случае вместо sendmail
можно использовать msmtp, который имеет поддержку
SMTP-авторизации, TLS, множества аккаунтов, но при этом
не выступает в роли полноценного MTA (не слушает порт и
не принимает соединения). |
# cd /usr/ports/mail/msmtp # make WITH_OPENSSL=yes
install clean
Со спамом можно бороться разными способами, но если
ты пользователь, а не админ почтового сервера, то для
тебя остается один путь - SpamAssassin. Он использует
текстовые анализаторы и black-листы для определения
спама.
# cd /usr/ports/mail/p5-Mail-SpamAssassin
# make install clean
Если ты хочешь защитить свою переписку или, по
крайней мере, проверять/подтверждать аутентичность
сообщений, тебе понадобится GnuPG.
# cd /usr/ports/security/gnupg
# make install clean
Забегая вперед, скажу, что mutt умеет отображать
вложения ничуть не хуже, чем The BAT'ы и Outlook'и,
вызывая сторонние программы для обработки аттача в
зависимости от его MIME-типа. Так, для просмотра M$
Word-файлов нам понадобится antiword - по сути,
преобразователь ".doc" в ".txt":
# cd /usr/ports/textproc/antiword
# make install clean
Никак не обойтись и без поиска по бездонным папкам
почтового ящика. В Maildir'е очень хорошо ищет mairix.
Утилита создает виртуальную папку, в которую складывает
результаты поиска. Очень удобно.
# cd /usr/ports/mail/mairix
# make install clean
Ну и, разумеется, сочинять письма мы будем в своем
любимом текстовом редакторе. Это дело личного вкуса
каждого. Я использую vim.
[готовим!]
Собрав и разложив по полкам ингредиенты, начинаем
готовить. Начнем c «основы основ» - конфигурационного
файла Mutt. Самый распространенный метод - занести все
опции в конфиг ~/.muttrc. Это неудобно по нескольким
причинам, главная из которых - как следует настроенный
mutt имеет конфиг размером в несколько десятков
килобайт, искать и править нужную опцию в этом случае -
не самое веселое развлечение. Я предпочитаю логически
разделить настройку клиента на несколько конфигов и
подключать их в главный файл. В этом случае удобнее
создать папку ~/.mutt, а в ней - muttrc (без точки).
Настройка mutt - длительный, но приятный процесс :).
Почитывая документацию, ты открываешь для себя все новые
опции, и все больше настраиваешь клиент по своему вкусу.
Те же, кто не любит читать документацию, могут найти на
нашем диске полностью отточенные конфиги, которыми я
пользуюсь каждый день. Здесь же приведу основные опции,
без которых не обойтись, с комментариями.
Сила mutt - в его конфигах. Синтаксис основного
конфигурационного файла имеет вид: "set name[=value]".
Этот конфиг будет содержать только главные опции,
которые вряд ли придется часто менять. Переменная name,
в зависимости от опции, может быть строкой, либо
переменной вида "yes|no", а также ask-[yes|no], в этом
случае клиент будет запрашивать подтверждение на
операцию, с отмеченным по умолчанию значением yes или no.
Допустимо также использование конструкций вида "unset
value" и "set value", когда подразумевается no или yes.
Например, "set quit=ask-yes" означает запрос
подтверждения на выход из mutt (по нажатию клавиши 'q'),
по умолчанию (если ничего не вводить в ответ на запрос)
будет считаться ответ yes. В дополнительные конфиги мы
вынесем настройку заголовков писем, привязок клавиш к
действиям, настройку обработчиков событий («хуков»), PGP
и цветовых оформлений (тем). |
Сначала мы определим заголовки, которые будут
подставляться в письмо, и заголовки, которые будут
выводиться в клиенте при просмотре писем. $ vi
~/.mutt/headers.mutt
# выключаем дефолтный порядок представления
заголовков
ignore *
# включаем только интересующие нас поля
unignore Bcc Cc Date From Mailing-List Newsgroups
Organization Reply-To Subject To User-Agent X-Mailer
X-Spam-Status X-Qmail-Scanner X-Spam
# определяем порядок их вывода на экран
hdr_order Date From: To Cc Reply-To Subject
User-Agent X-Mailer X-Spam-Status X-Qmail-Scanner X-Spam
# определяем SMTP-заголовки писем, которые будут
подставляться в наши сообщения
my_hdr From: "Anton A. Karpov" <toxa@toxahost.ru>
my_hdr X-Comment-To: "Anton A. Karpov"
my_hdr User-Agent: Outluck Express 1.5.6i for MS-DOS
6.22-SMP
my_hdr X-Mailer: See User-Agent above :)
my_hdr X-Operating-System: MS-DOS 6.22-CURRENT on
Sony VAIO laptop
my_hdr X-PGP-Public-Key:
http://www.toxahost.ru/gpg/pubkey.asc
my_hdr X-Useless-Header: Do Androids Dream of
Electric Sheep?
Хуки - один из мощных бонусов mutt. С помощью условий
можно переопределять указанные ранее опции, привязывать
их, например, к имени получателя и т.п.
$ vi ~/.mutt/hooks.mutt
# данный хук меняет заголовок From в случае, если
получатель письма имеет адрес вида <name>@real.xakep.ru
send-hook '~t @real\.xakep\.ru' 'my_hdr From: Anton
Karpov <toxa@real.xakep.ru>'
# а этот хук включает pgp-шифрование (по умолчанию я
не шифрую письма), если получатель - putin@gov.ru
send-hook '~t ^putin@gov\.ru$' 'set pgp_autoencrypt'
Мне не нравятся сочетания клавиш по умолчанию. Плюс к
этому, я хочу повесить свои хоткеи на часто выполняемые
операции.
$ vi ~/.mutt/bindings.mutt
# по умолчанию я использую свой сервер для отправки
писем, но при нажатии в клиенте сочетания <Esc-4>,
smtp-аккаунт для отправки писем будет меняться на
gmail'овский:
macro generic "<esc>4" ":set
sendmail=\"/usr/local/bin/msmtp -a gmail\""
# перемещаться по сообщениям клавишами UP и DOWN
bind pager <UP> previous-page
bind pager <DOWN> next-page
# при нажатии клавиши 'S' в окне просмотра писем
вызывается написанный мной скрипт, который подсчитывает
количество писем во всех ящиках
macro index S "!~/.mutt/scripts/msgnum.sh\r"
# при нажатии 'G' в окне просмотра писем, сообщения,
или отправке письма, будет вызываться программа
получения почты
macro pager G "!getmail\r"
macro browser G "!getmail\r"
macro index G "!getmail\r"
# нажатие 'z' на отмеченном письме, которое
проскочило спам-фильтр, «обучит» SpamAssassin, чтобы в
дальнейшем оно определялось как спам. |
macro index z "|sa-learn --no-sync --spam\n" # по
сочетанию клавиш переходить в соответствующие папки
macro index ",f" "c=freebsd-list"
macro index ",o" "c=obsd-list""
Mutt может быть полностью перекрашен во все цвета
радуги. Не буду приводить здесь описание цветовой схемы,
на диске ты найдешь файл с темой toxapaint, где
полностью расписаны все элементы оформления клиента.
$ vi ~/.mutt/themes/mytheme
Настройки GnuPG лучше всего взять из примера,
входящего в документацию. Они вполне разумны и требуют
изменений в редких случаях.
$ vi ~/.mutt/gpg.mutt
Теперь перейдем к основному конфигурационному файлу.
$ vi ~/.mutt/muttrc
# подключаем написанные ранее конфиги
source ~/.mutt/headers.mutt
source ~/.mutt/hooks.mutt
source ~/.mutt/bindings.mutt
source ~/.mutt/gpg.mutt
source ~/.mutt/themes/mytheme
# нижеследующие опции мы не выносим в отдельные
файлы, хотя у экстремалов muttrc состоит из одних
source-включений
# группа опций, отвечающая за кодировку писем
set charset=koi8-r
set send_charset="koi8-r"
set allow_8bit=yes
# а это касается заголовков и редактора
set use_from=no
set envelope_from=no
set attribution="On %d, %n wrote:"
set editor="vim +':set textwidth=72' %s"
# удалять письма без подтверждения
set delete=yes
# спрашивать сохранение копии исходящего письма
set copy=ask-no
# спрашивать при печати письма
set print=ask-yes
# включать оригинальное письмо при ответе
(цитирование)
set include=yes
# уточнять, действительно ли ты хочешь выйти из mutt
set quit=ask-yes
# не соединять аттачи в один файл
set attach_split
# при ответе на письмо не спрашивать про поля To, CC
set fast_reply
# не помечать непрочитанные письма как прочитанные
после выхода
unset mark_od
# позволяет суспендить mutt в шелле стандартным
сочетанием Ctrl^Z
set suspend
# не пищать ;)
unset beep
# не спрашивать про поле CC при написании письма
set askcc=no
# подпись выводится как результат скрипта
set signature="~/.mutt/scripts/signature|"
# просматривать письма встроенным пейджером; можно
указать команды less|more
set pager=builtin
# не показывать следующее письмо после текущего
set pager_stop
# мы берем версию агента из самопальных заголовков
set user_agent=no
# если ты собрал mutt с патчем поддержки NNTP, то для
чтения новостей потребуются следующие опции:
set news_cache_dir="~/Maildir/nntp"
set news_server="my.news.server"
set newsrc="~/.mutt/news.mutt"
set catchup_newsgroup=ask-yes
set nntp_context=2000
set nntp_load_description=yes
# если сервер требует авторизации
#set nntp_user=""
#set nntp_pass=""
set nntp_poll=60
set nntp_reconnect=ask-yes
# далее идет, пожалуй, самый важный параметр. По
умолчанию mutt, как классический юниксовый почтовый
клиент, хочет использовать локальный почтовый сервер,
sendmail. Но у нас нет такового на рабочей машине, и мы
используем msmtp.
set sendmail="/usr/local/bin/msmtp"
# следующие опции понадобятся для поддержки Maildir:
set mbox_type="Maildir"
set spoolfile=~/Maildir/default
set mbox=~/Maildir/default
# здесь складывается отложенная почта |
set postponed=~/Maildir/postponed # а здесь
отправленная
set record=~/Maildir/sent
# помимо цветовых схем, mutt позволяет гибко
настраивать вывод информации о ящиках на тулбар.
Описание несложного синтаксиса можно найти в официальной
документации, но и так ясно, что %d означает количество
удаленных писем, а %n - новых, и т.д.
set status_format="%v [%f] [%m msgs (%l), %n new, %p
unsent, %d deleted]"
set folder_format="%N %F %2l %-8.8u %-8.8g %8s %d %f"
set index_format="%3C %Z %{%b %d} %-20.20L
(%?l?%4l&%4c?) %s"
Еще раз повторюсь, что здесь отмечены не все опции.
Так, например, полностью опущена работа со списками
рассылки. На диске ты найдешь ПОЛНЫЙ комплект моих
рабочих конфигов, проверенных и оттачиваемых годами, со
всеми комментариями. Актуальную версию конфигов
(все-таки я время от времени что-нибудь исправляю) можно
взять с www.toxahost.ru/projects.html.
[получаем и отправляем]
Читать почту мы уже умеем, а вот отправлять и
получать - пока еще нет. Настройка msmtp не займет много
времени. Его конфигурационный файл поделен на секции,
каждая из которых начинается с директивы account
<название_аккаунта>. По умолчанию msmtp ищет аккаунт с
названием default, но можно указать любую другую учетную
запись с помощью аргумента '-a'. Таким образом,
переключение почтовых серверов, через которые будет
отправляться почта, в связке mutt+msmtp будет
осуществляться с помощью хоткея (см. bindings.mutt),
устанавливающего переменную sendmail в значение вида
msmtp -a account.
$ vi ~/.msmtprc
# минимальная настройка включает в себя имя аккаунта,
имя хоста и поле from
account default
host toxahost.ru
from toxa@toxahost.ru
# если же требуется SMTP-авторизация или доступ по
TLS - нет проблем
account toxahost-auth-tls
host toxahost.ru
auth login
user toxa
password mycoolpass
tls
tls_nostarttls
tls_nocertcheck
from toxa@toxahost.ru
За получение почты отвечает getmail. Ее
конфигурационные файлы располагаются в каталоге
~/.getmail и имеют формат «один файл - один аккаунт».
Getmail умеет доставлять почту как по plain POP3/IMAP,
так и по POP3S/IMAPS (POP3/IMAP over SSL), достаточно
указать соответствующий тип доставки. Типичный конфиг
состоит из трех частей - общих опций (options), опций
протокола (retriever) и опций доставки (destination).
$ vi ~.getmail/getmailrc
# здесь мы указываем общие опции, выставляемые для
данного аккаунта
[options]
# включаем подробное журналирование действий
verbose = 1
# указываем получать все сообщения с POP3-сервера, в
том числе и прочитанные
readall = yes
# удалять после получения
delete = yes
# протоколировать процесс
message_log = /var/log/getmail.log
timeout = 360
max_message_size = 0
# самая главная часть - протокол, логин, пароль
[retriever]
type = SimplePOP3Retriever
server = toxahost.ru
username = toxa
password = mycoolpass
# а здесь мы указываем, как будет осуществляться
обработка почты
[destination]
# вместо того чтобы сразу класть почту в ящик, мы
отдаем ее на обработку внешней программе
type = MDA_external
# а именно - procmail
path = /usr/local/bin/procmail
Если вместо незащищенного плайнтекстового POP3
используется POP3-over-SSL, и демон принимает такие
соединения на порту 995, надо всего лишь изменить секцию
retriever на следующую: |
[retriever] type = SimplePOP3SSLRetriever
server = toxahost.ru
port = 995
username = toxa
password = mycoolpass
В сведениях о доставке мы указали, что вся почта
будет отдаваться на обработку procmail, который и
займется сортировкой писем по папкам. Это очень удобно,
когда ты подписан на несколько списков рассылки, или
просто хочешь раскладывать письма по разным папкам в
зависимости от отправителя. Синтаксис конфигурационного
файла procmail выполнен в традиционном наркоманском
стиле ;), характерным для oldschool-программ. Вкратце,
после объявления переменных каждая запись имеет вид
«действие до - условие - действие после», где «действие
до» может быть перенаправлением другой программе,
переписыванием полей письма и т.д., «условие» - регексп,
по которому выполняется «действие после» - перемещение
письма в заданную папку, вызов внешней программы и
прочее. Синтаксис записей ужасен, но именно благодаря
своим возможностям делать с почтой все, что душе угодно,
procmail и по сей день остается самым мощным средством
фильтрации сообщений.
$ vi ~/.procmailrc
MAILDIR=$HOME/Maildir/
LOGFILE=$HOME/.procmaillog
LOGABSTRACT=no
VERBOSE=no
DROPPRIVS=yes
FORMAIL=/usr/local/bin/formail
NL="
"
# прежде всего, вызываем проверку ВСЕХ писем на спам
с помощью SpamAssassin. Об этом чуть позже.
:0fw: spamassassin.lock
| /usr/local/bin/spamc
# письма, помеченные как спам, уходят в трэш
:0:
* ^X-Spam-Status: Yes
$MAILDIR/junk/
# html-письма тоже уходят в трэш
:0
* ^Content-Type:.*html
$MAILDIR/junk/
# письма из списка рассылки freebsd перемещаются в
отведенную для них папку
:0
* ^List-Id:.*freebsd
$MAILDIR/freebsd-lists/
# системные сообщения от рута уходят в специальную
папку, чтобы не забивать мусором основной ящик
:0
* ^(FROM|TO):.*root@*
$MAILDIR/toxahost/
# все остальное сыпется в основной ящик по умолчанию
:0
* .*
$MAILDIR/default/
Пару слов о спаме. Самым первым вызовом procmail была
проверка писем на спам. В принципе, для этого достаточно
просто установить SpamAssassin, так как утилита spamc,
входящая в его комплект, позволяет проверять письма
автономно, без запуска сервера СпамАссассина, spamd. Но
при запущенном сервере проверка идет гораздо быстрее.
# echo spamd_enable="YES" >> /etc/rc.conf
# /usr/local/etc/rc.d/sa-spamd start
[финальный штрих]
Вот и все. Последний штрих - создание файла ~/.mailcap,
в котором будут прописаны соответствия вызываемых
программ различным MIME-типам. Так, кто сказал, что mutt
не умеет читать вложенные doc-файлы?
$ echo "application/msword; antiword -m koi8-r.txt %s;
copiousoutput" >> ~/.mailcap
Теперь при получении письма с аттачем MIME-типа
application/msword (когда тебе во вложении пришлют
doc-файл) mutt вызовет программу antiword, которая
удобно представит тебе содержимое doc-файла в текстовом
виде. По аналогии можно сопоставить другие программы
различным MIME-типам. На диске ты найдешь полные
варианты всех упомянутых сегодня конфигов, в том числе и
«боевой» mailcap. Просто поставь из пакетов/портов
недостающие утилиты и - готово. |
Что такое UNIX-way? Вопрос этот из разряда
философских. И не стоит в компании фанатичных юниксоидов
поднимать на обсуждение тему вроде «правда ли, что perl
- это не UNIX-way» :). Технически же - это то, на чем
основана вся работа в классическом UNIX: когда для
каждой конкретной задачи существует одна маленькая
программа, ничего больше не умеющая, зато выполняющая
свою работу на все сто. Гибкость и сила проявляются в
соединении этих программ, например, через каналы (pipes),
когда вывод одной команды подается на ввод другой.
Например, если я хочу посчитать, сколько человек
запросило определенный файл с сервера по http, я набираю
команду:
# cat /var/log/httpd-access.log | grep 46664.mpg |
awk '{print $1}' | sort | uniq | wc -l
200
В этой простой команде задействовано 6 утилит. В
*nix-системе их сотни, каждая делает что-то свое и имеет
огромное количество опций, так что можно представить,
откуда берется та пресловутая гибкость работы в *nix.
Гибкость увеличивается также и классической юниксовой
парадигмой «все - файл», когда любая прикладная задача
сводится, по сути, к работе с текстовыми файлами с
помощью вышеозначенных утилит.
Разбираемся с терминологией
Почтовый клиент сокращенно называют MUA (Mail User
Agent). По аналогии, почтовый сервер называют MTA (Mail
Transfer Agent). Программа же, занимающаяся доставкой
почты от сервера клиенту (но не обработкой, ни чтением,
ни, тем более, составлением писем), называется MDA -
Mail Delivery Agent.
Будь внимателен, убирая из crontab все запуски
periodic. Взгляни на скрипты в /etc/periodic: помимо
составления отчетов руту, регулярно выполняются такие
вещи, как обновления базы для locate(1). Бездумно удаляя
все подряд можно, например, лишить себя свежей
locate.database. |
(Администратор не несет ответственности (Автор Денис
Евгеньевич)
|