6. Другая Конфигурация

При перекомпилировании sendmail можно сделать некоторые изменения конфигурации. Этот раздел описывает, какие изменения могут быть сделаны, и что для этого нужно сделать. Во многих случаях это не должно быть необходимым, пока вы не начнете переносить sendmail в новую среду.

6.1. Параметры в devtools/OS/$oscf

Эти параметры предназначены для описания среды компиляции, а не правил узла, и обычно должны быть определены в конфигурационном файле для данной операционной системы. Вообще-то этот раздел нужно полностью переписать.
 
NDBM Если установлен, то будет использоваться новая версия библиотеки DBM, разрешающая разнообразные базы данных. Если не установлено ни NDBM, ни NEWDB, используется наименее эффективный метод просмотра псевдонимов.
NEWDB Если он указан, использовать новый пакет баз данных от Berkeley (с 4.4BSD). Этот пакет существенно быстрее, чем DBM или NDBM. Если указаны и NEWDB и NDBM, sendmail будет читать файлы DBM, но будет создавать и использовать файлы NEWDB.
NIS Включить поддержку NIS. Если указанно вместе с NEWDB и NDBM, sendmail будет создавать и DBM и NEWDB файлы только в том случае, если файл псевдонимов включает подстроку "/yp/" в имени. Это предназначено для совместимости с программой mkalias от Sun Microsystems, используемой на мастерах YP.
NISPLUS Вкомпилировать поддержку NIS+.
NETINFO Вкомпилировать поддержку NetInfo (рабочие станции NeXT).
LDAPMAP Вкомпилировать поддержку запросов LDAP X500.
Требует libldap и liblber от Umich LDAP 3.2 или 3.3 release или эквивалентные библиотеки для других библиотек LDAP, таких как OpenLDAP.
HESIOD Вкомпилировать поддержку Hesiod.
MAP_NSD Вкомпилировать поддержку для просмотра IRIX NSD.
MAP_REGEX Вкомпилировать поддержку проверки регулярных выражений.
PH_MAP Вкомпилировать поддержку просмотра ph.
SASL Вкомпилировать поддержку для SASL, необходимый компонент для поддержки SMTP Authentication.
STARTTLS Вкомпилировать поддержку для STARTTLS.
EGD Вкомпилировать поддержку для "Entropy Gathering Daemon" для обеспечения лучших случайных данных для TLS.
SFIO Вкомпилировать поддержку для sfio, необходимого для включения шифрования, например, STARTTLS.
TSPWRAPPERS Вкомпилировать поддержку для TCP Wrappers.
_PATH_SENDMAILCF Путь к файлу sendmail.cf.
_PATH_SENDMAILPID Путь к файлу sendmail.pid.

Есть также несколько флагов компиляции для указания среды, например "_AIX3" и "_SCO_unix_". Смотри файл sendmail/READ_ME, содержащий самое свежее описание собрание этих флагов.

6.2. Параметры в sendmail/conf.h

Параметры и опции компиляции определяются в conf.h. Большинство из них обычно не трогают; все общие параметры находятся в sendmail.cf. Однако, размеры конкретных простейших векторов и т.д., включены в этот файл. Числа, стоящие после параметров означают их значения по умолчанию.

Этот документ не лучший источник информации о флагах компиляции в conf.h - лучше смотреть sendmail/READ_ME или сам sendmail/conf.h.
 

MAXLINE [2048] Максимальная длина строки любой входной строки. Если строки в сообщении превышают эту длину, они все равно будут корректно обработаны; однако, строки заголовков, строки файла конфигурации, строки файла псевдонимов и т.д., должны находиться в пределах этого ограничения.
MAXNAME [256] Максимальная длина любого имени, например имени хоста или пользователя.
MAXPV [256] Максимальное количество параметров для любой почтовой программы. Ограничивает количество получателей, передаваемых за одну транзакцию, и может быть равно любому произвольному числу больше 10, так что sendmail при необходимости будет разбивать доставку на более мелкие пакеты. Большие числа могут уменьшить загрузку вашей системы.
MAXATOM [1000] Максимальное количество атомов (лексем) в одном адресе. Например, адрес "eric@CS.Berkeley.EDU" содержит семь атомов.
MAXMAILERS [25] Максимальное количество почтовых программ, определяемых в файле конфигурации.
MAXRWSETS [200] Максимальное количество определяемых наборов правил перезаписи. Первая половина из них зарезервирована для числовой нумерации (например, "S92"), в то время как вторая половина зарезервирована для своей нумерации (например, "Sfoo"). Таким образом, при указании значения 200 попытка использовать "S99" будет успешной, а "S100" - нет.
MAXPRIORITIES [25] Максимальное количество определяемых значений для поля "Precedence:" (используя строку P в sendmail.cf).
MAXUSERENVIRON [100] Максимальное количество переменных окружения пользователя, передаваемых в подчиненные почтовые программы.
MAXMXHOSTS [100] Максимальное количество принимаемых записей MX для любого одиночного хоста.
MAXALIASDB [12] Максимальное количество открываемых баз данных псевдонимов. Заметьте, что также может быть ограничение на количество открытых файлов.
MAXMAPSTACK [12] Максимальное количество преобразований, "кучкуемых" в преобразовании класса sequence.
MAXMIMEARGS [20] Максимальное количество аргументов в заголовке MIME Content-Type:; дополнительные аргументы будут игнорированы.
MAXMIMENESTING [20] Максимальная глубина вложения сообщений MIME (то есть, вложенных документов Message или Multipart; это не ограничивает количество компонент в отдельном документе Multipart).
MAXDAEMONS [10] Максимальное количество сокетов, которые может открыть sendmail для приёма соединений на различных портах.
MAXMACNAMELEN [25] Максимальная длина имени макроса.

Существует множество других опций компиляции. Они определяют включать или нет в компиляцию определенные части кода. Отмеченные знаком | имеют значения 0/1.
 

NETINET| Если установлена, вкомпилируется поддержка сетевого протокола Internet. Предыдущие версии sendmail устанавливали ее опцией DAEMON; это старое использование теперь неправильно. По умолчанию включена; выключите ее, если ваша система не поддерживает протоколы Internet.
NETINET6| Если установлена, вкомпилируется поддержка работы в сети IPv6. Она должна быть дополнительно включена добавлением установок DaemonPortOptions.
NETISO| Если установлена, вкомпилируется поддержка сетевого протокола ISO (она может быть соответственно определена как #define в Makefile вместо conf.h).
NETUNIX| Если установлена, вкомпилируется поддержка доменных сокетов UNIX. Используется для поддержки управляющих сокетов.
LOG Если установлена, то используется программа syslog. Она делает информационные записи в протокол при каждой обработке сообщения, и делает запись в лог более высокого приоритета при внутренних ошибках системы. ОЧЕНЬ РЕКОМЕНДУЕТСЯ - если вам не нужно протоколирование, выключите его в файле конфигурации.
MATCHGECOS| Вкомпилировать код для "нечеткого совпадения " в поле GECOSв /etc/passwd. Также требует, чтобы опция MatchGECOS была включена.
NAMED_BIND| Вкомпилировать код для использования сервера Berkeley Internet Name Domain (BIND) для определения TCP/IP имен хостов.
NOTUNIX Если вы используете почтовый формат, отличный от UNIX, вы можете выставить этот флаг, чтобы отключить специальную обработку строк "From" в стиле UNIX.
QUEUE| Этот флаг должен быть выставлен для включения кода очереди. Если он не установлен, почтовые программы должны принимать почту немедленно, или она будет возвращена отправителю.
SMTP| Если установлен, то будет вкомпилирован код для обработки пользовательского и серверного SMTP. Необходим только в случае, если ваша машина имеет почтовые программы, говорящие на SMTP (то есть большинство машин).
USERDB| Включить экспериментальный пакет Berkeley user Information database. Это добавит новый уровень расширения локальных имен между псевдонимизированием и перенаправлением. Использует пакет NEWDB. Может быть изменено в будущих выпусках.

Следующие опции обычно включаются в описаниях операционных систем в conf.h.
 

IDENTPROTO| Вкомпилировать протокол IDENT определенный в RFC 1413. По умолчанию включена для всех систем, кроме Ultrix, которая, видимо, имеет такую интересную "особенность", что при получении сообщения "host unreachable", она закрывает все открытые соединения к тому хосту. Из-за того, что некоторые файервольные шлюзы посылают этот код ошибки при соединении с неавторизованным портом (типа 113, используемого IDENT), Ultrix не может получать email с таких хостов.
SYSTEM5 Устанавливает все параметры компиляции, подходящие для System V.
HASFLOCK| Использовать для блокировки Berkeley-style flock вместо SystemV lockf. Вследствие очень необычной семантики блокировок между разветвлениями в lockf, эта опция, по возможности, всегда должна быть использована.
HASINITGROUPS Выставьте эту опцию, если ваша система имеет вызов initgroups()(если вы имеете поддержку множественных групп). Используется по умолчанию, если не определена SYSTEM5, или если у вас HPUX.
HASUNAME Установите ее, если у ваша система имеет системный вызов uname(2) (или соответствующую библиотечную подпрограмму). Используется по умолчанию, если определена SYSTEM5.
HASGETDTABLESIZE Установите ее, если вы имеете системный вызов getdtablesize(2).
HASWAITPID Установите ее, если вы имеете системный вызов haswaitpid(2).
SFS_TYPE Механизм, который может быть использован для получения информации об объеме файловой системы. Значение может быть одним из SFS_USTAT (использует системный вызов ustat(2)), SFS_4ARGS (использует системный вызов statfs(2) с четырьмя аргументами), SFS_VFS (использует системный вызов statfs(2) с двумя аргументами, включая <sys/vfs.h>), SFS_MOUNT (использует системный вызов statfs(2) с двумя аргументами, включая <sys/mount.h>), SFS_STATFS (использует системный вызов statfs(2) с двумя аргументами, включая <sys/statfs.h>), SFS_STATVFS (использует системный вызов statfs(2) с двумя аргументами, включая <sys/statvfs.h>), или SFS_NONE (никаким образом нельзя получить эту информацию).
LA_TYPE Тип средней загрузки. Подробности описаны ниже.

Существует несколько встроенных способов подсчета средней загрузки. Sendmail пытается автоматически сконфигурировать их на основе несовершенных догадок; вы можете выбрать один из них используя опцию cc -DLA_TYPE=type, где type - это:
 

LA_INT Ядро хранит среднюю загрузку в ядре как целые числа типа long. Настоящие значения масштабируются коэффициентом FSCALE (по умолчанию 256).
LA_SHORT Ядро хранит среднюю загрузку в ядре как целые числа типа short. Настоящие значения масштабируются коэффициентом FSCALE (по умолчанию 256).
LA_FLOAT Ядро хранит среднюю загрузку в ядре как массив чисел с плавающей точкой двойной точности.
LA_MACH Использовать средние загрузки в стиле MACH.
LA_SUBR Вызывать программу getloadavg для получения средних загрузок в виде массива чисел типа double.
LA_ZERO Всегда в качестве средней загрузки возвращать ноль. Это крайний случай.

Если определен тип LA_INT, LA_SHORT, или LA_FLOAT, вам также может понадобиться определить _PATH_UNIX (путь к вашим системным бинарникам) и LA_AVENRUN (имя переменной, содержащей среднюю загрузку в ядре; обычно "_avenrun" или "avenrun").

6.3. Конфигурация в sendmail/conf.c

В conf.c могут быть сделаны следующие изменения. 6.3.1. Встроенные Семантики Заголовков Не все семантики заголовков определяются в файле конфигурации. Строки заголовков, которые могут быть включены только определенными почтовыми программами (так же как и другие более скрытые семантики) могут быть определены в таблице HdrInfo в conf.c. Эта таблица содержит имя заголовка (которое должно быть в символах нижнего регистра) и набор управляющих флагов заголовка (описанных ниже). Флаги таковы:
 
H_ACHECK Обычно, когда сделана проверка совместимости строки заголовка с почтовой программой, sendmail не удаляет существующую строку. Если этот флаг выставлен, sendmail будет удалять существующие строки заголовка. То есть, если этот бит выставлен, и почтовая программа не имеет установленные биты флагов, пересекающиеся с требуемыми почтовой программой флагами в определении заголовка в sendmail.cf, строка заголовка всегда уничтожается.
H_EOH Если установлено это поле заголовка, обращаться с ним, как с пустой строкой, т.е. оно сигнализирует о конце заголовка и начале текста сообщения
H_FORCE Добавить это вхождение в заголовок, даже если в сообщении такое уже было. Если вхождение заголовка не имеет этот бит выставленным, sendmail не добавит в заголовок еще одну строку, если строка с таким именем уже имеется в заголовке. Это обычно может быть использовано для того, чтобы каждый, кто обрабатывал это сообщение, оставлял в нем отметку.
H_TRACE Если этот флаг установлен, то это поле временной метки (трассировки). Если количество полей трассировки в сообщении превышает предустановленное значение, сообщение возвращается по подозрению в псевдонимной петле.
H_RCPT Если выставлен, то это поле содержит адреса получателей. Это поле используется флагом -t, когда он собирает получателей из сообщения, чтобы определить, кому посылать.
H_FROM Этот флаг указывает, что это поле определяет отправителя. Порядок этих полей в таблице HdrInfo определяет предпочтение sendmail, по какому полю отправлять сообщения об ошибке.
H_ERRORSTO Адреса в этом заголовке должны получить сообщения об ошибке.
H_CTE Этот заголовок является заголовком Content-Transfer-Encoding.
H_CTYPE Этот заголовок является заголовком Content-Type.
H_STRIPVAL Обрезать значение из заголовка (для Bcc:).

Давайте взглянем на пример спецификации HdrInfo:

        struct hdrinfo                          HdrInfo[] =
        {
                /* originator fields, most to least significant */

                "resent-sender",                H_FROM,
                "resent-from",                  H_FROM,
                "sender",                       H_FROM,
                "from",                         H_FROM,
                "full-name",                    H_ACHECK,

                "errors-to",                    H_FROM|H_ERRORSTO,
                /* destination fields */
                "to",                           H_RCPT,
                "resent-to",                    H_RCPT,
                "cc",                           H_RCPT,

                "bcc",                          H_RCPT|H_STRIPVAL,
                /* message identification and control */ 
                "message",                      H_EOH,
                "text",                         H_EOH,
                /* trace fields */

                "received",                     H_TRACE|H_FORCE, 
                /* miscellaneous fields */ 
                "content-transfer-encoding",    H_CTE, 
                "content-type",                 H_CTYPE,

                NULL,                           0,
        };
Эта структура показывает, что поля "To:", "ResentTo:", и "Cc:" - все они определяют адреса получателей. Любое поле "Full-Name:" будет удалено, пока требуемый флаг почтовой программы (указанный в файле конфигурации) не будет определен. Поля "Message:" и "Text:" будут заканчивать заголовок; они используются различными несогласными протестантами в сетевом мире. Поле "Received:" всегда будет добавлено, и может быть использовано для трассировки сообщений.

Здесь имеется большое количество важных точек. Во-первых, поля заголовка не добавляются автоматически просто потому, что они имеются в структуре HdrInfo; для того, чтобы они добавлялись в сообщение, они должны быть определены в файле конфигурации. Ко всем полям, упомянутым в файле конфигурации, но не упомянутым в структуре HdrInfo применяется обработка по умолчанию; то есть, они добавляются, если их еще нет в сообщении. Во-вторых, структура HdrInfo всего лишь определяет банальную обработку; конкретные заголовки обрабатываются отдельно, специальным кодом, вне зависимости от статуса, определенного в HdrInfo. Например, поля "Sender:" и "From:" всегда просматриваются в почте ARPANET для определения отправителя1; это используется для выполнения функции "вернуть отправителю". Поля "From:" и "Full-Name:" используются для определения полного имени отправителя, если это возможно; оно сохраняется в макросе $x и используется во многих случаях.

6.3.2. Ограничение использования Email Если существует необходимость ограничить прохождение почты через ретранслятор (relay), может быть изменена подпрограмма checkcompat. Эта подпрограмма вызывается для каждого адреса получателя. Она возвращает статус выхода, показывающий статус сообщения. Статус EX_OK принимает адрес, EX_TEMPFAIL ставит сообщение в очередь для более поздней попытки, а другие значения (обычно EX_UNAVAILABLE) отвергают сообщение. При отвержении сообщения checkcompat выдается сообщение об ошибке (используя usrerr). Например, checkcompat может быть такой:
        int
        checkcompat(to, e)
                register ADDRESS *to;
                register ENVELOPE *e;
        {
                register STAB *s;


                s = stab("private", ST_MAILER, ST_FIND);
                if (s != NULL && e->e_from.q_mailer != LocalMailer && 
                        to->q_mailer == s->s_mailer)
                {
                        usrerr("No private net mail allowed through this machine"); 
                        return (EX_UNAVAILABLE);
                }

                if (MsgSize > 50000 && bitnset(M_LOCALMAILER, to->q_mailer))
                {
                        usrerr("Message too large for non-local delivery");
                        e->e_flags |= EF_NORETURN;
                        return (EX_UNAVAILABLE);
                }
                return (EX_OK); 

        }
Такая конструкция будет отвергать сообщения размером более 50000 байт, если они не локальны. Для подавления возврата тела сообщения при ошибке, в e->e flags может быть выставлен флаг EF NORETURN. Конкретное использование этой подпрограммы очень зависит от реализации, и должно быть ограниченным. 6.3.3. Классы Преобразований Новой Базы Данных Новые ключевые преобразования могут быть добавлены созданием функции инициализации класса и функции просмотра. Они потом добавляются в подпрограмму setupmaps.

Функция инициализации вызывается так:

xxx map init(MAP *map, char *args)

где map является внутренней структурой данных; args - это указатель на кусок строки файла конфигурации с последующим именем класса преобразования; флаги и имена файлов могут быть взяты из этой строки. Функция инициализации должна возвращать TRUE, если она успешно открыла преобразование, и FALSE в другом случае.

Функция просмотра вызывается так:

xxx map lookup(MAP *map, char buf[], char **av, int *statp)

где map внутренне определяет преобразование; buf имеетв входной ключ; Он может быть (и даже очень часто так оно и есть) использован разрушающе; av - список аргументов, передаваемых внутрь из переписываемой строки. Функция просмотра должна возвращать указатель на новое значение. Если просмотр преобразования не успешен, *statp должен быть выставлен на код статуса выхода; в частности, если была произведена попытка восстановления кодом более высокого уровня, он должен быть выставлен в EX_TEMPFAIL,.

6.3.4. Функция Организации Очереди

Для определения того, должно ли быть сообщение поставлено в очередь, или обработано немедленно, используется подпрограмма shouldqueue. Обычно она сравнивает приоритет сообщения с текущей средней загрузкой. Определение по умолчанию таково:
        bool

        shouldqueue(pri, ctime)
                long pri;
                time_t ctime;
        {
                if (CurrentLA < QueueLA)
                        return (FALSE);
                return (pri > (QueueFactor / (CurrentLA - QueueLA + 1))); 

        }
Если текущая средняя загрузка (глобальная переменная CurrentLA, определяемая до вызова функции) меньше, чем нижний порог средней загрузки (опция x, переменная QueueLA), shouldqueue немедленно возвращает FALSE (то есть, оно не должно быть поставлено в очередь). Если текущая средняя загрузка превышает верхний порог средней загрузки (опция X, переменная RefuseLA), shouldqueue немедленно возвращает TRUE. В других случаях, она подсчитывает функцию основанную на приоритете сообщения, коэффициенте очереди (опция q, глобальная переменная QueueFactor), и текущей и пороговой средней загрузке.

Реализация, которая берет в рассмотрение настоящий возраст сообщения, может также использовать параметр ctime, который является временем первого представления сообщения в sendmail. Заметьте, что параметр pri уже учтен в количестве попыток отсылки сообщения (хотя, со временем это приводит к понижению приоритета сообщения); в ожидании того, что ctime будет использован как "оператор выхода" для гарантии того, что сообщение, в конце концов, обработано.

6.3.5. Отвержение Входящих Соединений SMTP

Если входящее соединение SMTP должно быть отвергнуто, функция refuseconnections возвращает TRUE. Текущая реализация основана исключительно на текущей средней загрузке и опции средней загрузки отказа (опция X, глобальная переменная RefuseLA):
        bool
        refuseconnections()
        {
                return (RefuseLA > 0 && CurrentLA >= RefuseLA);
Более умная реализация должна смотреть на большее количество системных ресурсов.

6.3.6. Подсчет Средней Загрузки

Подпрограмма getla возвращает значение текущей средней загрузки (Округленное до целого). Пакет поставки включает несколько возможных реализаций. Если вы портируете в новую среду, вам может понадобиться добавить некотрые новые вещи2.

6.4. Конфигурация в sendmail/daemon.c

Файл src/daemon.c содержит большое количество подпрограмм, зависящих от локальной сетевой среды. Поставляемая версия подразумевает, что вы имеете сокеты в стиле BSD.

В предыдущих выпусках, если вы хотели обобщить просмотры $[ ... $], мы рекомендовали вам изменить подпрограмму maphostname. Теперь, вместо этого, мы рекомендуем вам создавать новое ключевое преобразование.

6.5. Сертификаты для STARTTLS

В этом разделе мы подразумеваем, что sendmail был скомпилирован с поддержкой STARTTLS. Когда sendmail выступает в качестве сервера, он требует от сертификатов X.509 поддержку STARTTLS: сертификат для сервера (ServerCertFile), как минимум один корневой CA (CACERTFile), то есть сертификат, используемый для подписи других сертификатов, и путь к каталогу, содержащему остальные  CA (CACERTPath). Файл, указанный CACERTFile может содержать несколько сертификатов различных CA. DN этих сертификатов посылаются клиенту вов время рукопожатия TLS (как  часть CertificateRequest) как список приемлимых CA. Для идентификации в режиме клиента также требуется сертификат X.509 (ClientCertFile), однако sendmail всегда будет использовать STARTTLS, если это будет предложено сервером. Сертификаты могут быть получены от сертификационного авторитета или созданы с помощью OpenSSL. Требуемый формат для сертификатов и частных ключей - PEM. Чтобы sendmail мог стартовать автоматически, частные ключи (ServerCertFile, ClientCertFile) должны храниться в незашифрованом виде. Ключи защищаются на уровне прав доступа файловой системы. Никогда не давайте частные ключи посторонним лицам.

6.6. PRNG для STARTTLS

STARTTLS для нормальной работы требует мощный генератор псевдо-случайных чисел (PRNG). В зависимости от используемой вами библиотеки TLS, может потребоваться явно инициализировать PRNG случайными данными. OpenSSL по возможности использует /dev/random(4) (соответствует флагу компиляции HASURANDOMDEV). В системах с отсутствием этой поддержки, в файле sendmail.cf опцией RandFile должен быть указан случайный файл. В таких системах для получения полезных случайных данных очень советуется использовать "Enttropy Gathering Daemon" EGD от Brian Warner.В этом случае sendmail должен быть скомпилирован с флагом EGD, а опция RandFile должна указывать на сокет EGD. Если ни /dev/urandom(4), ни EGD не доступны, вы должны удостовериться, что полезные случайные данные всё время доступны в RandFile. Если файл не модифицировался последние 10 минут до использования его sendmail'ом, его содержимое считается устаревшим. Один из методов создания этого файла:

        openssl rand -out /etc/mail/randfile -rand /path/to/file:...256

Для получения расширенной информации смотрите документацию на OpenSSL. В данном случае PRNG для TLS загружается другими случайными данными, только если установлена опция DontBlameSendmail InsufficientTntropy. Скорее всего этого будет недостаточно для некоторых конкретных операций, например для создания (временных) ключей.
Для получения дополнительной информации о сертификатах, их создании и использовании, важности хорошего PRNG и других аспектах TLS читайте документацию OpenSSL.


1. На самом деле, в SMTP такого больше нет; эта информация содержится на конверте. Старые протоколы ARPANET не полностью отличали заголовок от конверта. [назад]

2. Если вы это сделаете, пожалуйста, присылайте изменения по адресу sendmail@Sendmail.ORG. [назад]



2001 Александр С. Плотников