Как узел выбирает источник и складывает его настройки

критично

<source> matching and inheritance
Настройка действует не там, где написана

Блоки <source> бывают двух пород, и ведут себя они по-разному.

Адресные блоки называют один адрес (10.0.0.5) или сеть в бесклассовой записи (10/8). Соединение попадает под все блоки, чьи адреса его накрывают, и настройки складываются — ровно так же, как у блоков получателей: где два блока говорят разное, побеждает более узкий.

Руководство печатает свой же пример дважды — как он написан и как его видит MTA после слияния. Это самое внятное место главы: читать конфигурацию построчно бесполезно, действует не строка, а сумма строк.

Именованные блоки (<source S1>) под адреса не подбираются вовсе. Они включаются только тогда, когда на них сослались по имени: параметром source= у smtp-listener или директивой source внутри <smtp-user>.

Что при этом происходит с адресными настройками, руководство описывает одним словом: именованный блок перекрывает то, что подобралось по адресу. Слово обещает наследование — настройка, о которой именованный блок молчит, должна достаться ему из адресного.

У нас вышло иначе. Переписывание обратного адреса, заданное в общем блоке 0/0, на авторизованное соединение не перенеслось: адрес остался неизменным, пока ту же строку не повторили в именованном блоке. Отсюда правило, по которому Хаб теперь собирает конфигурацию, — в именованном блоке повторяется весь набор, а не только то, что отличается.

Имена в фигурных скобках зарезервированы. Руководство называет два: {pickup} меняет обработку каталога подхвата, {auth} задаёт умолчания для любого аутентифицированного пользователя.

Главная ловушка. На вопрос «разрешено ли этому клиенту сдавать почту» не отвечает ни один блок по отдельности — отвечает их сумма. А после входа по логину ответ может смениться ещё раз: именованный блок пользователя перекрывает всё, что подобралось по адресу.

Отсюда практическое правило: разрешение, выданное в блоке 0/0, действует и на все подсети, для которых не сказано обратное. «Выдать только своим» означает запрет в широком блоке и разрешение в узком, а не наоборот.

Что делает Хаб. Пишет блоки источника обеих пород, в двух файлах.

В основном файле — адресные: 127.0.0.1 для подачи с самой машины, по блоку на каждый адрес из «Кому разрешена подача» и 0/0 как общая основа. Узкий блок наследует от широкого всё, чего сам не сказал: и выбор потока по адресу подачи, и список выбора, и подавление локальных отчётов. В базовой конфигурации, которая ставится до появления пар, выбора потока и списка в 0/0 ещё нет.

В файле адресов — именованные, по одному на логин подачи: общий {pmta-auth} и по блоку на каждую пару «домен плюс адрес». На них ссылается директива source внутри <smtp-user>. В каждом таком блоке Хаб выписывает полный набор — службу подачи, разрешение ретрансляции, требование авторизации, выбор потока, подавление локальных отчётов, работу с заголовками, — а не только отличия от адресных блоков. Так вышло не из осторожности: наследования на авторизованное соединение мы не увидели.

Имена Хаб берёт в фигурные скобки — формат общий с Protosender. Руководство эту область имён объявляет зарезервированной и называет в ней два своих имени; наши на них не похожи и работают, но область всё-таки вендорская.

Пример в конфигурации
# оба блока накрывают подачу с самой машины — действуют слитно
<source 0/0>
    default-virtual-mta by-smtp-source-ip
    add-received-header false
</source>

<source 127.0.0.1>
    always-allow-relaying yes    max-message-size 30M
</source>
Подача с самой машины получает разрешение на ретрансляцию и свой предел размера — плюс всё из широкого блока: выбор потока по адресу и отказ добавлять Received. В самом узком блоке ни той, ни другой строки нет.
жёлтым — — имена директив, голубым — блоки. Так же они подсвечены и в тексте карточки.
▲

Типичные ошибки и проблемы

что делают не так и чем это кончается4 ошибки▶

Читают конфигурацию построчно

§ 3.3.7

Чем чреватоНастройка ищется в том блоке, где стоит адрес подачи, — и не находится, потому что записана в широком. Или наоборот: находится в широком и считается действующей, хотя узкий её перекрыл. Руководство печатает пример до и после слияния именно ради этого случая.
Как заметитьУзел ведёт себя не так, как написано в блоке, который вы читаете.
Как правильноВыписать все блоки, накрывающие адрес подачи, и наложить их по правилу «узкий поверх широкого». Настройка, которой нет ни в одном, берёт вендорское умолчание.

Ждут, что именованный блок подберётся сам

§ 3.3.7

Чем чреватоИменованные блоки под адреса не подбираются. Блок, на который никто не сослался, не действует никогда — и настройки, которые в нём написаны, не применяются ни к одному соединению.
Как заметитьЛогин подачи работает, но ведёт себя как безымянное соединение с того же адреса.
Как правильноСослаться на блок по имени — параметром source= у приёмника или директивой source внутри блока пользователя.

Полагаются на наследование в именованный блок

наш опыт

Чем чреватоРуководство говорит «перекрывает», из чего следует, что неупомянутое достаётся из адресного блока. У нас так не вышло: переписывание обратного адреса из общего блока на авторизованное соединение не перенеслось, и обратный адрес остался неизменным.
Как заметитьНастройка, записанная в общем блоке, не действует для подачи под логином — при том что для той же подачи без логина действует.
Как правильноПовторять в именованном блоке весь набор целиком, а не только отличия. Проверять поведением, а не чтением конфигурации.

Разрешают в широком блоке, надеясь ограничить узким

наш опыт

Чем чреватоСлияние идёт сверху вниз по узости, а не по порядку строк в файле. Разрешение в блоке 0/0 достаётся каждой подсети, которая сама не сказала обратное, — включая ту, ради которой всё затевалось.
Как заметитьСдавать почту может кто угодно, хотя узкий блок выглядит ограничивающим.
Как правильноЗапрет ставить в широкий блок, разрешение — в узкий. Проверять слиянием, а не чтением одной строки.
Совместимость
PowerMTA 6.0
описана в руководстве этой версии · платформа: любая
С какой версии директива доступна, вендор указывает не для всех — здесь пометки нет. Имя встречается и в издании руководства 5.0.
⇄

Связанные записи

3 связи

Как проверить на узле
Слитого вида узел не показывает — ни одна команда не печатает настройки источника. Собирать придётся глазами, по двум файлам:
grep -n '^<source\|^</source' /etc/pmta/config /etc/pmta/virtualhost.txt
pmta test config
Первая команда даёт список блоков и их границы, вторая проверяет, что файл вообще разбирается. Дальше — вручную: выписать все блоки, под которые попадает адрес подачи, и наложить их по правилу «узкий поверх широкого». Команды show settings для источников, в отличие от получателей, у MTA нет.
В Хабе
Цена ошибки
обратимо: вредит, пока стоит
Сценарии
Жизненный цикл конфигурации · Безопасность узла · Разделение отправителей
Важность
критично