В этом документе рассматриваются следующие темы:
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 используются для поиска и извлечения информации. Например, перезапись адресов (строка поиска представляет собой старый адрес, а результат — новый адрес) или контроль доступа (строка поиска представляет собой клиента, отправителя или получателя, а результат — некоторое действие, такое как "reject").
Однако в некоторых случаях Postfix требуется знать лишь факт существования ключа поиска. Поскольку результирующее значение в этих случаях не используется, допустимо возвращать любое непустое значение. Примерами подобных поисков могут служить параметры local_recipient_maps
(определяющий, для каких локальных получателей Postfix принимает почту из сети), mydestination
(определяющий, для каких доменов Postfix доставляет почту локально) или mynetworks
(определяющий IP-адреса доверенных клиентов или клиентских сетей). Технически они являются списками, а не таблицами. Несмотря на указанное отличие, списки Postfix описаны здесь же, поскольку они используют ту же базовую инфраструктуру, что и таблицы поиска Postfix.
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 reload" для того, чтобы заставить Postfix принять новую информацию. Каждый раз, когда вы выполняете "postfix reload", производительность Postfix резко падает.
Если вы меняете сведения в сетевой базе данных, такой как LDAP, NIS или SQL, выполнять "postfix reload" не нужно. Серверы LDAP, NIS или SQL самостоятельно заботятся о разрешении конфликтов доступа на чтение/запись и передают в Postfix новые данные, как только они становятся доступными.
Если вы меняете файлы таблиц типа regexp:, pcre:, cidr: или texthash:, то Postfix может не сразу принять изменения файла. Это связано с тем, что процесс Postfix однократно считывает файл целиком в память, и больше никогда его не проверяет.
Если такой файл используется краткосрочным процессом, таким как smtpd(8)
, cleanup(8)
или local(8)
, выполнять "postfix reload" после внесения изменений не требуется.
Если такой файл используется долгосрочным процессом, таким как trivial-rewrite(8)
, на загруженном сервере, может потребоваться выполнить "postfix reload".
Если вы изменяете базу данных на основе локальных файлов, такую как DBM или Berkeley DB, выполнять "postfix reload" не нужно. Postfix использует блокировку файлов для недопущения конфликтов доступа на чтение/запись, и всякий раз, когда процесс демона Postfix обнаруживает, что файл был изменен, он завершает работу перед обработкой следующего клиентского запроса, чтобы новый процесс мог инициализироваться с новой базой данных.
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, используйте команду "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 может быть скомпонован с поддержкой динамической подгрузки таблиц поиска.