dovecot.service в systemd: разбор отказов
Dovecot объявлен с Type=notify: systemd ждёт от него сигнала готовности, и при ошибке в настройках служба зависает в состоянии запуска, а не падает сразу. Второй источник путаницы — штатный dovecot.socket: он занимает только порты 143 и 993, и включённый вместе со службой даёт занятый адрес.
О службе
Штатный unit-файл в Debian и Ubuntu запускает dovecot -F, то есть на переднем плане, и объявлен с Type=notify. Это значит, что службу считают запущенной только после сигнала готовности от самой программы. Практическое следствие: при ошибке в настройках dovecot не падает с понятным кодом, а остаётся в состоянии запуска до истечения таймаута, и только потом помечается упавшим. Разбирать такой отказ надо не по коду выхода, а по журналу и по проверке настроек. Остановка и перезагрузка тоже идут не сигналами, а собственными командами: doveadm stop и doveadm reload.
Вместе со службой в пакете лежит dovecot.socket — и он устроен неочевидно. В нём объявлены отдельные слушатели для IPv4 и IPv6 на портах 143 и 993, с режимом BindIPv6Only=ipv6-only, потому что dovecot ожидает раздельные сокеты. Портов POP3 там нет вовсе. Если включить и службу, и сокет, systemd займёт порты первым, а dovecot попытается открыть свои — и получит занятый адрес. Выбирать надо что-то одно: обычную службу или запуск по обращению.
Третье, что стоит знать до первого отказа, — изоляция, заданная прямо в штатном описании: ProtectSystem=full делает системные каталоги доступными только для чтения, PrivateTmp=true даёт службе собственный временный каталог, PrivateDevices=true скрывает устройства, а предел открытых файлов поднят до 65535. Из-за этого путь к почте вне /var может оказаться недоступным для записи, а отладочные приёмы с файлами во временном каталоге не работают так, как ожидается: у службы он свой. И отдельно: сам файл описания править не нужно — в его заголовке прямо предложено класть изменения в переопределение /etc/systemd/system/dovecot.service.d/, иначе обновление пакета затрёт правки.
Место, где dovecot чаще всего встречается с почтовым сервером: проверка подлинности при отправке. Сокет проверки подлинности должен быть доступен процессам отправляющей службы, а они у postfix работают в изолированном корне /var/spool/postfix. Поэтому сокет объявляют внутри этого корня и следят за его владельцем и правами — иначе отправка с проверкой подлинности отказывает при исправных обеих службах.
Как устроена
| Тип службы | Type=notify — состояние запуска держится до сигнала готовности от программы |
|---|---|
| Команда запуска | /usr/sbin/dovecot -F — на переднем плане, в фон не уходит |
| Остановка и перезагрузка | doveadm stop и doveadm reload, а не сигналы |
| Штатный сокет | dovecot.socket: только 143 и 993, раздельно IPv4 и IPv6, BindIPv6Only=ipv6-only |
| Изоляция из коробки | ProtectSystem=full, PrivateTmp=true, PrivateDevices=true |
| Предел открытых файлов | LimitNOFILE=65535 задан в штатном описании |
| Куда класть правки | в переопределение /etc/systemd/system/dovecot.service.d/, сам файл не править |
| Итоговые настройки | doveconf -n — только отличия от значений по умолчанию |
Частые ошибки
10 записей базы отмечены за этой службой.
Ошибки служб
- Почтовый сервер доступа не запускается: не читается сертификатСлужба падает при чтении сертификата: права на закрытый ключ, неверный порядок цепочки или путь к ней.
- Фильтр почты недоступен почтовой службе: сокет и группыПочтовая служба не может обратиться к фильтру: сокет создан с правами, недоступными её пользователю.
Сообщения журнала
- Address already in use при запуске службыПорт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Permission denied в журнале службыОтказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
Таймеры, сокеты, монтирование
- Сокет и служба включены одновременно: конфликт при загрузкеПри сокет-активации в автозапуск включена и служба, и сокет. Порт занимает то, что стартовало первым.
- Сокет слушает только IPv6 или только IPv4 неожиданноКлиенты по одному из протоколов не подключаются: поведение двойного стека задаётся отдельным параметром.
Ресурсы и ограничения
- Too many open files в журнале службыСлужба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
- Disk quota exceeded для службыМесто на разделе есть, а запись отклоняется: исчерпана дисковая квота пользователя или группы.
Состояния результата
- Job for … failed because a timeout was exceededЗадание на запуск прервано по таймауту. Как отличить медленный старт от заблокированного и правильно настроить TimeoutStartSec.
Коды выхода
- status=217/USER в systemdКод 217/USER означает, что systemd не смог определить или сменить пользователя из User=. Разбор причин: пользователя нет, имя недопустимо, конфликт с DynamicUser.
Коды выхода этой службы
Числа в status=N ниже 200 назначает сама программа, 200 и выше — systemd, когда не смог подготовить запуск.
| status | Что означает у этой службы | Куда смотреть |
|---|---|---|
1/FAILURE |
ошибка в настройках или недоступный путь к почте. Причину даёт doveconf -n и журнал службы. |
разбор |
89 |
своя ошибка dovecot при запуске вспомогательной службы — чаще всего нечитаемый закрытый ключ. | разбор |
таймаут запуска |
при Type=notify неготовая служба висит в состоянии запуска до истечения таймаута, потом помечается упавшей. |
разбор |
Диагностика
Состояние службы. При типе notify важно различать «запускается» и «запущена».
systemctl status dovecot --no-pager -l | head -10Итоговые настройки без значений по умолчанию: короткий вывод, по которому видно, что правили.
doveconf -nПеречитывание настроек тем же способом, каким это делает systemd.
sudo doveadm reloadКто занимает почтовые порты: служба, её сокет или посторонний процесс.
sudo ss -tlnp | grep -E ":143|:993|:110|:995"Включены ли служба и сокет одновременно — это даёт занятый адрес.
systemctl is-enabled dovecot dovecot.socket 2>/dev/nullСообщения о запуске: сертификаты, права, путь к почте.
journalctl -u dovecot -n 40 --no-pagerСокет проверки подлинности внутри изолированного корня почтового сервера и его права.
sudo ls -l /var/spool/postfix/private/auth 2>/dev/nullПараметры unit, которые тут важны
- Type=`notify`: готовность подтверждает сама программа
- ExecReload=перезагрузка настроек через `doveadm reload`
- ProtectSystem=системные каталоги только для чтения
- PrivateTmp=свой временный каталог: файлы туда кладутся не там, где вы их ищете
- PrivateDevices=устройства скрыты от процессов службы
- LimitNOFILE=поднят до 65535 в штатном описании
- Sockets=связь службы с сокетом при запуске по обращению
Частые вопросы
Служба висит в activating и падает через минуту с таймаутом.
Так выглядит ошибка настроек при Type=notify: dovecot не отправляет сигнал готовности, и systemd ждёт до таймаута. Смотрите журнал службы и вывод doveconf -n, а не код выхода.
При запуске пишет «Address already in use», хотя dovecot не работает.
Проверьте, не включён ли dovecot.socket. Он занимает порты 143 и 993, и тогда служба не может открыть свои слушатели. Нужно выбрать что-то одно: обычную службу или запуск по обращению.
Можно ли править /lib/systemd/system/dovecot.service?
Не нужно: обновление пакета затрёт правки. В заголовке файла прямо предложено класть изменения в переопределение /etc/systemd/system/dovecot.service.d/.
Почему POP3 не поднимается через штатный сокет?
В dovecot.socket объявлены только порты 143 и 993. Для POP3 слушатели надо объявлять самим или запускать dovecot обычной службой.
Источники
- Пакет dovecot-core 1:2.3.21+dfsg1-2ubuntu6.5 (Ubuntu 24.04): unit-файлы
- systemd.socket(5)
- systemd.service(5)
- Документация Dovecot
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)