Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Sendmail – Архитектура и принципы разработки

Глава 17 из 1 тома книги "Архитектура приложений с открытым исходным кодом".

Оригинал: "Sendmail"
Автор: Eric Allman
Перевод: Vlad http://vlad8.com/

17.3. Фазы разработки

Как и у большинства долгоживущих проектов у sendmail было несколько этапов разработки, каждый со своей общей целью и ощущениями.

17.3.1. Волна первая: delivermail

Первая реализация sendmail была известна как delivermail. Она была чрезвычайно простой, если не сказать примитивной. Ее единственной задачей было перенаправлять сообщения от одной программы к другой; в частности, у нее не было поддержки SMTP, и она никогда не делала никаких прямых сетевых соединений. Не было необходимости в очереди, потому что каждая сеть имела свою, поэтому программа по сути была просто координатным коммутатором. Так как у delivermail не было прямой поддержки сетевых протоколов, не было причин запускать ее как демон – она вызывалась для перенаправления каждого сообщения, когда то отправлялось. Программа передавала сообщение подходящей программе, которая реализовывала следующий этап и завершалась.

Не было попыток переписывать заголовки для соответствия сети, в которую доставлялось сообщение. Это обычно приводило к тому, что на перенаправляемые сообщения нельзя было ответить. Ситуация была настолько плохой, что об адресации писем была написана целая книга (названная соответствующе !%@:: Руководство по адресации электронной почты и сетям [AF94]).

Вся конфигурация в delivermail была внутри исходного кода и основывалась на специальных символах в адресах. Символы имели приоритет. К примеру, конфигурация хоста могла искать знак “@” и, если таковой был найден, посылала весь адрес назначенному транслирующему хосту Арпанет. Если его не было, она могла искать запятую, и затем посылать сообщение назначенному хосту BerkNET и пользователю, если такой был найден, затем могла проверять наличие восклицательного знака (“!”), сигнализирующего о том, что сообщение должно быть передано ретранслятору UUCP. Если и такого не было, совершалась попытка локальной доставки. Эта конфигурация могла выглядеть вот так:

Input 	Sent To {сеть, хост, потзователь}
foo@bar 	{Arpanet, bar, foo}
foo:bar 	{Berknet, foo, bar}
foo!bar!baz 	{Uucp, foo, bar!baz}
foo!bar@baz 	{Arpanet, baz, foo!bar}

Обратите внимание, что разделители в адресе указывались по-разному, что приводило к путанице, которая могла быть исправлена только при помощи эвристических методов. Например, последний из приведенных примеров мог вполне быть распарсен как {Uucp, foo, bar@baz} на одном из узлов.

Конфигурация была внедрена в исходный код по нескольким причинам: во-первых, из-за ограниченной памяти и 16-битного адресного пространства, парсинг конфигурации во время выполнения программы был бы слишком затратным. Во-вторых, системы того времени были настолько сильно заточены под собственые задачи их владельцев, что перекомпиляция была сама по себе хорошей идеей, просто чтобы убедиться, что у вас есть локальные версии используемых в них библиотек (совместно используемые библиотеки не существовали в Unix 6).

Delivermail распространялась с 4.0 и 4.1 версиями BSD и была более успешной, чем ожидалось; Беркли был далеко не единственным узлом с гибридной сетевой архитектурой. Стало ясно, что требовалась дополнительная работа над этим проектом.

17.3.2. Волна 2: sendmail 3, 4 и 5

Версии 1 и 2 распространялись под названием delivermail. В марте 1981 началась работа над версией 3, которая должна была выйти под именем sendmail. В это время 16-битная PDP-11 все еще была распространена, но 32-битная VAX-11 становилась все популярнее, так что многие имевшиеся изначально ограничения, связанные с малым пространством адресов, отходили в прошлое.

Первоочередными задачами для sendmail были переход на конфигурирование во время выполнения, разрешение модификаций сообщений для обеспечения совместимости между сетями для перенаправляемой почты, а также более богатый язык, на основе которого будут приниматься решения о маршрутизации. Для этого по существу использовалась текстовая перезапись адресов (основанная на токенах, а не символьных строках), этот механизм использовался в некоторых экспертных системах того времени. Существовал специально написанный для этого код для извлечения и сохранения всех строк комментариев (в скобках) и последующей их вставки после того, как программная перезапись была завершена. Было также важно иметь возможность добавлять или пополнять поля заголовков (например, добавлять заголовок Date или включать полное имя отправителя в заголовок From, если оно было известно).

Разработка SMTP началась в ноябре 1981. Исследовательская группа компьютерных наук в университете Беркли получила контракт DARPA на разработку платформы, основанной на Unix для поддержки исследований, спонсируемых DARPA, с целью сделать совместный доступ между проектами проще.

Первоначальная работа над стэком TCP/IP была к тому времени завершена, хотя детали интерфейса сокетов еще модифицировались. Основные протоколы приложений, такие как Telnet и FTP, были завершены, но SMTP еще не был реализован. На самом деле протокол SMTP еще даже не был окончен на тот момент; были большие дискуссии на тему того, что почта должна была пересылаться при помощи протокола, креативно названного Протокол передачи почты (Mail Transfer Protocol – MTP). В то время, как дебаты разгорались, MTP становился все более и более сложным до тех пор, пока от разочарования в нем не был создан набросок протокола SMTP (Простой Протокол Передачи Почты – Simple Mail Transfer Protocol – SMTP), который не был официально опубликован до августа 1982 года. Официально я работал на INGRES Relational Database Management System, но так как я знал о почтовых системах больше, чем кто-либо в Беркли в то время, со мной стали говорить о реализации SMTP.

оей первой мыслью было создать отдельного SMTP-отправителя, который имел бы свою собственную организацию очередей и демон; эта подсистема подсоединялась бы к sendmail для маршрутизации. Однако, некоторые особенности SMTP делали это проблематичным. Например, команды EXPN и VRFY требовали доступа к парсингу, созданию алиасов и модулю проверки локальных адресов. Также, в то время я считал важным, чтобы команда RCPT возвращала результат мгновенно, если адрес был не известен, а не принимала сообщение и затем отправляла бы сообщение о неудавшейся доставке позже. Это оказалось очень дальновидным решением. Забавно, что позже агенты передачи почты часто реализовывали этот момент неправильно, усугубляя проблему обратной отправки спама. Эти проблемы привели к решению сделать SMTP частью sendmail.

Sendmail 3 распространялась с версиями 4.1а и 4.1с BSD (бета версии), sendmail 4 распространялся с версией 4.2 BSD, а sendmail 5 – с версией 4.3 BSD.

17.3.3. Волна 3: Годы хаоса

После того, как я покинул Беркли и перешел в стартап, время на работу над sendmail резко сократилось. Но интернет начинал серьезно набирать обороты и sendmail использовался в различном новом, и все более масштабном, окружении. Большинство производителей Unix-систем (Sun, DEC и IBM) в частности создали свои собственные версии sendmail, взаимно не совместимые между собой. Были также попытки создать opensource-версии, в частности IDA sendmail и KJS.

IDA sendmail появилась из университета Linköping University. IDA включала расширения для более легкой установки и работы в масштабируемых системах, а также абсолютно новую систему конфигурации. Одной из главных новых функций было включение базы данных dbm(3) для поддержки узлов с динамическим содержимым. Поддержка базы данных была возможна за счет нового синтаксиса конфигурационного файла и использовались для многих функций, включая преобразование адресов в/из внешнего синтаксиса (например, отправка письма на ящик john_doe@example.com вместо johnd@example.com) и для маршрутизации.

Sendmail короля Джеймса (KJS, разработана Paul Vixie) была попыткой объединения всех различных версий sendmail. К сожалению, она так и не получила достаточной поддержки для достижения желаемого результата. Эта эра была также обозначена множеством новых технологий, которые отразились на почтовой системе.

Например, создание Sun бездисковых кластеров добавило службу директорий YP (позже NIS) и NFS, сетевую файловую систему. В частности YP должна была быть видимой для sendmail, т.к. алиасы хранились в YP, а не в локальных файлах.

17.3.4 Волна 4: sendmail 8

Спустя несколько лет я вернулся в Беркли как штатный сотрудник. Моей работой было управление группой, занимавшейся установкой и поддержкой инфраструктуры с совместным доступом для исследований отдела Вычислительной техники. Чтобы решать поставленные задачи, созданные главным образом спонтанно исследовательские группы должны были быть объединены каким-то рациональным образом. Во многом как и в ранние дни Интернета, различные исследовательские группы работали на абсолютно различных платформах, некоторые из них были довольно устаревшими. В общем, каждая группа имела свои системы, и хотя некоторые из них были хорошо управляемы, большинство страдало от «отложенного ремонта».

В большинстве случаев электронная почта также была не структурирована. У каждого был адрес электронной почты “person@host.berkeley.edu”, где хостом было название рабочей станции в их офисе или используемый ими общий сервер (университет не имел внутренних поддоменов), за исключением нескольких особенных людей, которые имели адрес @berkeley.edu. Задачей было перейти на внутренние поддомены (так чтобы все индивидуальные хосты имели поддомен cs.berkeley.edu) и объединенную почтовую систему (чтобы каждый человек имел адрес @cs.berkeley.edu). Эту задачу легче всего было решить, создав новую версию sendmail, которую можно было бы использовать во всем отделе.

Я начал с изучения различных вариантов sendmail, получивших популярность. В мои намерения не входило начинать с абсолютно нового кода, а скорее понять функциональность, которую другие нашли для себя полезной. Многие из тех идей были реализованы в sendmail 8, часто с модификациями для совмещения со схожими идеями или для того, чтобы представить их в более общем виде. Например, несколько версий sendmail имели возможность доступа к внешним базам данных, таких как dbm(3) или NIS; sendmail 8 объединил их в один механизм преобразования, который мог работать со многими базами данных (и даже с преобразованием произвольных данных не из баз данных). Аналогично, была включена обобщенная работа с базами данных (сопоставление внутренних и внешних имен) из IDA sendmail.

Sendmail 8 также включал новый конфигурационнй пакет, использующий m4(1) макропроцессор. Он был более декларативным, чем конфигурационный пакет sendmail 5 (главным образом процедурный). То есть sendmail 5 требовал от администратора полностью вручную создавать конфигурационный файл, используя только возможность “include” из m4 для удобства. Конфигурационный файл sendmail 8 позволял администратору задавать, какие функции, отправители сообщений и так далее требовались, а m4 выдавал конечный конфигурационный файл.

Большая часть секции 17.7 описывает улучшения в sendmail 8.

17.3.5 Волна 5: Коммерческие годы

С ростом Интернета и увеличения количества серверов, использовавших sendmail, поддержка больших баз пользователей становилась все более проблематичной. Какое-то время я мог продолжать этот процесс, создав группу добровольцев (неформально названную “Консорциум Sendmail”, или sendmail.org), которые обеспечивали бесплатную поддержку по e-mail и через группу новостей. Но к концу 1990-х количество пользователей выросло настолько, что их практически невозможно было поддерживать на добровольной основе. Вместе с более бизнес-ориентированным другом я создал Sendmail, Inc., ожидая получить новые ресурсы для работы над кодом.

Хотя коммерческий продукт был изначально главным образом ориентирован на конфигурационные инструменты, многие новые функции были добавлены в агент передачи посты с открытым исходным кодом для поддержки нужд коммерческого мира. В частности, компания добавила поддержку TLS (шифрование соединения), SMTP-аутентификации, улучшения в безопасности узлов, такие как защиту от отказа в обслуживании, и, самое важное, плагины для фильтрации почты (интерфейс Milter’а описывается ниже).

На момент написания этой книги коммерческий продукт разросся настолько, что стал включать большие пакеты приложений, основанных на e-mail, большинство которых были созданы на основе расширений, добавленных в sendmail во время первых лет существования компании.

17.3.6. Что произошло с sendmail 6 и 7?

Sendmail 6 по сути был бета-версией sendmail 8. Эта версия никогда не была официально выпущена, но получила довольно широкое распространение. Sendmail 7 вообще никогда не существовало; сразу была выпущена версия 8, потому что все остальные файлы исходных кодов для дистрибутива BSD были выпущены как версия 8, когда BSD 4.4 была выпущена в июне 1993.


Продолжение статьи: Проектные решения