RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Перевод выполнен Алексеем Паутовым в рамках некоммерческого проекта RussianLDP (http://www.rldp.ru/). Именно на этом сайте и надлежит искать новые версии, если таковые будут.

Транспорт pipe

Транспорт pipe использует доставку через канал (pipe) к команде, выполняющейся в ином процессе. Один пример: использование pipe как псевдоудалённого транспорта для передачи сообщений какому-то иному механизму доставки (типа UUCP). Другой: использование отдельными пользователями для автоматической обработки их входящих сообщений. Транспорт pipe может использоваться одним из следующих способов:

  • Маршрутизатор направляет один адрес на транспорт обычным способом, и транспорт сконфигурирован как транспорт pipe. В этом случае $local_part содержит локальную часть адреса (как обычно), запускаемая команда задана в транспорте опцией command.
  • Если опция batch_max установлена более, чем в 1 (значение по умолчанию 1), транспорт может обработать более одного адреса за один запуск. В этом случае когда к транспорту роутится более одного адреса, $local_part не установлена (поскольку она не уникальна). Однако, псевдопеременная $pipe_addresses (описанная в разделе 29.3) содержит все адреса, которые роутятся к транспорту.
  • Роутер переадресует адрес напрямую к команде pipe (например, из файла алиасов или форвардов). В этом случае $address_pipe содержит текст команды pipe, и опция command в роутере игнорируется. Если транспортируется лишь один адрес (batch_max более одного, или лишь один адрес был переадресован к команде), $local_part содержит переадресованную локальную часть.

Транспорт pipe неинтерактивный метод доставки. Также exim может доставлять сообщения через каналы, используя интерактивный протокол LMTP. Это осуществляется транспортом lmtp.

В случае, когда pipe работает как следствие совпадения в локальном пользовательском файле .forward, команда запускается под uid и gid этого пользователя. В других случаях uid и gid должны быть заданы явно, в транспорте или в маршрутизаторе, обрабатывающем адрес. Текущий и домашний каталоги также управляемы. Для получения дополнительных деталей об окружении локальной доставки, смотрите разделы 23 и 25 для обсуждения пакетной локальной доставки.

29.1. Конкурирующие доставки

Если два сообщения приходят почти одновременно и оба роутятся на доставку pipe, два транспорта pipe могут быть запущены одновременно. Вы должны гарантировать, что любые команды pipe, установленные Вами, являются корректными для этого случая. Если команда пишет в файл, может быть полезна утилита exim_lock.

29.2. Возвращаемый статус и данные

Если команда выходит со статусом, отличным от нуля, доставка считается неудачной, если не установлена опция ignore_status (в этом случае код возврата обрабатывается как ноль), или возвращаемый код один из перечисленных в опции temp_errors, которые интерпретируются со смыслом "попробуйте позднее" (try again later). В этом случае доставка задерживается. Детали постоянной ошибки протоколируются, но не включаются в рикошет, просто содержащий local delivery failed.

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

Если код возврата более, чем 128, а выполняемая команда shell-скрипт, это обычно означает, что скрипт был уничтожен сигналом, чьё значение равно коду возврата минус 128. Опция freeze_signal не применяется в этом случае. Если exim не может запустить команду (то есть, если execve() неудачна), код возврата устанавливается равным 127. Это значение, возвращаемое shell, если запрашивают о запуске невыполняемой команды. Формулировка для протоколов наводит на мысль, что проблемой может быть несуществующая команда.

Опция return_output может затрагивать результат доставки. Если она установлена, а команда производит какой-либо вывод на своём стандартном выводе или в стандартном потоке ошибок, предполагается, что произошла ошибка команды, даже если она вернула нулевой код возврата, или установлена опция ignore_status. Вывод команды включается как часть сообщения рикошета. Опция return_fail_output подобна вышеописанной за исключением того, что вывод возвращается, лишь когда команда выходит с ошибочным кодом возврата, то есть значениями кроме нуля или совпадающим с temp_errors.

29.3. Как выполняется команда

Командная строка (по умолчанию) разбирается в имя команды и аргументы непосредственно транспортом pipe. Опции allow_commands и restrict_to_path могут использоваться для ограничения команд, которые могут быть запущены.

Элементы, не помещённые в кавычки, разделяются по пробелам. Если аргумент помещён в двойные кавычки, обратный слэш интерпретируется как обычно: как специальный символ. Если аргумент фигурирует в одинарных кавычках, интерпретации специальных символов не производится (имеются в виду символы, начинающиеся с обратного слэша).

К командной строке применяется раскрытие строки кроме случаев, когда она приходит из традиционного файла .forward (команды из файла фильтра раскрываются). Раскрытие применяется по очереди к каждому аргументу, а не ко всей строке. Поэтому любой любой элемент раскрытия, содержащий пробелы, должен быть помещён в кавычки таким образом, чтобы он был внутри одного аргумента. Установка типа:
command = /some/path ${if eq{$local_part}{postmaster}{xx}{yy}}
работать не будет, поскольку элемент раскрытия разбивается на несколько аргументов. Вы должны написать:
command = /some/path "${if eq{$local_part}{postmaster}{xx}{yy}}"
для гарантии, что всё это в одном аргументе. Раскрытие производится этим способом, аргумент за аргументом, таким образом, число аргументов не может быть изменено в результате раскрытия, а кавычки или обратные слэши во вставленных параметрах не взаимодействуют с внешними кавычками. Однако, это приводит к проблемам: если Вы хотите генерировать много параметров (или имя команды плюс аргументы) из одного раскрытия. В этой ситуации самое простое решение: использовать shell. Например:
command = /bin/sh -c ${lookup{$local_part}lsearch{/some/file}}

Имеет место специальная обработка, когда аргумент состоит в точности из текста $pipe_addresses. Это не общая переменая раскрытия: единственное место, где распознаётся эта строка, когда она появляется как параметр для канала или команды транспортного фильтра. Она вызывает каждый обрабатываемый адрес для вставки в список аргументов в этой точке как отдельный параметр. Это позволяет избежать любых проблем с пробелами или метасимволами shell и используется когда транспорт pipe обрабатывает группу адресов в пакете.

После разделения на параметры и раскрытия, результирующая команда запускается в субпроцессе напрямую от транспорта, не под shell. Доставляемое сообщение предоставялется на стандартном вводе, стандартный вывод и стандартный вывод для ошибок связаны с одним каналом, читаемым exim. Опция max_output контролирует, как много вывода может произвести команда, и опции return_output и return_fail_output управляют, что с ним делается.

Невыполнение команды под shell (по умолчанию) уменьшает риск безопасности в случаях, когда команда из пользовательского фильтра строится из данных, взятых из входящего сообщения. Если shell требуется, он, разумеется, может быть явно определён как команда, которая выполнится. Однако, существуют обстоятельства, когда существующие команды (например, в файлах .forward) ожидают своего выполнения под shell и не могут быть легко модифицированы. Для разрешениия этих случаев есть опция, называемая use_shell, которая изменяет способ работы транспорта pipe. Вместо описанной разбивки командной строки, она раскрывает её как одну строку и передаёт результат /bin/sh. Опция restrict_to_path и средство $pipe_addresses не могут использоваться с use_shell, а весь механизм менее безопасен.

29.4. Переменные окружения

Перечисленные ниже переменные окружения устанавливаются при вызове команды. Список компромисс, для максимальной совместимости с другими MTA. Отметьте, что для добавления дополнительных переменных окружения может использоваться опция environment.
ИмяЗначение
DOMAINДомен адреса.
HOMEДомашний каталог, если задан.
HOST Имя хоста при вызове из роутера (смотрите ниже).
LOCAL_PARTСмотрите ниже.
LOCAL_PART_PREFIXСмотрите ниже.
LOCAL_PART_SUFFIXСмотрите ниже.
LOGNAMEСмотрите ниже.
MESSAGE_ID Локальный идентификатор сообщения exim.
PATHХадано путём опции path.
QUALIFY_DOMAINКвалификационный домен отправителя.
RECIPIENTПолный адрес получателя.
SENDERОтправитель сообщения (пустой, если рикошет).
SHELL/bin/sh
TZЗначение опции timezone, если установлена.
USERСмотрите ниже.

Когда транспорт pipe вызывается непосредственно из (например) роутера accept, LOCAL_PART устанавливается в локальную часть адреса. Когда он вызывается как результат раскрытия форварда или псевдонима, LOCAL_PART устанавливается в локальную часть адреса, который был раскрыт. В обоих случаях любые префиксы удаляются из локальной части и становятся доступны в LOCAL_PART_PREFIX и LOCAL_PART_SUFFIX соответственно. LOGNAME и USER устанавливаются в то же значение, что и LOCAL_PART для совместимости с другими MTA.

HOST устанавливается лишь, когда транспорт pipe вызывается из роутера, который ассоциирует хосты с адресами, типично используя pipe как псевдоудалённый транспорт. HOST устанавливается в первое имя хоста, заданное роутером.

Если установлена общая транспортная опция home_directory, её значение используется для переменной окружения HOME. Иначе, домашний каталог может быть установлен роутером путём опции transport_home_directory, имеющей значением по умолчанию домашний каталог пользователя, если установлена check_local_user.

29.5. Частные опции для pipe

ИмяИспользование ТипЗначение по умолчанию
allow_commandspipestring list† не задана

Строка раскрывается, а затем интерпретируется как разделённый двоеточиями список допустимых команд. Если restrict_to_path не установлена, разрешены лишь команды, перечисленные в списке allow_commands. Они не должны быть абсолютными путями: опция path продолжает использоваться для относительных путей. Если restrict_to_path установлена с allow_commands, команда должна быть в списке allow_commands или именем без каких-либо слэшей в путях. Другими словами, если не установлена ни allow_commands, ни restrict_to_path, нет никаких ограничений на команды, но иначе разрешены лишь команды, допускаемые той или другой опциями. Например, если:
allow_commands = /usr/bin/vacation
и restrict_to_path не установлена, разрешена лишь команда /usr/bin/vacation. Опция allow_commands не может быть установлена, если установлена use_shell.
ИмяИспользование ТипЗначение по умолчанию
batch_idpipestring† не задана

Смотрите описание пакетной локальной доставки в разделе 25.
ИмяИспользование ТипЗначение по умолчанию
batch_maxpipeinteger 1

Эта опция ограничивает число адресов, которые могут быть обработаны в одной доставке. Смотрите описание пакетной локальной доставки в разделе 25.
ИмяИспользование ТипЗначение по умолчанию
check_stringpipestring не задана

Когда pipe пишет сообщение, начало каждой строки проверяется на совпадение с check_string, и если оно происходит, начальные совпавшие символы заменяются содержимым escape_string, если обе установлены. Значение check_string литеральная строка, а не регулярное выражение, и регистр букв имеет значение. Когда установлена use_bsmtp, содержимое check_string и escape_string приводится к значениям, которые оформлены протоколом экранирования SMTP. Любые настройки, сделанные в конфигурационном файле, игнорируются.
ИмяИспользование ТипЗначение по умолчанию
commandpipestring† не задана

Эта опция не должна быть установлена, когда pipe используется для доставки в каналы, полученные непосредственно от переназначения адресов. В других случаях опция должна быть установлена для предоставления команды, которая будет выполнена. Она не нуждается в абсолютном пути (смотрите ниже опцию path). Команда разделяется exim на отдельные параметры, и каждый аргумент отдельно раскрывается, как описано выше в разделе 29.3.
ИмяИспользование ТипЗначение по умолчанию
environmentpipestring† не задана

Эта опция используется для добавления дополнительных переменных к среде окружения, в которой выполняется команда (смотрите раздел 29.4 для получения списка значений по умолчанию). Ее значение строка, которая вначале раскрывается, а затем интерпретируется как список, разделённый двоеточиями, установок среды окружения в формате name=value.
ИмяИспользование ТипЗначение по умолчанию
escape_stringpipestring не задана

Смотрите выше опцию check_string.
ИмяИспользование ТипЗначение по умолчанию
freeze_exec_failpipeboolean ложь

Ошибка выполнения команды в транспорте pipe по умолчанию обрабатывается как любая другая ошибка при запуске команды. Однако, если установлена опция freeze_exec_fail, ошибка выполнения обрабатывается особым образом и вызывает заморозку сообщения вне зависимости от установки ignore_status.
ИмяИспользование ТипЗначение по умолчанию
freeze_signalpipeboolean ложь

Обычно, если процесс, выполненный командой в транспорте канала выходит по сигналу, посылают сообщение об отказе. Если freeze_signal будет установлена, то сообщение будет заморожено в очереди вместо этого.

ИмяИспользование ТипЗначение по умолчанию
ignore_statuspipeboolean ложь

Если эта опция истинна, статус, возвращаемый субпроцессом, запустившим команду, игнорируется, а exim ведёт себя так, как будто был возвращён ноль. Иначе ненулевой статус или завершение по сигналу вызывают ошибку из транспорта, если статус не одно из значений, перечисленных в temp_errors: они вызывают задержку доставки и дальнейшие, более поздние, попытки доставки.

Отметьте: Эта опция не касается таймаутов, которые не возвращают статус. Смотрите опцию timeout_defer для информации об обработке таймаутов.
ИмяИспользование ТипЗначение по умолчанию
log_defer_outputpipeboolean ложь

Если эта опция установлена, и статус, возвращаемый командой, один из кодов перечисленных в temp_errors (то есть, доставка была задержана), а ей был сгенерирован какой-либо вывод, его первая строка записывается в главный протокол.
ИмяИспользование ТипЗначение по умолчанию
log_fail_outputpipeboolean ложь

Если эта опция установлена, и команда возвращает какой-либо вывод, а также завершается с кодом возврата, не равным ни нулю, ни кодам, перечисленным в temp_errors (то есть, доставка неудачна), первая строка вывода записывается в главный протокол. Эта опция и log_output взаимоисключаемы. Лишь одна из них может быть установлена.
ИмяИспользование ТипЗначение по умолчанию
log_outputpipeboolean ложь

Если эта опция установлена, и команда возвращает какой-либо вывод, первая строка вывода записывается в главный протокол вне зависимости от возвращённого кода. Эта опция и log_fail_output взаимоисключаемы. Лишь одна из них может быть установлена.
ИмяИспользование ТипЗначение по умолчанию
max_outputpipeinteger 20K

Эта опция определяет максимальное количество вывода, который команда может сгенерировать на своём стандартном выводе и объединённом стандартном файле ошибок. Если лимит исчерпан, процесс, выполняющий команду, уничтожается. Это мера безопасности для поимки неудержимо растущих процессов. Ограничение применяется независимо от настроек опций контролирующих, что происходит с этим выводом (например, return_output). Из-за эффекта буферизации, объём вывода может немного превысить ограничение до того, как exim это заметит.
ИмяИспользование ТипЗначение по умолчанию
message_prefixpipestring† смотрите ниже

Заданная строка раскрывается и выводится в начале каждого сообщения. По умолчанию она не задана, если установлена опция use_bsmtp. Иначе она:
message_prefix = \
   From ${if def:return_path{$return_path}{MAILER-DAEMON}}\
   ${tod_bsdinbox}\n

Обычно это требуется для программы /usr/bin/vacation. Однако, она не должна присутствовать, если производится доставка на Cyrus IMAP server или локальному агенту доставки tmail. Префикс может быть запрещён путём установки:
message_prefix =

ИмяИспользование ТипЗначение по умолчанию
message_suffixpipestring† смотрите ниже

Заданная строка раскрывается и выводится в начале каждого сообщения. По умолчанию она не задана, если установлена опция use_bsmtp. Иначе она одна новая строка. Суффикс может быть запрещён путём установки:
message_suffix =

ИмяИспользование ТипЗначение по умолчанию
pathpipestring /bin:/usr/bin

Эта опция определяет строку, которая устанавливается в переменную окружения PATH для субпроцесса. Если опция command не приводит к абсолютному пути к имени, команда разыскивается в каталогах PATH обычным способом. Предупреждение: это не применяется к команде, заданной как транспортный фильтр.
ИмяИспользование ТипЗначение по умолчанию
permit_coredumppipeboolean ложь

Обычно Exim запрещает дампы памяти во время поставки. Если у Вас есть потребность получить дамп памяти команды канала, включите эту опцию. Это включает дамп памяти во время поставки, затрагивая сразу исполняемый файл Exim и выполненную команду канала. Рекомендуется, чтобы эта опция осталась выключенной, а включалась только после того как у Вас появилась потребность в этом, поскольку риск чрезмерного потребления ресурса может быть довольно высоким. Заметьте также, что двоичный модуль Exim как правило устанавливается как setuid, а большинство операционных систем запретит их дамп по умолчанию, таким образом, еще надо смотреть как это разрешить в Вашей ОС.

ИмяИспользование ТипЗначение по умолчанию
pipe_as_creatorpipeboolean ложь

Если не задана общая опция user, и эта опция истинна, процесс доставки запускается под uid, который был у exim при изначальном вызове для приёма сообщения. Если не установлен идентификатор группы (через общую опцию group), в силе gid, который был у exim при при изначальном вызове для приёма сообщения.
ИмяИспользование ТипЗначение по умолчанию
restrict_to_pathpipeboolean ложь

Когда эта опция установлена, любое имя команды, не перечисленное в allow_commands, не должно содержать каких бы то ни было слэшей. Команда ищется лишь в каталогах, перечисленных в опции path. Эта опция предназначена для случая, когда команда канала была сгенерирована из пользовательского файла .forward. Обычно это обрабатывается транспортом pipe, называемым address_pipe.
ИмяИспользование ТипЗначение по умолчанию
return_fail_outputpipeboolean ложь

Если эта опция установлена в истину, команда производит какой-либо вывод и завершается с кодом возврата, не равным нулю или не содержащимся в кодах, перечисленных в temp_errors (то есть, имеет место ошибка доставки), вывод возвращается в рикошете. Однако, если сообщение имеет пустого отправителя (оно само по себе рикошет), вывод команды отбрасывается. Эта опция и return_output взаимоисключаемы. Лишь одна из них может быть установлена.
ИмяИспользование ТипЗначение по умолчанию
return_outputpipeboolean ложь

Если эта опция установлена в истину, а команда производит какой-либо вывод, доставка считается неудачной вне зависмости от кода возврата, и вывод возвращается в рикошете. Иначе вывод просто игнорируется. Однако, если сообщение имеет пустого отправителя (оно само по себе рикошет), вывод команды всегда отбрасывается, вне зависимости от установки этой опции. Эта опция и return_fail_output взаимоисключаемы. Лишь одна из них может быть установлена.
ИмяИспользование ТипЗначение по умолчанию
temp_errorspipeboolean не задана

Эта опция содержит список разделённый двоеточиями или единственную звёздочку. Если опция ignore_status ложна, и return_output не задана, а команда выходит с ненулевым кодом, ошибка обрабатывается как временная, и доставка задерживается, если код возврата совпадает с одним из чисел, или если стоит звёздочка. Иначе, ненулевые коды возврата обрабтываются как постоянные ошибки. Значение по умолчанию содержит коды, заданные EX_TEMPFAIL и EX_CANTCREAT в sysexits.h. Если exim скомпилирован на системе, не задающей эти макросы, они принимают значения 75 и 73, соответственно.
ИмяИспользование ТипЗначение по умолчанию
timeoutpipetime 1h

Если команда не смогла завершится в течение этого времени, она уничтожена. Обычно это вызывает ошибку доставки (но посмотрите опцию timeout_defer). Нулевой интервал времени задаёт, что нет таймаута. Для гарантии, что любые созданные командой субпроцессы также уничтожены, exim делает начальный процесс лидером группы процессов, и по таймауту уничтожает всю группу процессов. Однако, это может быть обойдено, если один из процессов начинает новую группу процессов.
ИмяИспользование ТипЗначение по умолчанию
timeout_deferpipeboolean ложь

Таймаут в транспорте pipe, в команде, запускаемой транспортом или в ассоциированном с ним транспортном фильтре по умолчанию обрабатывается как жёсткая ошибка, и доставка неудачна. Однако, если timeout_defer установлена в истину, оба вида таймаута становятся временными, вызывая задержку доставки.
ИмяИспользование ТипЗначение по умолчанию
umaskpipeoctal integer 022

Эта опция определяет установку umask для субпроцесса, выполняющего команду.
ИмяИспользование ТипЗначение по умолчанию
use_bsmtppipeboolean ложь

Если эта опция установлена в истину, транспорт pipe пишет сообщения в формате пакетного SMTP с отправителем конверта и получателем (получателями), включенными как SMTP-команды. Если Вы хотите включить начальную команду HELO с каждым сообщением, можете сделать это путём установки опции message_prefix. Для получения дополнительных деталей о пакетном SMTP, смотрите раздел 44.10.
ИмяИспользование ТипЗначение по умолчанию
use_classresourcespipeboolean ложь

Эта опция доступна лишь в случае, если exim работает на FreeBSD, NetBSD или BSD/OS. Если она установлена в истину, функция setclassresources() используется для установки ограничений ресурсов, когда транспорт pipe производит доставку. Лимиты для uid, под которым работает канал, лолучаются из БД классов логинов /etc/login.conf.
ИмяИспользование ТипЗначение по умолчанию
use_crlfpipeboolean ложь

Эта опция заставляет завершатся строки двухсимвольной последовательностью CRLF (возврат каретки, новая строка) вместо одного символа перевода строки. В случае пакетного SMTP записанная в канал последовательность байтов представляет собой точное подобие того, что было бы послано в реальном SMTP-подключении.

Содержимое опций message_prefix и message_suffix пишется дословно, таким образом, они должны содержать свои символы возврата каретки, если они им необходимы. Так как значение по умолчанию для обоих (message_prefix и message_suffix) содержит один перевод строки, их значения должны быть изменены, чтобы они завершались \r\n, если задана опция use_crlf.

29.6. Использование внешнего (постороннего) агента локальной доставки

Транспорт pipe может использоваться для передачи всех сообщений, которым требуется локальная доставка, отдельному локальному агенту доставки, типа procmail. Когда это делается, нужно быть осторожным, чтобы гарантировать, что канал выполняется под соответствующими uid и gid. В некоторых конфигурациях требуется, чтобы это был uid, которому доверяет агент доставки, для предоставления корректного отправителя сообщения. Может потребоваться повторно пересобрать или переконфигурировать агент доставки таким образом, чтобы он доверял соответствующему пользователю. Далее приведен пример конфигурации транспорта и роутера для procmail:
# transport
procmail_pipe:
  driver = pipe
  command = /usr/local/bin/procmail -d $local_part
  return_path_add
  delivery_date_add
  envelope_to_add
  check_string = "From "
  escape_string = ">From "
  user = $local_part
  group = mail
# router
procmail:
  driver = accept
  check_local_user
  transport = procmail_pipe

В этом примере канал запускается как локальный пользователь, но с установленнной группой mail. Как альтернативу можно запускать канал под определённым пользователем, типа mail или exim, но в этом случае Вы должны принять меры, чтобы procmail доверял этому пользователю для предоставления корректного адреса отправителя. Если Вы не задаёте опцию group или user, команда канала запускается под локальным пользователем. Домашним каталогом будет домашний каталог пользователя.

Отметьте: команда, которая запускает транспорт pipe, НЕ начинается с
IFS=" "
как показано в документации на procmail, поскольку exim по умолчанию не использует shell для запуска команд канала. Следующий пример показывает транспорт и роутер для систем, где локальные доставки обрабатываются Cyrus IMAP server.
# transport
local_delivery_cyrus:
  driver = pipe
  command = /usr/cyrus/bin/deliver -m \
            ${substr_1:$local_part_suffix} -- $local_part
  user = cyrus
  group = mail
  return_output
  log_output
  message_prefix =
  message_suffix =
# router
local_user_cyrus:
  driver = accept
  check_local_user
  local_part_suffix = .*
  transport = local_delivery_cyrus

Отметьте, что не заданы message_prefix и message_suffix, а также на использование return_output для того, чтобы любой текст, записанный Cyrus, был возвращён отправителю.

Поиск

 

Найди своих коллег!