
Контекст
У меня docker-compose --version
2.13.0
Я создал репродуктор вhttps://github.com/Losmoges/postfix-dovecot-lmtp-reproducer
В моем пробном варианте в файле compose есть три службы docker: postfix, dovecot и client. Они делят сеть через драйвер моста.
- Postfix настроен на пересылку входящих писем в dovecot с помощью
virtual_transport = lmtp:dovecot:24
настройки в файле main.cf. - Dovecot настроен на прием подключений через параметр
service lmtp
// в конфигурации dovecot.conf.inet_listener lmtp
port = 24
- Я могу отправить письмо через Postfix, выполнив в клиентском контейнере. Его msmtp настроен на подключение через файл конфигурации.
echo test | msmtp [email protected]
host postfix
msmtprc
Это дает следующий результат в очереди Postfix, который я могу проверить, запустив postqueue -p
в контейнере Postfix.
Ошибка
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient-------
DEC4F3DCBE 245 Fri Dec 16 19:41:17 [email protected]
(Host or domain name not found. Name service error for name=dovecot type=A: Host not found, try again)
[email protected]
Обходной путь
Когда я нахожу IP-адрес контейнера Dovecot через docker inspect
и ввожу его в конфигурацию Postfix, например, как virtual_transport = lmtp:172.18.0.4:24
, все работает как и ожидалось. В этом случае команда postqueue -p
выдает Mail queue is empty
(после отправки письма через msmtp)
Вопросы
Почему virtual_transport = lmtp:dovecot:24
не работает? Я что-то неправильно настроил? Любая форма поиска имени, например nslookup dovecot
(после установки dnsutils) в контейнере Postfix, работает нормально и возвращает IP-адрес контейнера Dovecot. Выполняет ли Postfix собственное отдельное разрешение доменных имен? Если да, как заставить его использовать разрешение доменных имен по умолчанию?
Редактировать: Решение в Ответе
Я добавил следующую строку в Dockerfile для образа Postfix
RUN sed -i'' -e 's/^lmtp .*/lmtp unix - - n - - lmtp/g' /etc/postfix/master.cf
решение1
Почему virtual_transport = lmtp:dovecot:24 не работает?
В вашем master.cf
, вы lmtp
настроили работу в chroot
среде:
# ==========================================================================
# service type private unpriv chroot wakeup maxproc command + args
# (yes) (yes) (no) (never) (100)
lmtp unix - - n - - lmtp
Среда chroot
не имеет доступа к контейнеру /etc/resolv.conf
, поэтому она не знает, как разрешать имена хостов. Конфигурация lmtp по умолчанию запускается в среде chrooted, поскольку типичная конфигурация использует сокеты unix для связи, поэтому разрешение имен хостов не является проблемой.
Самое простое решение — просто настроить среду lmtp
так, чтобы она не запускалась chroot
:
lmtp unix - - y - - lmtp
Благодаря этому изменению почта доставляется правильно:
postfix_1 | Dec 16 21:47:15 8d74be7a5951 postfix/smtpd[598]: connect from unknown[172.28.0.1]
postfix_1 | Dec 16 21:47:15 8d74be7a5951 postfix/smtpd[598]: 9131638672DA: client=unknown[172.28.0.1]
postfix_1 | Dec 16 21:47:15 8d74be7a5951 postfix/qmgr[582]: 9131638672DA: from=<[email protected]>, size=434, nrcpt=1 (queue active)
postfix_1 | Dec 16 21:47:15 8d74be7a5951 postfix/smtpd[598]: disconnect from unknown[172.28.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
dovecot_1 | Dec 16 21:47:15 lmtp(16): Info: Connect from 172.28.0.3
dovecot_1 | Dec 16 21:47:15 lmtp([email protected])<16><+A19J2PnnGMQAAAAqj6rOA>: Info: msgid=<20221216164715.079491@rocket>: saved mail to INBOX
postfix_1 | Dec 16 21:47:15 8d74be7a5951 postfix/lmtp[597]: 9131638672DA: to=<[email protected]>, relay=dovecot[172.28.0.2]:24, delay=0.09, delays=0.07/0/0/0.01, dsn=2.0.0, status=sent (250 2.0.0 <[email protected]> +A19J2PnnGMQAAAAqj6rOA Saved)
dovecot_1 | Dec 16 21:47:15 lmtp(16): Info: Disconnect from 172.28.0.3: Logged out (state=READY)
postfix_1 | Dec 16 21:47:15 8d74be7a5951 postfix/qmgr[582]: 9131638672DA: removed
Одной из альтернатив может быть настройка общего сокета Unix между контейнерами dovecot
и postfix
и использование его для связи вместо соединения Inet.
Вторым вариантом может быть запуск контейнера lmtp в том же сетевом пространстве имен, что и контейнер postfix, в этом случае проще использовать имя хоста localhost
.