RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
YandexMoney: 
41001198119846 
E-gold:
5128052

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

31. Перезапись адресов

Существуют некоторые обстоятельства, при которых exim автоматически переписывает домены в адресах. Два самых частых: когда адрес даётся без домена (называемый неквалифицированным адресом, unqualified address) или когда адрес содержит сокращённый домен, раскрываемый путём поиска в DNS.

Неквалифицированные адреса конверта принимаются лишь для локально переданных сообщений или для сообщений, которые передаются с хостов, совпадающих с sender_unqualified_hosts или recipient_unqualified_hosts соответственно. Неполные адреса в строках заголовков квалифицируются, если они в локально переданных сообщениях, или сообщениях с хостов, которым разрешено посылать неквалифицированные адреса конверта. Иначе, неквалифицированные адреса в строках заголовков ни квалифицированы, ни перезаписаны.

Одна ситуция, в которой exim автоматически не перезаписывает домен: когда его имя CNAME-запись в DNS. Старые RFC предлагают, что такой домен домен должен быть перезаписан используя каноническое имя, и некоторые MTA так и делают. Новые RFC не содержат этого предложения.

31.1. Явно сконфигурированная перезапись адресов

Эта часть описывает правила перезаписи, которые могут быть использованы в основном разделе конфигурационного файла и также в общей опции headers_rewrite, которая может быть установлена лишь для транспорта. Некоторые люди полагают, что сконфигурированная перезапись адресов кошмар. Другие полагают, что работа без этого невозможна. Exim предоставляет средство, Вы не обязаны его использовать.

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

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

Есть два часто встречающихся обстоятельства, где используется перезапись, как иллюстрировано этими примерами:

  • Компания, чей домен hitch.fict.example, имеет множество хостов, которые обмениваются почтой друг с другом за файрволлом, но есть лишь один шлюз во внешний мир. Шлюз переписывает *.hitch.fict.example как hitch.fict.example, когда посылает почту наружу.
  • Хост перезаписывает локальные части собственных пользователей так, чтобы, например, fp42@hitch.fict.example стал Ford.Prefect@hitch.fict.example.

31.2. Когда происходит перезапись?

Конфигурирование перезаписи адресов может иметь место на нескольких различных стадиях обработки сообщения. В начале ACL для MAIL, отправитель адреса, может быть перезаписан путём специального SMTP-правила перезаписи (смотрите раздел 31.9), но никаких обычных правил перезаписи не применяется. Однако, если адрес отправителя проверен в ACL, он перезаписан перед проверкой, и остаётся перезаписанным после неё. Последующее значение $sender_address уже перезаписанный адрес. Также это применяется, если проверка отправителя происходит в RCPT ACL. Иначе, когда адрес отправителя не проверен, он перезаписывается сразу после получения строк заголовка.

Точно также, в начале ACL для RCPT, текущий адрес получателя может быть перезаписан во время SMTP путём специального правила, но никаких обычных правил перезаписи не применяется. Однако, когда проверяется получатель, поведение отличается от проверки адреса отправителя. Адрес перезаписан для проверки, но на этой стадии перезапись не запоминается. Значения $local_part и $domain после проверки всегда те же самые, что и до неё (то есть, они содержат неперезаписанный, исключая перезапись во время SMTP, адрес).

Как только строки заголовков были получены, все адреса получателей конверта перезаписаны насовсем, и перезапись применяется к адресам в строках заголовков (если это сконфигурировано). Это происходит до добавления любых строк заголовков, которые были заданы в MAIL или RCPT ACL, до DATA ACL и выполнения функции local_scan().

Когда адрес роутится, для доставки или проверки к дочерним адресам, сгенерированным перенаправлением, перезапись применяется немедленно, если на роутере не установлена опция no_rewrite.

В транспортное время дополнительная перезапись адресов в строках заголовков может быть задана путём установки в транспорте общей опции headers_rewrite. Эта опция содержит правила, которые идентичны по форме правилам в секции перезаписи конфигурационного файла. Они применяются к оригинальным строкам заголовков и любым добавленным ACL или системным фильтром. Они не применяются к строкам заголовков, которые были добавлены роутерами или транспортами.

Исходящий отправитель конверта может быть перезаписан при помощи транспортной опции return_path. Однако, невозможно переписать получателей конверта в транспортное время.

31.3. Тестирование правил перезаписи, применяемых на входе

Входная конфигурация перезаписи появляется в части рабочего конфигурационного файла, озаглавленная как begin rewrite. Она может быть протестирована путём опции командной строки -brw. Она берёт адрес (который может быть полным адресом в соответствии с RFC 2822) как аргумент. Вывод: список того, как адрес был бы преобразован путём правил перезаписи для каждого различного места, в котором он мог бы появиться во входящем сообщении, то есть, для каждого различного заголовка, для поля отправителя конверта и поля получателя конверта. Например:
exim -brw ph10@exim.workshop.example
может привети к такому выводу:
sender: Philip.Hazel@exim.workshop.example
from: Philip.Hazel@exim.workshop.example
to: ph10@exim.workshop.example
cc: ph10@exim.workshop.example
bcc: ph10@exim.workshop.example
reply-to: Philip.Hazel@exim.workshop.example
env-from: Philip.Hazel@exim.workshop.example
env-to: ph10@exim.workshop.example
который показывает, что перезапись была установлена для этого адреса, когда он используется в любых исходных полях, но не когда он появляется как адрес получателя. В настоящее время нет никакого альтернативного способа протестировать правила перезаписи, установленные для специфического транспорта.

31.4. Правила перезаписи

Секция перезаписи в конфигурационном файле содержит строки правил перезаписи в форме:

source pattern   replacement   flags

Правила перезаписи, которые заданы для общей транспортной опции headers_rewrite, даны в виде списка, разделённого двоеточиями. Каждый элемент в списке принимает такую же форму, как строка в главной конфигурации перезаписи (исключая, разумеется, что любые двоеточия должны быть удвоены).

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

Для каждого адреса, который, потенциально, может быть перезаписан, правила сканируются по порядку, и замены для адресов из ранних правил, могут быть самостоятельно заменены более поздними правилами (но смотрите флаги q и R).

Порядок в котором перезаписываются адреса не задан, может измениться между релизами, и на него нельзя положиться, с одним исключением: когда сообщение получено, отправитель конверта всегда перезаписан первым, до перезаписи любых строк заголовков. Например, строка замены для перезаписи адреса в To:, не должна предполагать, что адрес сообщения в From: был (или не был) уже перезаписан. Однако, перезапись From: может предположить, что отправитель конверта уже был перезаписан. Переменные $local_part и $domain могут быть использованы в строке замены для ссылки на перезаписываемый адрес. Отметьте, что управляемая поиском перезапись не может быть сделана правилом в форме:
*@*   ${lookup ...
где ключ поиска использует $1 и $2, или $local_part и $domain для ссылки на перезаписываемый адрес.

31.5. Шаблоны перезаписи

Исходные шаблоны в правилах перезаписи это любой элемент, который может появиться в списке адресов (смотрите раздел 10.18). Фактически, он обрабатывается как одноэлементный список адресов, что означает, что он раскрывается до проверки адресов. Как всегда, если в шаблоне Вы используете регулярное выражение, Вы должны позаботиться об экранировке символов доллара и обратного слэша или использовать средство \N, для подавления раскрытия строки в пределах регулярного выражения.

Домены в шаблонах должны быть даны в строчных (маленьких) буквах. Локальные части в шаблонах чувствительны к регистру. Если Вы хотите сделать регистронезависимое сравнение локальных частей, Вы должны использовать регулярное выражение, начинающееся с ^(?i).

После совпадения числовые переменные $1, $2 и т. д. могут быть установлены, в зависимости от произошедшего типа соответствия. Это может использоваться в строках замены для вставки части входящего адреса. $0 всегда совпадает с полным входящим адресом. Когда используется регулярное выражение, числовые переменные установлены из его подвыражений. Для других типов шаблонов они устанавливаются следующим образом:

  • Если локальная часть или домен начинаются со звёздочки, числовые переменные ссылаются на строки символов, совпадающие со звёздочками, с $1 ассоциированной с первой звёздочкой, $2 со второй, если она представлена. Например, шаблон
    *queen@*.fict.example
    
    сравнивается с адресом hearts-queen@wonderland.fict.example, тогда
    $0 = hearts-queen@wonderland.fict.example
    $1 = hearts
    $2 = wonderland
    

    Отметьте, что если локальная часть не начинается со звёздочки, но домен начинается, тогда $1 будет содержать совпавшую часть домена.

  • Если доменная часть шаблона частичный поиск, совпавшие и фиксированные части домена помещаются в следующие доступные числовые переменные. Предположим, например, что адрес foo@bar.baz.example обрабатывается по правилу перезаписи в форме
    *@partial-dbm;/some/dbm/file    replacement string
    
    а ключ в файле соответствует домену в форме *.baz.example. Тогда:
    $1 = foo
    $2 = bar
    $3 = baz.example
    

Если адрес foo@bar.baz.example находится, он совпадает с тем же вхождением подстановочного знака, и в случае $2 устанавливается в пустую строку, но $3 всё ещё совпадает с baz.example. Если неподстановочный ключ совпадает с частичным поиском, $2 снова устанавливается в пустую строку, и $3 устанавливается в весь домен. Для нечастичных поисков поисков домена никакие числовые переменные не заданы.

31.6. Перезапись замен

Если строка замены для правила единственная звёздочка, адрес, который совпадает с шаблоном, и флаги не перезаписываются, и никакие последующие правила перезаписи не просматриваются. Например:
hatta@lookingglass.fict.example  *  f
определяет, что hatta@lookingglass.fict.example никогда не будет перезаписан в заголовках From:. Если заменяющая строка не единственная звёздочка, она раскрывается и должна привести к полностю квалифицированному адресу (с доменной частью). В пределах раскрытия переменные $local_part и $domain ссылаются на перезаписываемый адрес. Любые буквы, которые они содержат, сохраняют оригинальный регистр: они не преобразуются в нижний. Числовые переменные установлены согласно типу шаблона, совпадающего с адресом, как описано выше. Если раскрытие принудительно неудачно, путём присутствия fail в условном элементе или элементе поиска, перезапись путём текущего правила оставлена, но последующие правила могут вступить в силу. Любые другие ошибки раскрытия вызывают пропуск всей операции перезаписи, и вход пишется в протокол сбоев.

31.7. Флаги перезаписи

Есть три различных вида флагов, которые могут появляться в правилах перезаписи:

  • Флаги, которые определяют, какой заголовок и адрес конверта перезаписывать: E, F, T, b, c, f, h, r, s, t.
  • Флаг, который определяет перезапись во время SMTP: S.
  • Флаги, которые контролируют процесс перезаписи: Q, q, R, w. Для правил являющихся частью общей транспортной опции headers_rewrite, E, F, T и S не разрешены.

31.8. Флаги, определяющие какие заголовки и адрес конверта перезаписывать

Если нет ни одного из следующих флагов, ни флага S (смотрите раздел 31.9), главное правило перезаписи применяется ко всем заголовкам, полям отправителя и получателя конверта, тогда как правило перезаписи в транспортное время, применяется лишь ко всем заголовкам. Иначе, правило перезаписи пропускается, если не обрабатываются релевантные адреса.
флагчто перезаписывается
Eвсе поля конверта
Fполе From в конверте
Tполе To в конверте
bзаголовок Bcc:
cзаголовок Cc:
fзаголовок From:
hвсе заголовки
rзаголовок Reply-To:
sзаголовок Sender:
tзаголовок To:

Вам надо быть осторожным при перезаписи заголовков Sender: и ограничить ее известными специальными случаями в Ваших доменах.

31.9. Флаг перезаписи во время SMTP

Флаг перезаписи S определяет перезапись входящих адресов конверта во время SMTP, как только адрес получен в команде MAIL или RCPT, и до любых других процессов, даже до проверки синтаксиса. Шаблон обязан быть регулярным выражением, он сравнивается с любыми данными для команд, включая любые соседние угловые скобки.

Форма правила перезаписи позволяет обработать адреса, которые не соответствуют RFC 2821 и RFC 2822 (например, адреса с восклицательными знаками в пактном SMTP-вводе). Поскольку ввод не обязан быть синтаксически правильным адресом, переменные $local_part и $domain недоступны в процессе раскрытия строки. Результат перезаписи замещает оригинальный адрес в командах MAIL и RCPT.

31.10. Флаги контролирующие процесс перезаписи

Есть четыре флага, которые контролируют работу процесса перезаписи. Они вступают в силу лишь, когда правило вызвано, то есть, когда адрес корректного типа (совпадает с флагами) и соответствуют шаблону:

  • Если в правиле установлен флаг Q, перезаписанному адресу разрешается быть неквалифицированной локальной частью. Она квалифицируется с qualify_recipient. В отсутствии Q перезаписанный адрес всегда должен включать домен.
  • Если в правиле установлен флаг q, никакие дальнейшие правила перезаписи не рассматриваются, даже если не было фактической перезаписи, поскольку в раскрытии присутствовало fail. Флаг q неэффективен, если адрес неверного типа (не соответствует флагам) или не совпадает с шаблоном.
  • Флаг R вызывает повторное применение успешного правила перезаписи к новому адресу до десяти раз. Это может быть скомбинировано с флагом q для прекращения перезаписи, как только будет несоответствие (после по крайней мере одной успешной перезаписи).
  • Когда адрес в заголовке перезаписан, перезапись обычно применяется лишь к рабочей части адреса, с оставленными неизменными любыми комментариями и фразой RFC 2822. Например, перезапись может изменить
    From: Ford Prefect <fp42@restaurant.hitch.fict.example>
    
    на
    From: Ford Prefect <prefectf@hitch.fict.example>
    

Иногда есть потребность изменить весь элемент адреса, и это может быть сделано путём добавления флага w к правилу. Если он установлен для правила, вызывающего перезапись адреса в строке заголовка, заменяется весь адрес, а не только рабочая часть. Замена должна быть полным адресом согласно RFC 2822, включая угловые скобки, если есть необходимость. Если текст вне угловых скобок содержит символ, чьё значение более 126 или менее 32 (исключая табуляцию), текст кодируется согласно RFC 2047. Кодировка берётся из headers_charset, значение по умолчанию которой ISO-8859-1. Когда флаг w установлен для правила перезаписи адреса конверта, отбрасывается всё, кроме рабочей части.

31.11. Примеры перезаписи

Вот пример двух обычных образцов перезаписи:
*@*.hitch.fict.example   $1@hitch.fict.example
*@hitch.fict.example   ${lookup{$1}dbm{/etc/realnames} \
                       {$value}fail}@hitch.fict.example bctfrF

Отметьте, что использование fail в поиске во втором правиле вызывает принудительную неудачу в случае безуспешного поиска. В этом контексте это имеет эффект оставления оригинального адреса неизменным, но exim продолжает рассмотрение последующих правил, если таковые имеются, поскольку в этом правиле не присутстсвует флаг q. Альтернативой для fail могла бы быть явная вставка $1, которая вызвала бы перезапись адреса прежним, за счёт маленького снижения скорости обработки. Непредоставление любого из них является ошибкой, так как перезаписанный адрес вообще не содержал бы локальной части.

Первый пример заменяет домен вышестоящим, более общим доменом. Возможно, это нежелательно для некоторых локальных частей. Если правило
root@*.hitch.fict.example  *
было вставлено до первого правила, перезапись будет подавлена для локальной части root в любом домене, заканчивающемся на hitch.fict.example.

Перезапись может быть сделана условной в ряде тестов путём использования ${if в элементе раскрытия. Например, для применения правил перезаписи лишь для сообщений, который созданы вне локального хоста:
*@*.hitch.fict.example  "${if !eq {$sender_host_address}{} \
   {$1@hitch.fict.example}fail}"

Строка замены в этом примере помещена в кавычки, поскольку она содержит пустое пространство. Exim не обрабатывает адреса в форме адресов с восклицательными знаками. Если он видит такой адрес, он обрабатывает его как неквалифицированную локальную часть, которую он квалифицирует с локальным квалификационным доменом (если источник сообщения локальный, или если удалённому хосту разрешается посылать неквалифицированные адреса). Перезапись может иногда использоваться для обработки простых адресов с восклицательным знаком с фиксированным числом компонентов. Например, правило
\N^([^!]+)!(.*)@your.domain.example$\N   $2@$1
перезаписывает двухкомпонентный адрес с восклицательным знаком host.name!user как доменный адрес user@host.name. Однако, тут замешана безопасность, в использовании этого как глобального перезаписывающего правила для адресов конверта. Это может предоставить чёрный ход для использования Вашей системы как релея, поскольку входящие адреса кажутся локальными. Если адреса с восклицательными знаками получены через SMTP, более безопасно использовать флаг S для их перезаписи при получении так, чтобы проверка релея могла быть сделана на перезаписанных адресах.

Поиск

 

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