Интерпретация и написание правил перезаписи
Возможно, наиболее мощное свойство sendmail – правила перезаписи. Они используются sendmail, чтобы определить, как обработать полученное сообщение почты. sendmail передает адреса из заголовка письма через совокупности правил, названные наборами(rulesets). Правила преобразуют адреса. Каждое правило имеет левую и правую стороны, отделяемые по крайней мере одним символом табуляции. Когда sendmail обрабатывает почту, он просматривает правила в поисках соответствия на левой стороне. Если адрес соответствует левой стороне правила, он будет заменен правой стороной и обработан снова.
sendmail.cf: команды R и S
В файле sendmail.cf наборы определяются, используя команды Sn, где n определяет текущий набор.
Правила непосредственно появляются в командах R. Поскольку каждая команда R читается, это правило будет добавлено к текущему набору. Если вы имеете дело только с файлом sendmail.mc, Вы не должны заботиться о командах S, поскольку макрокоманды будут формировать их для Вас автоматом. Но нужно самому
кодировать правила команд R.
Набор правил в sendmail выглядит так:
Sn Rlhs rhs Rlhs2 rhs2
Полезные макросы
sendmail использует ряд стандартных макросов. Наиболее полезные из них применительно к написанию правил:
- $j
- Полное доменное имя хоста.
- $w
- Компонент hostname из записи FQDN.
- $m
- Компонент domain name записи FQDN.
Эти макросы можно включать в правила. Наша конфигурация использует макрос $m.
Левая сторона
В левой стороне правила Вы определяете шаблон, который будет соответствовать адресу или группе адресов, которые нужно трансформировать. Большинство символов сравниваются буквально, но есть ряд символов, которые имеют специальное значение. Они перечислены в следующем списке:
- $@
- Соответствует строго нулю элементов.
- $*
- Соответствует нулю или большему числу элементов.
- $+
- Соответствует одному или большему числу элементов.
- $-
- Соответствует строго одному элементу.
- $=x
- Соответствует любой фразе в классе x
- $x
- Соответствует любому слову НЕ в классе x
Элемент представляет собой строку символов, разграниченных пробелами. Когда правило соответствует адресу, текст, связанный с каждым из элементов в шаблоне, будет назначен специальной переменной, которую мы используем в правой стороне. Единственное исключение: $@, который не соответствует никаким элементам и, следовательно, не будет создавать текст, который нужно использовать на правой стороне.
Правая сторона
Когда левая сторона правила соответствует адресу, первоначальный текст будет удален и заменен правой стороной правила. Все элементы в правой стороне не будут скопированы буквально, если они начинаются с символа доллара. Как и для левой стороны несколько метасимволов могут использоваться на правой стороне. Они приведены в следующем списке:
- $n
- Этот метасимвол будет заменен на n-ое выражение с левой стороны.
- $[name$]
- Этот метасимвол превратит hostname в каноническое имя.
- $(map key $@arguments $:default $)
- Это более общая форма поисковой таблицы. Вывод: результат поиска ключа в таблице map с использованием параметров arguments. Здесь map может быть любой из поддерживаемых sendmail карт, таких как virtusertable, которые я опишу немного позже. Если поиск провалился, будет использовано значение default. Если оно не задано, ничего не изменится, а запись key будет выведена так, как пришла.
- $>n
- Анализирует остаток строки через набор правил n. Вывод этого набора будет выдан как результат текущего правила. Это позволяет правилам вызывать другой набор.
- $#mailer
- Этот метасимвол заставляет набор правил остановить обработку и определяет транспорт, который должен использоваться для передачи данного сообщения на следующем шаге доставки. Этот метасимвол должен быть вызван только из набора 0 или из его подпрограмм. Это конечная стадия синтаксического анализа адреса.
- $@host
- Этот метасимвол определяет хост, которому это сообщение будет послано. Если это локальный хост, имя может быть опущено. Параметр host может быть разделенным двоеточияим список хостов-адресатов, которые будут последовательно перебраны для доставки данного письма.
- $:user
- Определяет целевого пользователя для сообщения почты.
Правило обычно обрабатывается до тех пор, пока не прекратится совпадение. Тогда запускается следующее правило. Это можно поменять указанием на правой стороне одного из двух специальных метасимволов:
- $@
- Этот метасимвол заставляет набор вернуть остаток правой стороны как значение. Никакие другие правила в наборе не обрабатываются.
- $:
- Заставляет это правило завершаться немедленно, но остаток текущего набора будет обработан.
Пример простого правила
Рассмотрим следующее правило левой стороны:
$* < $+ >
Это правило соответствует нулю или большему количеству элементов, сопровождаемых символом <, за которым идет один или большее число элементов и символ > после них.
Если это правило применить к postmaster@example.com или к Head Postmaster < >, соответствия не будет. В первом случае потому, что нет символа <. Во втором из-за того, что $+ соответствует одному или большему числу элементов, а в данном случае никаких элементов между символами <> нет. В любом случае при несоответствии правила, правая сторона не используется.
Если правило применить к Head Postmaster < postmaster@example.com >, то оно сработает, и на правой стороне $1 заменится на Head Postmaster, а $2 на postmaster@example.com.
Если правило применить к < postmaster@example.com > оно сработает потому, что $* соответствует нулю или более элементам, а на правой стороне $1 заменится на пустую строку.
Семантика наборов правил
Каждый из наборов sendmail выполняет свою задачу в обработке почты. Когда Вы пишете правила, важно понять, что каждый из наборов должен делать. Рассмотрим все наборы, которые можно менять через скрипты m4:
- LOCAL_RULE_3
- Набор 3 ответственен за преобразование адреса в произвольном формате в общий формат, который sendmail будет обрабатывать. Ожидаемый выходной формат:
local-part@host-domain-spec.
Набор правил 3 должен поместить имя хоста преобразованного адреса в символы < и >, чтобы сделать проще последующий синтаксический анализ. Набор 3 применяется перед тем, как sendmail сделает любую другую обработку адреса. Так что именно здесь нужно задавать преобразование адресов в случае использования sendmail как почтового шлюза для сети с нестандартными адресами почты. Используйте макрос LOCAL_RULE_3.
- LOCAL_RULE_0 и LOCAL_NET_CONFIG
- Набор 0 применяется к адресам получателя после набора 3. Макрос LOCAL_NET_CONFIG управляет правилами для вставки в нижнюю половину набора 0. Набор 0 выполнит доставку сообщения получателю. Он должен установить три параметра: транспорт, хост и получатель. Правила будут помещены перед любым определением интеллектуального хоста. Этим способом обрабатываются все smtp-соединения для пользователей LAN в примере.
- LOCAL_RULE_1 и LOCAL_RULE_2
- Набор 1 применяется ко всем адресам отправителей, а набор 2 ко всем адресам получателей. Обычно они пустые.
Интерпретация правил в нашем примере
Теперь мы сможем понять, как это работает. Давайте возьмем пример.
Правило из example.com.uucpsmtp.m4
LOCAL_NET_CONFIG # This rule ensures that all local mail is delivered using the # smtp transport, everything else will go via the smart host. R$* < @ $* .$m. > $* $#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3
Известно, что макрос LOCAL_NET_CONFIG вызовет правило, которое будет вставлено где-нибудь близко к концу набора 0, но перед любым определением интеллектуального хоста. Также известно, что набор 0 последний. Здесь должны быть три параметра: транспорт, хост и пользователь.
Две строки комментария можно игнорировать: они все равно ничего не делают. Правило задано строкой, начинающейся с R. Мы знаем, что R является командой sendmail и добавляет это правило к текущему набору. В данном случае это набор 0. Давайте рассматривать левую и правую стороны.
Левая сторона правила выглядит так: $* < @ $* .$m. > $*.
Набор 0 ищет символы < и > потому, что они должны прийти из набора 3. Набор 3 преобразует адреса в общую форму и делает синтаксический анализ проще, он также помещает часть host адреса почты в символы <>.
Это правило соответствует любому адресу почты, который напоминает: 'ToUser < @ example.com. > Some Text'. То есть, это соответствует почте для любого пользователя на любом компьютере в нашем домене.
Помните, что текст, согласованный метасимволами на левой стороне правила, будет назначен макроопределениям для использования на правой стороне. В примере первое определение $* соответствует тексту от начала адреса до символа <. Весь этот текст назначается переменной $1 для работы с ним на правой стороне. Второе определение $* назначено $2, а последнее к $3.
Мы теперь имеем достаточно данных, чтобы понять левую сторону. Эти правила соответствуют почте для любого пользователя в любом компьютере в нашем домене. Имя пользователя будет в $1, имя хоста в $2, любой сопроводительный текст в $3. Затем вызывается правая сторона, чтобы обработать эти данные.
Давайте теперь рассматривать то, что мы ожидаем видеть в выводе. Правая сторона нашего правила выглядит так:
$#smtp $@ $2.$m. $: $1 < @ $2.$m. > $3.
Когда правая сторона нашего набора обрабатывается, каждый из метасимволов интерпретируется, и соответствующие замены будут сделаны. Метасимвол $# заставляет это правило использовать указанный транспорт, в данном случае smtp. Метасимвол $@ задает целевой хост. В этом примере целевой компьютер определен как $2.$m., что является полным доменным именем в нашем домене, то есть FQDN, созданный из компонента hostname, назначенного $2 левой стороной, с добавлением доменного имени (.$m.). Метасимвол $: определяет целевого пользователя, который тоже задан на левой стороне правила и хранится в $1. Мы сохраняем содержание секции <> и любой сопроводительный текст, используя данные из левой стороны. Так как это правило обращается к конкретному транспорту, письмо будет послано для доставки соответствующему транспортному агенту. В нашем примере оно будет передано адресату через протокол SMTP.