Обзор поисковых таблиц Postfix

Содержание

В этом документе рассматриваются следующие темы:

Модель таблиц поиска Postfix

Postfix использует таблицы поиска для хранения и поиска информации в целях выполнения контроля доступа, перезаписи адресов и даже для фильтрации содержимого. Все таблицы поиска Postfix определяются как "type:table", где тип "type" — один из типов баз данных, описанных в разделе "Типы поисковых таблиц Postfix" этого документа, а "table" — имя таблицы поиска. В документации Postfix термины "база данных" и "таблица поиска" используются как синонимы.

Примеры таблиц поиска, часто встречающиеся в документации Postfix:

/etc/postfix/main.cf:
    alias_maps = hash:/etc/postfix/aliases            (локальные псевдонимы)
    header_checks = regexp:/etc/postfix/header_checks (фильтрация контента)
    transport_maps = hash:/etc/postfix/transport      (таблица маршрутизации)
    virtual_alias_maps = hash:/etc/postfix/virtual    (перезапись адресов)

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

Преимущества интерфейса запросов (ключ, значение) Postfix:

Отличие списков и таблиц в Postfix

Большинство поисковых таблиц Postfix используются для поиска и извлечения информации. Например, перезапись адресов (строка поиска представляет собой старый адрес, а результат — новый адрес) или контроль доступа (строка поиска представляет собой клиента, отправителя или получателя, а результат — некоторое действие, такое как "reject").

Однако в некоторых случаях Postfix требуется знать лишь факт существования ключа поиска. Поскольку результирующее значение в этих случаях не используется, допустимо возвращать любое непустое значение. Примерами подобных поисков могут служить параметры local_recipient_maps (определяющий, для каких локальных получателей Postfix принимает почту из сети), mydestination (определяющий, для каких доменов Postfix доставляет почту локально) или mynetworks (определяющий IP-адреса доверенных клиентов или клиентских сетей). Технически они являются списками, а не таблицами. Несмотря на указанное отличие, списки Postfix описаны здесь же, поскольку они используют ту же базовую инфраструктуру, что и таблицы поиска Postfix.

Подготовка Postfix для LDAP или SQL-поисков

LDAP и SQL — сложные системы. Пытаться настроить одновременно и Postfix, и LDAP или SQL — определённо не лучшая идея. Вы можете сэкономить кучу времени, настроив для начала взаимодействие Postfix с локальными файлами, такими как Berkeley DB. Сюрпризы при работе с локальными файлами практически исключены, кроме того, они легко поддаются отладке с помощью команды postmap(1):

% postmap -q info@example.com hash:/etc/postfix/virtual

После того, как вы добились корректной работы с локальными файлами, можно заменить поиски в локальных файлах на LDAP или SQL-поиски, следуя инструкциям из man-страниц ldap_table(5), mysql_table(5), pgsql_table(5) или sqlite_table(5). Завершив настройки, вам снова следует провести тестирование с помощью команды postmap(1), чтобы убедиться, что поиски в базе данных дают аналогичные результаты:

% postmap -q info@example.com ldap:/etc/postfix/virtual.cf 

Обязательно выполните все запросы частичных почтовых адресов или родительских доменов, сведения о которых приводятся в разделах "Порядок поиска в таблице" соответствующих man-страниц access(5), canonical(5), virtual(5), transport(5), либо в описаниях параметров конфигурации, таких как mynetworks, relay_domains, parent_domain_matches_subdomains.

Обслуживание файлов поисковых таблиц Postfix

При внесении изменений в базу данных во время работы почтовой системы, желательно, чтобы Postfix не производил чтения информации во время её изменения. Также было бы замечательно, если при изменении базы данных не требовалось бы выполнять "postfix reload" для того, чтобы заставить Postfix принять новую информацию. Каждый раз, когда вы выполняете "postfix reload", производительность Postfix резко падает.

Безопасное обновление файлов Berkeley DB

Postfix использует блокировку файлов для предотвращения конфликтов доступа при обновлении файлов Berkeley DB или других локальных баз данных. Раньше это было безопасно, но по мере того, как Berkeley DB стала использовать более агрессивное кеширование, блокировки файлов может оказаться недостаточно.

Кроме того, блокировка файлов не предотвратит проблем, если обновление завершится неудачно из-за переполнения диска или что-то ещё приведёт к сбою обновления базы данных. В частности, команды, postmap(1) или postalias(1) перезаписывают существующие файлы. Если в ходе процесса перезаписи произойдёт сбой, то у вас не останется работающей версии базы данных, и Postfix перестанет работать. Для баз данных типа CDB, доступных с Postfix 2.2 и более новыми версиями, это не проблема: CDB создаёт новый файл, а после успешного завершения обновления переименовывает его.

Для Berkeley DB и других "однофайловых" баз данных можно повысить надёжность, выполняя ЗАМЕНУ существующего файла базы данных с помощью команды "mv" вместо его непосредственной перезаписи:

# postmap access.in && mv access.in.db access.db

В данной последовательности команд входной файл "access.in" конвертируется в выходной файл "access.in.db", который, в свою очередь, заменяет файл "access.db" только в случае успешного выполнения команды postmap(1). Конечно, набирать такие длинные команды быстро надоедает, поэтому люди предпочитают использовать make-файлы. Возможный вариант make-файла и работы с ним (пользовательский ввод выделен жирным шрифтом):

# cat Makefile
all: aliases.db access.db virtual.db ...и так далее...

# Примечание 1: команды указываются после символа табуляции.
# Примечание 2: для локальных псевдонимов используется postalias(1), для всего остального - postmap(1).
aliases.db: aliases.in
        postalias aliases.in
        mv aliases.in.db aliases.db

access.db: access.in
        postmap access.in
        mv access.in.db access.db

virtual.db: virtual.in
        postmap virtual.in
        mv virtual.in.db virtual.db

...и так далее...
# vi access.in
...процесс редактирования не показан...
# make
postmap access.in
mv access.in.db access.db
#

В данном случае команда "make" обновляет только те файлы, которые были изменены. В случае ошибки команда "make" остановится и вызова команды "mv" не произойдёт, таким образом Postfix продолжит использовать существующий файл базы, как будто ничего не произошло.

Типы поисковых таблиц Postfix

Для определения того, какие типы баз данных поддерживает ваша система Postfix, используйте команду "postconf -m". Далее приведён список часто поддерживаемых типов баз данных:

btree
Отсортированная, сбалансированная древовидная структура. Доступна только в системах с поддержкой баз данных Berkeley DB. Файлы базы данных создаются командой postmap(1) или postalias(1). Имя поисковой таблицы в записи "btree:table" представляет собой имя файла базы данных без указания суффикса ".db".
cdb
Оптимизированная для чтения структура, не поддерживающая инкрементные обновления. Файлы базы данных создаются командой postmap(1) или postalias(1). Имя поисковой таблицы в записи "cdb:table" представляет собой имя файла базы данных без указания суффикса ".cdb". Этот тип базы данных доступен в Postfix 2.2 и более новых версиях.
cidr
Таблица, которая связывает значения с шаблонами бесклассовой адресации (Classless Inter-Domain Routing, CIDR). Формат такой таблицы описан в man-странице cidr_table(5).
dbm
Индексированный тип файла на основе хеширования. Доступен только в системах с поддержкой баз данных DBM. Общедоступные файлы баз данных создаются командой postmap(1) или postalias(1), а приватные базы данных обслуживаются демонами Postfix. Имя поисковой таблицы в записи "dbm:table" представляет собой имя файла базы данных без указания суффикса ".dir" или ".pag".
environ
Массив переменных окружения UNIX-процесса. В качестве ключа поиска используется имя переменной. Имя поисковой таблицы в записи "environ:table" игнорируется.
fail
Таблица, все запросы к которой безусловно завершаются сбоем. Данный тип поисковой таблицы используется только для логирования и предназначен для упрощения тестирования ошибок Postfix.
hash
Индексированный тип файла на основе хэширования. Доступен только в системах с поддержкой баз данных Berkeley DB. Общедоступные файлы баз данных создаются командой postmap(1) или postalias(1), а приватные базы данных обслуживаются демонами Postfix. Имя базы данных в записи "hash:table" представляет собой имя файла базы данных без указания суффикса ".db".
inline (только для чтения)
Не оформленная в виде файла, содержащаяся в оперативной памяти таблица поиска. Пример: "inline:{ key=value, { key = текст с пробельными символами и запятыми }}". Пары ключ-значение разделяются пробельными символами и запятыми; для пар ключ-значение внутри фигурных скобок "{}" пробельные символы игнорируются после открывающейся скобки "{", вокруг знака равно "=" между ключом и значением, и перед закрывающейся скобкой "}". Встроенные таблицы избавляют от необходимости создавать файл базы данных, если обслуживаются всего несколько фиксированных элементов. Смотрите также тип карты static:.
internal
Не оформленная в виде файла, содержащаяся в оперативной памяти хэш-таблица поиска. Её содержимое теряется при завершении процесса.
lmdb
База данных LMDB от OpenLDAP. Доступна только в системах с поддержкой баз данных LMDB. Общедоступные файлы баз данных создаются командой postmap(1) или postalias(1), а приватные базы данных обслуживаются демонами Postfix. Имя базы данных в записи "lmdb:table" представляет собой имя файла базы данных без указания суффикса ".lmdb". Подробное описание смотрите в man-странице lmdb_table(5).
ldap (только для чтения)
Клиент базы данных LDAP. Подробное описание конфигурации приводится в man-странице ldap_table(5).
memcache
Клиент базы данных Memcache. Подробное описание конфигурации приводится в man-странице memcache_table(5).
mysql (только для чтения)
Клиент базы данных MySQL. Подробное описание конфигурации приводится в man-странице mysql_table(5).
netinfo (только для чтения)
Клиент базы данных Netinfo.
nis (только для чтения)
Клиент базы данных NIS.
nisplus (только для чтения)
Клиент базы данных NIS+. Подробное описание конфигурации приводится в man-странице nisplus_table(5).
pcre (только для чтения)
Поисковая таблица, основанная на совместимых с Perl регулярных выражениях (Perl Compatible Regular Expressions). Формат файла описан в man-странице pcre_table(5). Имя поисковой таблицы в записи "pcre:table" представляет собой имя файла с регулярными выражениями.
pipemap (только для чтения)
Конвейер таблиц поиска. Пример: "pipemap:{type1:name1, ..., typen:namen}". Каждый запрос к конвейеру "pipemap:" передаётся к первой из указанных поисковых таблиц. Каждый полученный результат поиска становится запросом для следующей таблицы в конвейере, а финальный результат производится последней таблицей. Если какая-либо из таблиц не возвращает никакого результата, весь конвейер не возвращает результата. Первым и последним символом описания таблицы в записи "pipemap:table" должны быть фигурные скобки "{" и "}". Внутри скобок отдельные карты разделяются запятыми или пробельными символами.
pgsql (только для чтения)
Клиент базы данных PostgreSQL. Подробное описание конфигурации приводится в man-странице pgsql_table(5).
proxy
Postfix-клиент proxymap(8) для совместного доступа к базам данных Postfix. Синтаксис таблицы поиска — "proxy:type:table".
randmap (только для чтения)
Содержащаяся в оперативной памяти таблица поиска, выполняющая случайный выбор значения. Пример: "randmap:{result1. ..., resultn}". На каждый запрос к таблице возвращается случайно выбранный вариант из заданного множества возможных результатов. Первым и последним символом описания таблицы в записи "randmap:table" должны быть фигурные скобки "{" и "}". Внутри скобок отдельные значения разделяются запятыми или пробельными символами. Чтобы придать конкретному результату больший вес, укажите его несколько раз.
regexp (только для чтения)
Таблица поиска, основанная на регулярных выражениях. Формат файла описан в man-странице regexp_table(5). Имя поисковой таблицы в записи "regexp:table" представляет собой имя файла с регулярными выражениями.
sdbm
Индексированный тип файла на основе хэширования. Доступен только в системах с поддержкой баз данных SDBM. Общедоступные файлы баз данных создаются командой postmap(1) или postalias(1), а приватные базы данных обслуживаются демонами Postfix. Имя базы данных в записи "sdbm:table" представляет собой имя файла базы данных без указания суффикса ".dir" или ".pag".
socketmap (только для чтения)
Клиент socketmap в стиле Sendmail. Именем таблицы будет либо inet:host:port:name для серверов TCP/IP, либо unix:pathname:name для серверов домена UNIX. Подробное описание смотрите в man-странице socketmap_table(5).
sqlite (только для чтения)
База данных SQLite. Подробное описание конфигурации приводится в man-странице sqlite_table(5).
static (только для чтения)
Таблица, всегда возвращающая своё имя в качестве результатов поиска. Например, "static:foobar" всегда возвращает в качестве результата поиска строку "foobar". Если в строке результата есть пробельные символы, используйте для её указания конструкцию "static:{ text with whitespace }"; в этой форме пробельные символы после открывающейся скобки "{" и до закрывающейся скобки "}" игнорируются. Смотрите также тип карты inline:.
tcp
Клиент TCP/IP. Протокол описан в man-странице tcp_table(5). Имя таблицы поиска представляет собой "tcp:host:port", где в качестве "host" указывается символьное имя хоста или числовой IP-адрес, а в качестве "port" указывается символьное имя сервиса или числовой номер порта.
texthash (только для чтения)
Таблица, которая выдаёт такие же результаты, как и файлы типа hash:, за исключением того, что вам не нужно выполнять команду postmap(1) перед тем, как использовать такой файл, и что таблицы типа texthash: не выявляют изменений после того, как файл был считан. Имя таблицы поиска в записи "texthash:filename" представляет собой полное имя файла без изменений; никаких суффиксов не добавляется.
unionmap (только для чтения)
Таблица, в которой каждый запрос посылается нескольким поисковым таблицам, а затем все найденные результаты объединяются через запятую. Синтаксис имени таблицы аналогичен синтаксису для таблиц pipemap.
unix (только для чтения)
Ограниченное представление базы данных аутентификации UNIX. Реализованы следующие таблицы:
unix:passwd.byname
Данная таблица представляет собой базу данных паролей UNIX. Ключём является имя учётной записи. Результатом будет запись файла паролей в формате passwd(5).
unix:group.byname
Данная таблица представляет собой базу данных групп UNIX. Ключём является имя группы. Результатом будет запись файла групп в формате group(5).

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