Как стать автором
Обновить

Избавляемся от PGP в почтовом ящике mutt

Время на прочтение4 мин
Количество просмотров3.8K
На мой параноидальный взгляд по возможности всё общение по почте и IM должно быть зашифровано. (Не потому, что мне есть что скрывать, а просто потому, что я не вижу причин показывать свои сообщения соседу Пете, вне зависимости от того, где он работает — нигде, у провайдера, или в спецслужбе.) Для почты это PGP/GPG, для IM это OTR. Но это шифрование призвано защищать сообщения в процессе передачи по сети, а не на винте в почтовом ящике/логах IM. На винте от него толку нет, одни неприятности — медленный поиск в сообщениях (если в вашем MUA поиск вообще работает в зашифрованных письмах), невозможность обрабатывать почтовый ящик простыми скриптами, etc. Если есть необходимость шифровать данные у себя на винте, то для этого есть другие, более подходящие и универсальные средства, чем PGP для части писем.

Поскольку PGP требуется только во время передачи по сети, то было бы идеальным решением шифровать/дешифровать письма в момент приёма/передачи, т.е. используя локальный POP3/SMTP relay сервер. В этом случае все почтовые клиенты (MUA) автоматически получили бы «поддержку PGP», и при этом ничего о PGP сами не знали, и работали с не зашифрованными письмами. Под Windows такой сервер есть — GPGrelay. Под *NIX я аналога найти не смог. Есть утилитка kuvert, которая может автоматически шифровать исходящую почту, но утилитки для дешифровки входящей я не нашёл.

Но девиз mutt не зря «All mail clients suck. This one just sucks less.» — мне удалось с помощью его гибкости, небольшого вспомогательного скрипта для qmail, и такой-то матери решить эту, на первый взгляд банальную, задачку.

Отправка писем


С этим всё просто. За шифрование отправляемых писем отвечает, как обычно, mutt. Таким образом я вижу/контролирую какие сообщения шифруются, а какие нет. А чтобы в моём почтовом ящике оставалась не зашифрованная версия отправленного сообщения, достаточно добавить в ~/.muttrc:
set fcc_clear=yes

Получение писем


А вот здесь возникли сложности. В mutt есть функция decrypt-save, которая корректно дешифрует письмо (в т.ч. с аттачами), сохраняет дешифрованное письмо в указанный почтовый ящик, а зашифрованный оригинал удаляет. (Кстати, не перепутайте её с decode-save, которая делает почти то же самое, только хуже — вроде аттачи как минимум не поддерживает. Что интересно, по умолчанию в mutt именно decode-save повешена на Esc+s, а лучшая decrypt-save не назначена ни на какую комбинацию кнопок.) С её помощью можно создать hook, который автоматически будет дешифровать сообщение в момент открытия, заменяя в текущем ящике шифрованную версию нешифрованной — дописываем в ~/.muttrc:
message-hook '~h"Content-Type: multipart/encrypted"' 'push <decrypt-save>\cu^<Enter><sync-mailbox><Enter>'
У этого подхода есть несколько особенностей/недостатков:
  • Удалить только одно зашифрованное письмо нельзя, так что в момент открытия зашифрованного письма удаляются все помеченные к удалению письма в этом ящике, что может оказаться неприятным сюрпризом в некоторых ситуациях.
  • Как обычно в mutt, в момент пометки текущего письма к удалению, он переходит к следующему письму в этом ящике. Если это зашифрованное письмо было единственным новым письмом, то всё сработает идеально — следующим письмом окажется именно его не зашифрованная копия, так что входя в это письмо вы именно его и увидите. Если в ящике было несколько новых писем, и все зашифрованные, то открывая первое из них вы вызовете лавину автоматических переходов в следующие письма с их автоматическим дешифрованием, но внешне всё сработает как ожидается — в результате откроется именно то письмо, которое вы открывали. Но вот если среди новых писем встречаются зашифрованные и не зашифрованные вперемешку, то входя в первое зашифрованное письмо у вас неожиданно вместо него откроется первое не зашифрованное.
  • В отличие от виндового GPGrelay (который при расшифровке может опционально добавить в письмо информацию о том, что оно было зашифровано/подписано), функция decrypt-save никак не модифицирует письмо. Таким образом, после автоматической расшифровки и удаления оригинала письма мы никак не сможем узнать, было ли оно зашифровано и корректно подписано.
Для решения последней проблемы я написал небольшой скрипт addgpginfo. Он получает на STDIN письмо, если оно было зашифровано или зашифровано и подписано то он добавляет к письму нестандартные заголовки GPG: с полной информацией о шифровании/подписи, после чего запускает указанную ему параметрами программу, предоставляя ей на STDIN модифицированное письмо. Я его разрабатывал для использования в ~/.qmail, но в теории этот подход должен работать с любыми аналогичными программами вроде procmail. Например, если у вас в ~/.qmail:
./Maildir/
то вы вместо этого пишете:
|addgpginfo qmail-local "$USER" "$HOME" "$LOCAL" "" "nodeliver" "$HOST" "$SENDER" ./Maildir/

Из соображений паранойи в него надо бы ещё добавить удаление возможных GPG: заголовков из входящих писем (чтобы никто не смог прислать вам не подписанное письмо от чужого имени, в заголовках которого прописав что оно, якобы, было корректно подписано). И из соображений совместимости переименовать заголовок GPG: в X-GPG:. Но это уже мелочи. Для работы addgpginfo необходимо, чтобы у вас был запущен gpg-agent с опцией --write-env-file, и запущенные X-ы ($DISPLAY ему можно передать параметром, если он у вас не ":0").

Результат выглядит примерно вот так:
image
Теги:
Хабы:
Всего голосов 22: ↑20 и ↓2+18
Комментарии9

Публикации

Истории

Ближайшие события

15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань