Можно запросить 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 делает какой-то странный запрос, чтобы вытащить пароль из базы данных, и нигде не указано, что это на самом деле, и при этом оно не зарегистрировано.

2 ответа2

1

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

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

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

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

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

0

Просто сделаю дикое предположение (я не смешал 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'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .