«Unable to determine enabled services from ldap»: пять причин

Проектное бюро в Балашихе, 19 рабочих мест, январь 2021 года. Виртуалку с Zimbra перенесли на другой гипервизор, и после включения почта не поднялась. В консоли — строка про LDAP. Я поверил этой строке и потерял на ней целый день. Настоящая причина лежала в файле на четыре строки, и проверяется она за пятнадцать секунд.

Строка про LDAP, из-за которой копают не там

Почти всегда это выглядит одинаково. Стоит почтовый сервер, поставленный несколько лет назад. Работает. Его не трогают — потому что страшно, потому что документации нет, а человек, который его ставил, давно уволился. Потом сервер один раз перезагружают. После отключения света, после переезда виртуалки на новый гипервизор, после планового обновления хоста. И почта не поднимается.

Дальше сценарий тоже одинаковый. Кто-то заходит по SSH, набирает zmcontrol status и получает строку со словом ldap. Гуглит её. И весь интернет отвечает про LDAP: пароли репликации, повреждённая база, права на каталог, ресинк со слейва. Человек лезет туда, потому что больше ему опереться не на что.

Так вот. Эта строка почти никогда не про LDAP.

Точный её текст такой: Unable to determine enabled services from ldap. Enabled services read from cache. Service list may be inaccurate. В переводе на человеческий она означает ровно одно: скрипт не смог спросить у каталога, какие службы на этом узле включены, и взял старый ответ из кэша. Почему не смог — она не сообщает. А не смочь можно пятью разными способами, и только один из них имеет отношение собственно к LDAP.

Я на этом однажды потерял день. Дальше — как именно.

Балашиха, январь 2021: 19 мест и переехавшая виртуалка

Позвонили в понедельник, в 9:20. Проектное бюро в Балашихе, 19 рабочих мест, конструкторы и два сметчика. Zimbra 8.8.15 Open Source на CentOS 7. Поставил подрядчик в 2017-м — тогда, разумеется, ещё восьмёрку, — и один раз, в конце 2019-го, обновил до 8.8.15; это видно по датам в логах установщика в /opt/zimbra/log. После того обновления сервер не трогали и, судя по всему, не открывали.

В выходные их системный администратор — приходящий, раз в неделю — перенёс виртуалку на новый хост, потому что старый начал сыпать ошибками дисковой полки. Перенёс аккуратно: выключил, скопировал, включил. Машина поднялась, ОС загрузилась, ssh отвечал. Почта — нет.

Что я увидел, когда подключился:

[zimbra@mail ~]$ zmcontrol -v
Release 8.8.15_GA_... RHEL7_64 FOSS edition

[zimbra@mail ~]$ zmcontrol status
Unable to determine enabled services from ldap.
Enabled services read from cache. Service list may be inaccurate.
        Host mail.bureau.local
                amavis                  Stopped
                antispam                Stopped
                antivirus               Stopped
                ldap                    Running
                logger                  Stopped
                mailbox                 Stopped
                mta                     Stopped
                snmp                    Stopped
                stats                   Stopped
                zmconfigd               Stopped

Обратите внимание на строку ldap Running. Сам каталог живой. Он поднялся, он слушает, процесс slapd в памяти есть. И при этом скрипт не может у него ничего спросить.

Уже здесь можно было остановиться и подумать. Я не остановился.

Ложная версия: пароли и повреждённая база каталога

Меня сбила формулировка. «Не могу получить список служб из ldap» я прочитал как «каталог отвечает мусором», а виртуалку перед этим жёстко выключали — значит, база могла побиться. Версия выглядела логично: hard reset, BDB-хранилище, повреждение.

Я пошёл по этому пути и провёл там почти весь день.

  • Проверил пароли: zmlocalconfig -s ldap_root_password, ldap_replication_password, сверил с тем, что реально принимает slapd.
  • Сделал ldapsearch напрямую под cn=config — каталог отвечал, записи на месте.
  • Полез в логи slapd. Ни одной ошибки bind. Вообще ни одного обращения от локальных скриптов.
  • Всерьёз готовился к жёсткому сбросу через db_recover с удалением файлов базы и повторной синхронизацией.

Вот на этом месте меня и остановила собственная строчка в блокноте: «в логах slapd нет обращений от скриптов». Если бы каталог отвечал мусором — обращения были бы, просто неудачные. А их не было ни одного. Значит, скрипт до каталога вообще не доходит. Он спотыкается раньше.

Это была моя ошибка в чистом виде, и я до сих пор считаю её обидной. Я поверил тексту ошибки вместо того, чтобы проверить, что у неё под ногами. День работы, счёт на 18 тысяч и почта, которая стояла с утра понедельника до вечера — всё это следствие того, что я начал с пятого пункта списка вместо первого.

Проверьте у себя за две минуты

Если эта строка у вас прямо сейчас — вот набор из пяти команд. Выполнять под пользователем zimbra, кроме одной, где нужен root. Занимает меньше двух минут, закрывает подавляющее большинство случаев.

# 1. Имя себя и его резолв
hostname --fqdn
host -t A  $(hostname --fqdn)
host -t MX $(hostname -d)

# 2. Локальная таблица имён
cat /etc/hosts

# 3. Свободное место — по всем разделам, не только по корню
df -h
df -i

# 4. Каталог доступен на порту?
nc -zv $(hostname --fqdn) 389
ldapsearch -x -H ldap://$(hostname --fqdn):389 -s base -b "" namingContexts

# 5. Идентификаторы пользователя zimbra (актуально для нескольких серверов)
id zimbra

Теперь как читать результат.

Что увиделиЧто это значитЧто делать
host -t A отвечает not found или чужим адресомСервер не может найти сам себя. Это причина номер одинПочинить A-запись и MX в том DNS, который сервер реально использует
В /etc/hosts нет строки с FQDN сервера или адрес в ней старыйТот же эффект, что и выше, но локально. Частый гость после переезда машиныВернуть строку вида 10.0.0.15 mail.company.ru mail
df -h показывает 100% хотя бы на одном разделеЭто самая обманчивая причина: строка про LDAP, а виноват дискОсвободить место, потом перезапускать службы
df -i показывает 100% при живом местеКончились inode — обычно от миллионов мелких файлов в логах и очередиЧистить каталоги с мелочью, не гнаться за гигабайтами
nc говорит connection refused на 389Каталог действительно не слушает — вот это уже про LDAPСмотреть slapd, сертификаты, права
id zimbra даёт разные UID/GID на разных узлахМультисерверная установка, узлы не договорились о владельце файловПриводить идентификаторы к одному значению и переназначать владельца

Если первые три пункта чистые, а пятый одинаковый на всех узлах — тогда и только тогда есть смысл открывать логи каталога.

Пять причин и почему порядок именно такой

Порядок не случайный. Он выстроен от самой дешёвой проверки к самой дорогой и одновременно от самой частой причины к самой редкой.

1. DNS: записи A и MX

Скрипты Zimbra на старте выясняют, кто этот сервер, и лезут в каталог по имени, а не по адресу. Нет разрешения имени — нет обращения. Проверяется секундой, чинится минутой.

2. Файл /etc/hosts

То же самое, только локально. Ломается при смене адреса, при переносе машины, при активном dhclient, который считает своим долгом переписать чужие настройки. Именно этот пункт и был виноват в Балашихе.

3. Свободное место

Zimbra при нехватке места останавливается сама — это защита, а не поломка. Но наружу она выдаёт не «у меня кончился диск», а вот эту самую строку про каталог. Из пяти причин эта вводит в заблуждение сильнее всех: человек читает про LDAP и идёт разбирать LDAP, хотя лечится всё командой df -h и получасом уборки.

4. Порт 389 закрыт или каталог не слушает

Здесь connection refused будет виден прямо. Причин две: slapd не поднялся (смотрим его лог, сертификаты, права) или его закрыл локальный firewall, который после переезда машины вдруг ожил с дефолтными правилами.

5. Расхождение UID и GID пользователя zimbra

Актуально, когда узлов несколько: отдельный mailstore, отдельный MTA, отдельный каталог. Пользователь zimbra создаётся при установке, и на разных машинах ему легко достаются разные числовые идентификаторы. Файлы, которые один узел считает своими, для другого чужие. Симптом получается ровно тот же.

Отдельный случай: после возни с сертификатами

Есть шестая причина, которая не попадает в общий порядок, потому что у неё своя предыстория. Если незадолго до появления строки кто-то ставил сертификат по инструкции из интернета — почти наверняка сломаны права на файлы Zimbra. Рядом в консоли обычно висит вторая ошибка: zmcertmgr: ERROR: no longer runs as root! Лечится восстановлением прав:

# от root
/opt/zimbra/libexec/zmfixperms -e -v
# затем под zimbra
zmcontrol restart

Помогает не всегда. Я видел случай, когда после чужих экспериментов с сертификатами быстрее и надёжнее оказалось откатить виртуалку на снимок, чем разбирать, что именно там натворили.

Что было на самом деле: четыре строки в /etc/hosts

В шесть вечера я наконец открыл /etc/hosts. Там было это:

127.0.0.1   localhost localhost.localdomain
::1         localhost localhost.localdomain
192.168.10.7    mail.bureau.local mail

А сама машина после переезда получила адрес 192.168.20.7. Подсеть на новом хосте была другая — админ поменял адрес в настройках сети и совершенно логично не вспомнил про файл, о существовании которого Zimbra ему никогда не рассказывала.

Дальше всё заняло четыре минуты:

# поправили адрес
sudo sed -i 's/^192\.168\.10\.7/192.168.20.7/' /etc/hosts

# проверили, что сервер видит себя
host -t A mail.bureau.local
# mail.bureau.local has address 192.168.20.7

# и подняли всё как есть
su - zimbra -c 'zmcontrol restart'

Через две минуты zmcontrol status выдал десять строк со словом Running и ни одной со словом ldap в шапке. Почта пошла. Накопленная за день входящая — 148 писем — доехала за полторы минуты, потому что отправители честно держали её в своих очередях и повторяли попытки.

Отдельно про DNS в том же случае. A-запись во внутренней зоне тоже указывала на старый адрес, но её админ поправил ещё в воскресенье. Если бы он этого не сделал, я бы, скорее всего, нашёл проблему быстрее: два неверных ответа заметнее, чем один.

Цена этого дня в часах и деньгах

Считаем честно, потому что цифры здесь показательные.

  • Простой почты: с 9:20 понедельника до 18:10. Восемь часов пятьдесят минут на 19 человек.
  • Из них реально пострадали пятеро: сметчики, которые ждали от заказчика опросные листы, и руководитель проекта с согласованиями.
  • Комплект документации, который бюро должно было отправить в понедельник, ушёл во вторник утром. Штраф не выставили, но разговор был неприятный.
  • Мой день работы: 18 000 рублей.

Теперь второй столбец. Если бы я прошёл пять проверок в правильном порядке — а это двадцать минут вместе с чтением вывода, — счёт был бы на 3 000 рублей, а почта поднялась бы к половине одиннадцатого утра. Разница в пятнадцать тысяч рублей и восемь часов простоя целиком объясняется тем, что я начал не с того конца.

Мне эта история стоила дороже, чем клиенту. Я списал ему две трети счёта, потому что платить за мой неверный ход должен был не он.

И ещё одна цифра, уже не про этот случай. За пять лет я приезжал по этой строке одиннадцать раз. Разбивка такая: шесть раз — DNS или /etc/hosts, три раза — забитый диск, один раз — закрытый порт 389 после того, как ожил firewall, один раз — разные UID пользователя zimbra на двух узлах. Ни разу — повреждённая база каталога. Ни одного раза.

Где эта задача перестаёт быть двадцатиминутной

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

Место первое — когда причин две. Диск забился, потому что перестала ротироваться очередь, а очередь перестала ротироваться, потому что не резолвится имя. Вы чините место, служба поднимается, к вечеру всё повторяется. Здесь надо не чинить симптом, а разматывать цепочку в обратную сторону, и это уже не двадцать минут.

Место второе — перезапуск, который не проходит. После долгой остановки zmcontrol restart может зависнуть на остановке зимлетов на десять-пятнадцать минут и выглядеть как окончательно умерший сервер. Человек нервничает и убивает процессы руками. Дальше начинается второе приключение, уже с PID-файлами и с базой, которую не закрыли по-человечески.

Место третье — Zimbra вне поддержки на ОС с назначенной датой смерти. В Балашихе всё поднялось как было, потому что ломалось не ПО. Но если параллельно выяснится, что версия давно вне поддержки, а под ней CentOS 7, который сам уже мёртв, — разговор из «поднять почту» превращается в «решать, что делать с этим сервером вообще». Это другая работа и другой бюджет, и путать их не надо.

Место четвёртое — мультисерверная установка. Пункт про UID и GID выглядит безобидно, пока не выясняется, что менять владельца придётся на нескольких сотнях гигабайт при остановленных службах, и окно на это нужно ночное.

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

Пришлите мне вывод пяти команд из блока выше — hostname --fqdn, host -t A, cat /etc/hosts, df -h и id zimbra, — и я за день отвечу, что именно у вас сломалось и сколько времени займёт починка. Обычно ответ короткий и радостный.

Частые вопросы

Почему zmcontrol status показывает ldap Running, но всё равно ругается на ldap?

Потому что это два разных факта. Строка Running означает, что процесс slapd жив и его PID-файл на месте — это проверка на уровне процесса. А строка про enabled services означает, что скрипт не смог задать каталогу вопрос по сети, по имени сервера. Между этими двумя фактами лежит целый слой: разрешение имени, файл /etc/hosts, свободное место, доступность порта. Именно поэтому каталог может быть совершенно здоров, а строка всё равно будет. У меня в Балашихе slapd работал идеально все девять часов, пока я его подозревал.

Насколько опасно работать с сервером, пока эта строка висит?

Сама по себе строка ничего не ломает — она предупреждает, что список служб взят из кэша и может не соответствовать реальности. Опасность в другом: пока она висит, вы не можете доверять выводу zmcontrol. Он покажет Running у службы, которая на самом деле лежит, потому что берёт данные из старого кэша. Я поэтому и говорю всем: сначала уберите причину строки, потом смотрите на статус служб. В обратном порядке вы будете принимать решения по недостоверной картине.

У нас сервер работает годами, эта строка появляется иногда и сама пропадает. Это нормально?

Нет, и это самый неприятный вариант из всех. Плавающая строка почти всегда означает, что что-то периодически кончается: место на разделе, которое подъедается и освобождается ротацией логов, или DNS-сервер, который иногда не отвечает вовремя. Сервер балансирует на грани и рано или поздно свалится не вовремя. Смотрите df -h в момент появления строки, а не после — разница будет видна сразу. И проверьте, сколько DNS-серверов прописано в resolv.conf и живы ли они все.

Можно ли просто убрать эту строку, чтобы не мешала?

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

Как понять, что дело всё-таки в самом LDAP, а не в пяти внешних причинах?

Признак один и он резкий: nc -zv на порт 389 отвечает connection refused, а ldapsearch не проходит вообще. Если порт открыт и ldapsearch возвращает namingContexts — каталог здоров, ищите причину снаружи от него. Дополнительный признак настоящей проблемы с каталогом: в его логе есть попытки bind с ошибками. Если попыток нет совсем, значит, до каталога никто не доходит, и разбирать надо не его. Эта проверка занимает пятнадцать секунд и экономит рабочий день — мой она в своё время не спасла, потому что я сделал её последней.

Нужна помощь с проектом?

Специалисты АйТи Фреш помогут с архитектурой, DevOps, безопасностью и разработкой — 15+ лет опыта

📞 Связаться с нами
#Zimbra#LDAP#диагностика#авария#CentOS 7
Комментарии 0

Оставить комментарий

загрузка...

Подпишитесь на рассылку ITfresh

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

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.