Ruby on Rails

индекс
82,34

ActionMailer_X509: подписываем и шифруем письма прямо в Ruby On Rails

В одном из последних проектов понадобилось подписывать и шифровать с помощью сертификатов X.509 письма, отправляемые приложением на Ruby on Rails 3. Беглый поиск привёл к плагину actionmailer_x509, а вот дальше начались проблемы.

Выяснилось, что он не обновлялся с 2008 года, скорее всего не работает с Rails 3 (в частности, смущал комментарий автора: «It has been tested with Rails 2.0.1») и умеет только подписывать, но не шифровать письма. Поиск альтернативных решений ничего не дал, и пришлось знакомиться с плагином поближе.



Знакомство осложнилось очень быстро: набор тестов, шедший в комплекте с плагином падал при прогоне. Как оказалось, хотя сходу заметить это было не просто, дело было в том, что истёк срок действия сертификатов, которые автор включил в тестовый набор. Пересоздал сертификаты. Далее, я убрал из тестового хелпера библиотеки от Rails 2 и добавил соответствующие от Rails 3, сделал ещё ряд изменений

Тут же выяснилось, что Mail, новый gem обработки почты, который теперь используется в Ruby on Rails 3, существенно отличается от Tmail. Пришлось врубаться во внутреннее устройство Mail и Tmail, переписывать все части, затрагивающие Tmail. Ок, готово. Конечно, повозился, и попереносил неперенесённые заголовки письма, но это было решаемо.

Новая проблема: в комментариях к коду автор пишет «NOTE: we can not reparse the whole mail, TMail adds a \r\n which breaks the signature...». И действительно, проверка подписи не работает и в результирующем теле объекта Mail \r\n стоят через каждые 60 символов, в то время как в оригинальном, через каждые 64. Вот над этой проблемой пришлось биться очень долго. Я пытался gsub'ом вернуть всё на место, изучал код gem'а Mail, оставлял баг-репорты в Mail, писал в список расслыки, но всё было тщетно. В конце концов меня спас вопрос на stackoverflow. Оказалось, что Mail добавляет content-id, который меняет заголовки письма, и, следовательно, подпись становится неверна, и это никак не связано с \r\n, о которых писал автор оригинального actionmailer_x509.

После исправления и принудительной установки content_id всё пошло как по маслу: я почистил код, завернул всё в отдельный gem, поправил rake-задания и дописал код, отвечающий за шифрование письма.

Результатом моих трудов можете наслаждаться в моём форке actionmailer_x509 на github'е или с помощью строчки gem 'actionmailer_x509' в вашем Gemfile.

Он позволяет следующим незатейливым кодом включить подпись и\или шифрование исходящего письма

class FooMailer < ActionMailer::Base
  def sending_method(email, from , subject = "Empty subject for signed")
    # Для включения подписи
    x509_sign  true
    x509_sign_cert  "certs/yourwebsite.crt"
    x509_sign_key   "certs/yourwebsite.key"
    # Пароль для приватного ключа
    x509_sign_passphrase "my passphrase for the certificate"
    # Для включения шифрования
    x509_crypt  true
    x509_crypt_cert  "certs/crypt.crt"
    # Можно изменить алгоритм шифрования, если не устраивает стандартный DES
    x509_crypt_cipher "AES-128-CBC"

    mail(:subject => subject, :to => email, :from => from)
  end
end


Кроме того плагин позволяет выставить все эти настройки ключей для всего приложения в целом и предоставляет несколько rake задач для тестирования настроек и скорости работы. Подробнее об этом читайте в README.

Вместо заключения

Я потратил больше месяца на адаптацию actionmailer_x509 к особенностям Ruby on Rails 3. Я изучил smime openssl, gem Mail, gem Tmail и ActionMailer. Я узнал, как заворачивать код в gem и как вообще должна выглядеть структура gem'а; как правильно, с помощью railtie, подгружать rake задачи, что б они стали видны в итоговом Rails приложении. Были моменты, когда я был готов сдаться, и искал обходные пути решения моей проблемы, но, к счастью, я сумел дожать gem.

Я не жалею о потраченном времени, и смотрю на новосозданный gem с чувством удовлетворения. Теперь я гораздо лучше чувствую всю почтовую кухню Ruby on Rails, и я стал гораздо подкованней в вопросах, связанных с OpenSSL. Если вам вдруг придётся выбирать допилить\создать существующее решение или попытаться обойти проблему как-то иначе — попробуйте сделать что-то новое для сообщества, вам должно понравиться!
+30
29 августа 2011, 10:25
16

комментарии (6)

0
wuoten #
достаточно специфичная у вас возникла задача)

все-таки приятно, что для рельсов появляется огромное количество полезных и нужных гемов
0
mpetrunin #
Да уж весьма специфическая :)

Но, к сожалению, партнёр представляет себе межистемное взаимодействие как периодический обмен шифрованными и подписанными письмами :)
0
andrew72ru #
Не один ваш партнер представляет себе так межсистемное взаимодействие. Точно так же действуют налоговая / ПФР / сбербанк и иже с ними.
В данное время взаимодействие с ними может осуществляться только с помощью Windows + IE, потому что, в связи с требованиями закона, все данные должны быть зашифрованы и подписаны прежде чем быть переданными по открытым сетям. Что, в общем-то логично и правильно, но держать терминальный сервер с виндовс только ради такого рода ПО как-то не кошерно, тем более что основная деятельность предприятия отнюдь не связана с постоянным взаимодействием с такого рода структурами.
Так вот, идея такова.
Делаем маленький неттоп, в него ставим любой кастомизируемый линукс, который допиливаем до состояния «получили почту с определенного адреса, зашифровали / подписали ключами с флэшки, отправили по другому адресу».
В результате бухгалтерия любого предприятия может купить себе такой неттоп, включить его в любую структуру сети, и без установки дополнительных программ на клиентские компьютеры мы можем отправлять валидные письма во все государственные (или полугосударственные) организации.
Как вам?
0
mpetrunin #
Про налоговуя / ПФР / сбербанк не знал.

По второй части: отличная идея! Главное, что б было на уровне воткнул — заработало.
0
andrew72ru #
Да, именно так — из коробки.
А по всяким налоговым и прочим — как ни грустно, так оно и есть.
Я работаю в типографии, у нас дизайнеры / пре-пресс — на Mac`ах, менеджеры — на убунтах, и только одна бухгалтерия вечно со своими виндовыми проблемами. С введением терминального серва для 1С-а, СБИС++ и прочих таких проблем стало меньше, но они таки остались.
Самая главная проблема в производстве таких штук — это не настройка / программирование, а лицензии ФСБ на производство шифровального ПО. Я не сталкивался близко с этим всем, но глядя на окружающую действительность, не думаю, что все легко и просто.
0
mixrin #
> налоговая / ПФР / сбербанк

Но там же вся это содомия завязана на Windows + IE + КриптоПРО (седьмая винда причем вроде всё еще не поддерживается)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.