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


    Существуют некоторые обстоятельства, при которых exim автоматически переписывает домены в адресах. Два самых частых - когда адрес даётся без домена (называемый  неквалифицированным адресом (unqualified address)), или когда адрес содержит сокращённый домен, раскрываемый путём поиска в DNS.
   Дисквалифицированные адреса конверта принимаются лишь для локально переданных сообщений, или для сообщений, которые передаются с хостов, совпадающих с
sender_unqualified_hosts или recipient_unqualified_hosts , соответственно. Неполные адреса, в строках заголовков, квалифицируются, если они в локально переданных сообщениях, или сообщениях с хостов, которым разрешено посылать неквалифицированные адреса конверта. Иначе, неквалифицированные адреса в строках заголовков, ни квалифицированы, ни перезаписаны.
   Одна ситуция, в которой exim автоматически не перезаписывает домен, - когда его имя - CNAME запись в DNS. Старые RFC предлагают что такой домен домен должен быть перезаписан используя
каноническое имя, и некоторые MTA так и делают. Новые RFC не содержат этого предложения.

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

   Эта часть описывает правила перезаписи, которые могут быть использованы в основном разделе конфигурационного файла, и, также, в общей опции headers_rewrite , которая может быть установлена лишь для транспорта.
   Некоторые люди полагают, что сконфигурированная перезапись адресов - Смертный Грех. Другие полагают, что хизнь без этого - невозможна. Exim предоставляет средство; Вы не должны его использовать.
   Главные правила перезаписи, в строках заголовков, применяются лишь к тем заголовкам, которые были получены с сообщением, и, в случае транспортной перезаписи, тем, которые были добавлены системным фильтром. Таким образом, это применяется лишь к тем заголовкам, которые являются общими для всех копий сообщения. Строки заголовков, которые добавлены путём индивидуальных роутеров или транспортов (и, которые поэтому явялются специфическими для индивидуальных получателей адресов), не перезаписываются.
   Вообще, перезапись адресов от вашей системы или домена имеет немного легитимности (законности). Перезапись иных адресов должна быть сделана лишь с большой осторожностью и в особых обстоятельствах. Автор exim`a полагает, что перезапись должна использоваться расчётливо, и, главным образом, для
упорядочивания адресов в ваших собственных доменах. Хотя это и может использоваться как инструмент маршрутизации, это очень строго нерекомендуется.
   Есть два часто встречающихся обстоятельства, где используется перезапись, как иллюстрировано этими примерами:

  • Компания, чей домен - 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 . Она берёт адрес (который может быть полным адресом, в соответствии с RFC2822) как аргумент. Вывод - список как адрес был бы преобразован путём правил перезаписи для каждого различного места, в котором он мог бы появиться во входящем сообщении, т.е. для каждого различного заголовка, и для поля отправителя конверта, и поля получателя конверта. Например,

    
    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 , даны в в виде списка, разделённого двоеточиями. Каждый элемент в списке принимает такую же форму, как строка в главной конфигурации перезаписи (исключая, разумеется, что любые двоеточия должны быть удвоены).
       Формат исходных шаблонов, и строк замены описаны ниже. Каждый - завершается пустым пространством (пробелом), если он не находится в двойных кавычках, в этом случае, применяются обычные соглашения о квотировании (помещении в двойные кавычки, экранировке - прим. lissyara). Флаги - единственные символы, которые могут появляться в любом порядке. Пробелы и символы табуляции, между ними, игнорируются.
       Для каждого адреса, который, потенциально, может быть перезаписан, правила сканируются по порядку, и замены для адресов из ранних правил, могут быть самостоятельно заменены более поздними правилами (но, смотрите флаги
    q и R).
       Порядок в котором перезаписываются адреса - не задан, может измениться между релизами, и на него нельзя положиться, с одним исключением: когда сообщение получено, отправитель конверта всегда перезаписан первым, до перезаписи любых строк заголовков. например, строка замены, для перезаписи адреса в
    To: , не должна предполагать, что адрес сообщения в From: был (или небыл) уже перезаписан. Однако, перезапись From: может предположить, что отправитель конверта уже был перезаписан.
       Переменные
    $local_part и $domain могут быть использованы в строке замены, для ссылки на перезаписываемый адрес. Отметтьте, что управляемая поиском перезапись не может быть сделана правилом в форме

    *@*   ${lookup ...
    
    
    

    где ключ поиска использует $1 и $2 , или $local_part и $domain для ссылки на перезаписываемый адрес.

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

       Исходные шаблоны в правилах перезаписи - это любой элемент, который может появиться в списке адресов (смотрите раздел 10.18). Фактически, он обрабатывается как одноэлементный список адресов, что означает, что он раскрывается до проверки адресов. Как всегда, если в шаблоне вы используете регулярное выражение, вы должны позаботиться о экранировке символов доллара и обратного слэша, или использовать средство \N, для подавления раскрытия строки в пределах регулярного выражения.
       Домены, в паттернах (шаблонах, или образцах - прим. lissyara), должны быть даны в строчных (маленьких) буквах. Локальные части, в паттернах, чувствительны к регистру. Если вы хотите сделать регистронезависисимое сравнение локальных частей, вы должны использовать регулярное выражение начинающееся с
    ^(?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: .
       Если заменяющая строка - не единственная звёздочка, она раскрывается, и должна привести к полностю квалифицированному адресу (с доменной частью - прим. lissyara). В пределах раскрытия, переменные
    $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, и до любых других процессов; даже до проврки синтаксиса. Паттерн обязан быть регулярным выражением, и он сравнивается с любыми данными для команд, включая любые соседние угловые скобки.
       Форма правила перезаписи позволяет обработать адреса, которые не соответствуют RFC2821 и RFC2822 (например, адреса с восклицательными знаками, в пактном SMTP-вводе). Поскольку ввод не обязан быть синтаксически правильным адресом, переменные
    $local_part и $domain недоступны в процессе раскрытия строки. Результат перезаписи замещает оригинальный адрес в командах MAIL и RCPT.

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

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

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

    на

    
    From: Ford Prefect <prefectf@hitch.fict.example>
    
    
    

       Иногда, есть потребность изменить весь элемент адреса, и это может быть сделано путём добавления флага w к правилу. Если он установлен для правила, вызывающего перезапись адреса в строке заголовка, заменяется весь адрес, а не только рабочая часть. Замена должна быть полным адресом согласно RFC2822, включая угловые скобки, если есть необходимость. Если текст вне угловых скобок, содержит символ чьё значение более 126 или менее 32 (исключая табуляцию), текст кодируется согласно RFC2047. Кодировка берётся из 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 не обрабатывает адреса в форме
    адресов с восклицательными знаками (bang paths - хрен его знает что это. - прим. lissyara). Если он видит такой адрес, он обрабатывает его как неквалифицированную локальную часть, которую он квалифицирует с локальным квалификационным доменом (если источник сообщения локальный, или если удалённому хосту разрешается посылать неквалифицированные адреса). Перезапись может, иногда, использоваться для обработки простых адресов с восклицательным знаком, с фиксированным числом компонентов. Например, правило

    \N^([^!]+)!(.*)@your.domain.example$\N   $2@$1
    
    
    

    перезаписывает двухкомпонентный адрес с восклицательным знаком host.name!user , как доменный адрес user@host.name . Однако, тут замешана безопасность, в использовании этого как глобального перезаписывающего правила, для адресов конверта. Это может предоставить чёрный ход для использования вашей системы как релея, поскольку входящие адреса кажутся локальными. Если адреса с восклицательными знаками получены через SMTP, более безопасно использовать флаг S, для их перезаписи при получении, так, чтобы проверка релея могла быть сделана на перезаписанных адресах.




    =============
    Автор перевода: lissyara, оригинал: http://www.lissyara.su/?id=1200