Каков правильный формат файла карты базы данных паролей Postfix?

352
aphid

Можно запросить postfix для получения информации о входе в систему sasl для его сервера ретрансляции из базы данных. Затем этот сервер ретрансляции получает ту же самую регистрационную информацию.

Как нам отформатировать этот файл конфигурации для правильной выборки?

Мы знаем эти фрагменты информации:

  1. Доменное имя реле.
  2. Имя пользователя почтового ящика.
  3. Доменное имя на постфиксном сервере (может быть больше одного).

Теперь обычный текстовый файл, содержащий только пароли, будет отформатирован следующим образом (для каждой строки), при условии, что mailboxотправляется с domain2использованием пароля mailpass:

smtp.relay.tld mailbox@domain2.tld:mailpass 

Я проверил, что метод открытого текста работает для конкретного пользователя и пароля в базе данных. Теперь я хочу использовать файл .cf для подключения к базе данных.

Учитывая таблицу доменов, как это 1 :

+----+----------+-------------+----------+ | id | username | domain | password | +----+----------+-------------+----------+ | 1 | mailbox | domain2.tld | mailpass | +----+----------+-------------+----------+ 

В общем, такой файл будет отформатирован так;

user = sqluser password = dbpass hosts = localhost dbname = maildb query = SELECT password FROM accounts WHERE username = '%u' AND domain = '%d' 

Я не уверен относительно того, что именно поместить в параметр «запрос». Официальная документация по нему довольно плохая: в ней говорится, что вы можете настроить ее с помощью базы данных sql, в ней вообще не указано, как, конкретных примеров не приводится.

Теперь я попытался использовать наивный подход; создайте запрос, который просто возвращает значение точно так же, как строка в текстовом файле. Я также попытался вернуть различные подмножества строки, но безуспешно. Каждая попытка просто генерирует ошибку «Отказано в доступе».

1 : я знаю, что хранение фактических паролей пользователя в базе данных таким способом - плохая идея . Используемые здесь пароли предназначены только для связи между двумя конкретными серверами.

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

Проделав еще кое-что: включив ведение журнала уровня L4 и просматривая расшифровку транскрипта соединения с сервером, он, похоже, никогда не отправляет сообщение AUTH (поэтому он даже не выясняет, как «найти» пользователя). Следующие сообщения могут быть найдены в почтовом журнале (с отредактированными доменными именами и т. Д.);

postfix/smtp[6494]: maps_find: smtp_sasl_password_maps: smtp.relay.tld: not found postfix/smtp[6494]: maps_find: smtp_sasl_password_maps: smtp.relay.tld:587: not found postfix/smtp[6494]: smtp_sasl_passwd_lookup: no auth info found  (sender=`user@domain.tld', host=`smtp.relay.tld') 

все же, выполняя эту команду:

postmap -q user@domain.tld mysql:/etc/postfix/mysql-map.cf 

производит

smtp.relay.tld user@domain.tld:mailpass 

Другими словами, конфигурация работает, но программа postfix делает какой-то странный запрос, чтобы вытащить пароль из базы данных, и нигде не указано, что это на самом деле, и при этом оно не зарегистрировано.

0

2 ответа на вопрос

1
aphid

Нужны две вещи:

Во-первых, опция smtp_sender_dependent_authentication = yesдолжна быть включена в основном файле конфигурации postfix (обычное расположение /etc/postfix/main.cf). Без этой опции сервер будет выполнять поиск только на основе доменного имени узла ретрансляции, которое будет одинаковым для каждого пользователя.

Во-вторых, правильный запрос должен выглядеть так:

query = SELECT CONCAT(username, "@", domain, ":", password) FROM accounts \ WHERE username = '%u' AND domain = '%d' 

Примечание: конфигурационные файлы не поддерживают многострочность в этом смысле; так что удалите \ и перевод строки

0
grawity

Просто сделаю дикое предположение (я не смешал Postfix и SQL), но вот что я бы начал с:

  1. «Локальная часть» адреса электронной почты не становится автоматически «именем пользователя» для аутентификации ретранслятора. Таким образом, даже если в вашей базе данных они оба идентичны, Postfix не может сделать это предположение автоматически, поэтому поле имени пользователя должно быть возвращено в любом случае.

  2. Все таблицы Postfix выполняют поиск одинаково: один ввод приводит к одному выводу, и ядро ​​Postfix фактически не заботится о том, поддерживает ли конкретный бэкэнд таблицы несколько столбцов или нет. Я думаю, что он ожидает одну строку и анализирует ее одинаково во всех случаях.

Согласно пункту № 2, если таблица открытого текста хранится mailbox@domain2.tld:mailpass, то SQL-запрос, вероятно, должен также возвращать один столбец, отформатированный таким же образом. Поэтому я бы попробовал это:

query = SELECT CONCAT(username, ":", password) FROM accounts WHERE username = '%u' AND domain = '%d' 

Но если это не правильно, то должны работать два отдельных столбца:

query = SELECT username, password FROM accounts WHERE username = '%u' AND domain = '%d' 
Я проверил оба варианта. Оба результата приводят к «отказу в разрешении». В двухколоночной версии будут выбраны `mailbox @ domain2.tld` и` mailpass`. Версия с 1 столбцом выберет `mailbox@domain.tld: mailpass`. Ни один из строковых форматов не является правильным. (Хотя, возможно, проблема заключается не в буквенно-цифровых цифрах в реальном пароле?) aphid 5 лет назад 0
Вы пытались узнать, какое имя пользователя / пароль на самом деле пытается использовать Postfix? (Надеюсь, это доступно на самом высоком уровне отладки.) grawity 5 лет назад 0
Я обновил свой пост с этой информацией. К сожалению ... Кажется, этого не происходит, даже на 4-м уровне. Мне бы пришлось просмотреть исходный код. aphid 5 лет назад 0

Похожие вопросы