Что у вашей Zimbra торчит наружу: аудит портов и админки

У клиента-медклиники в Одинцове почтовый сервер отдавал наружу админ-консоль, служебный порт postjournal и memcached. Файрвол при этом был, работал и всех устраивал. Первый мой скан показал, что всё в порядке — и это была самая полезная ошибка того апреля. Разбираю, как снять честную карту периметра и что на ней быть не должно.

«У нас файрвол есть» — и почему это ничего не значит

Про периметр почтового сервера я слышу три стандартных ответа. «У нас файрвол». «Сервер за роутером, снаружи его нет». «Провайдер всё закрывает». Все три бывают правдой. И все три бывают вежливым способом сказать «мы туда не заглядывали».

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

Отдельная неприятность в том, что такое состояние ничем себя не выдаёт. Почта ходит, веб открывается, пользователи довольны. Никакого симптома нет до того дня, когда симптом становится очень громким.

Дальше — апрельский случай 2025 года и порядок, по которому я теперь проверяю периметр за двадцать минут. Начинается он с моей же ошибки, из-за которой я час считал дырявый сервер закрытым.

Апрель 2025, Одинцово: клиника, 24 места и белый адрес

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

Позвали по бытовому поводу: письма клиники стали попадать в спам у части получателей. Разбор доставляемости — работа спокойная, я приехал в среду днём. Начал, как обычно, с общей картины сервера:

Release 9.0.0_GA_3924.RHEL8_64_20240710004244 RHEL8_64 FOSS edition, Patch 9.0.0_P39.

Девятка, патч P39. Уже интересно: RCE через postjournal закрыт в P41, значит, у них открыто. Держу в голове и иду дальше.

Сеть устроена просто. У клиники два белых адреса от провайдера. Один — на роутере, за ним офис. Второй отдан почтовому серверу через трансляцию «один в один»: весь адрес заворачивается на внутренний IP машины. Подрядчик, который это делал в 2022 году, аргументировал разумно — «так проще, не надо возиться с пробросами по одному порту».

Вот эта фраза «не надо возиться с пробросами» и есть корень всей истории. Совет звучит удобно, экономит час настройки и раздаёт наружу всё, что сервер слушает.

Первый скан соврал, и я ему поверил

Проверять периметр надо снаружи — это я знал и сделал правильно. Взял внешний хост, прогнал сканер по белому адресу клиники:

$ nmap -Pn 203.0.113.44
Not shown: 995 filtered tcp ports
PORT    STATE SERVICE
25/tcp  open  smtp
80/tcp  open  http
443/tcp open  https
587/tcp open  submission
993/tcp open  imaps

Пять портов, все ожидаемые. Я написал в блокноте «периметр в норме» и вернулся к спаму.

Через час, разбирая заголовки писем, я полез смотреть, кому сервер разрешает пересылку, и заодно посмотрел, что он слушает изнутри. Список оказался вдвое длиннее того, что показал сканер. И вот тут до меня дошло, в чём был подвох.

Сканер по умолчанию проверяет тысячу самых популярных портов. Не все 65 535, а тысячу. Ни 7071, ни 7072, ни 10027 в эту тысячу не входят. Порт 11211 в некоторых сборках списка есть, в некоторых нет — мне не повезло.

Прогнал заново, честно:

$ nmap -Pn -p- --min-rate 800 203.0.113.44
PORT      STATE SERVICE
25/tcp    open  smtp
80/tcp    open  http
443/tcp   open  https
587/tcp   open  submission
993/tcp   open  imaps
7071/tcp  open  ssl/unknown
7072/tcp  open  unknown
10027/tcp open  unknown
11211/tcp open  memcache

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

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

Карта портов Zimbra: что кому нужно

Чтобы понимать, на что смотреть, надо представлять путь письма внутри сервера. Он такой: письмо приходит на приёмник Postfix на 25-й или 587-й порт, оттуда уходит на антивирусно-антиспамный слой на 10024, тот возвращает его обратно в Postfix уже на 10025, и дальше оно ложится в ящик через локальную доставку на 7025. Три из четырёх этих портов — чисто внутренние.

Сводная таблица, которой я пользуюсь:

ПортКто этоНаружу
25Приём почты от чужих серверовОбязательно открыт
587Отправка от своих пользователей с авторизациейОткрыт, только с TLS
443Веб-почтаОткрыт
80Веб, обычно редирект на 443Открыт или закрыт — по вкусу
993 / 995IMAP и POP поверх TLSОткрыт, если люди ходят почтовыми клиентами
143 / 110IMAP и POP без шифрованияЗакрыть
389 / 636Служба каталогаЗакрыть наглухо
7025Локальная доставка в ящикЗакрыть наглухо
7071Административная консольЗакрыть наглухо
7072Обработчик маршрутов для обратного проксиЗакрыть наглухо
10024 / 10025Антивирус и антиспам, вход и возвратЗакрыть наглухо
10027Служба postjournalЗакрыть наглухо и по возможности выключить саму службу
11211Кэш маршрутов для проксиЗакрыть наглухо

Три порта, за которыми стоят конкретные неприятности

Три строки из этой таблицы стоит прокомментировать отдельно, потому что за ними стоят конкретные неприятности.

7071 — административная консоль

Это полный доступ ко всем ящикам, доменам, настройкам и паролям. Открытая наружу админка означает, что весь ваш почтовый сервер защищён ровно одним паролем администратора — и на него круглосуточно идёт подбор. У другого нашего клиента за две недели мы насчитали десятки тысяч попыток входа на веб-интерфейсы. Тут ещё и встроенный фильтр Zimbra подкидывает: он блокирует адрес после серии неудачных попыток, и потом в логе появляется запись про приостановку доступа для адреса — а у вас звонят пользователи, которые не могут зайти из-за чужого перебора.

10027 — postjournal

Служба обрабатывает почту по SMTP на этом порту. Именно через неё работает уязвимость, где вредоносный код передаётся в поле CC письма и выполняется на сервере, потому что ввод не проверяется. Закрыта она в 8.8.15 Patch 46, 9.0.0 Patch 41, 10.0.9 и 10.1.1. Вендор прямо рекомендует: если служба не используется — выключить её, а не только закрыть порт.

11211 — memcached

Кэш, в котором прокси хранит соответствие «пользователь — сервер». Данные там живут около часа. Доступный снаружи memcached — это классическая мишень: и для чтения чужих кэшированных данных, и для инъекций в кэш, для чего существует отдельная уязвимость в связке с Zimbra. Плюс, если у вас торчит наружу ещё и UDP-порт 11211, сервер становится чужим оружием: открытый memcached по UDP годами используют для усиления сетевых атак на третьи стороны. У Zimbra по умолчанию слушает TCP, и в этом скане мы видели именно его — но проверять стоит оба протокола.

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

Три действия. Первое — изнутри, посмотреть, что вообще слушает. Второе — снаружи, посмотреть, что из этого видно. Третье — проверить, кому сервер разрешает отправлять через себя.

# на сервере
ss -lntp | grep -E ':(25|80|110|143|389|443|587|636|993|995|7025|7071|7072|10024|10025|10027|11211)\b'

# с любого внешнего хоста, не из вашей сети
nmap -Pn -p- --min-rate 800 ВАШ.БЕЛЫЙ.АДРЕС

# на сервере, под пользователем zimbra
zmprov gcf zimbraMtaMyNetworks
zmprov gs $(zmhostname) zimbraServiceEnabled

Трактовка:

Что увиделиЧто это значитНасколько срочно
Снаружи виден 7071Админ-консоль в интернете, идёт подбор пароля прямо сейчасСегодня
Снаружи виден 10027При патче ниже нужного — прямой путь к выполнению команд на сервереСегодня
Снаружи виден 11211Кэш маршрутов доступен посторонним, сервер пригоден для усиления атакСегодня
Снаружи видны 7072, 7025, 10024, 10025Внутренняя кухня наружу; сами по себе не так страшны, но это признак трансляции «весь адрес на сервер»На этой неделе
Снаружи виден 389 или 636Служба каталога в интернете — оттуда достаются учётки и структура организацииСегодня
В zimbraMtaMyNetworks есть что-то шире вашей локальной сетиСервер готов пересылать чужую почту; при попадании в чёрные списки чинить это долгоСегодня
Список снаружи короче списка изнутри — и вы сканировали без -p-Вы смотрите на тысячу популярных портов; нужных там нетПересканировать

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

Что было у клиники и почему первая версия причины оказалась неверной

После честного скана я пошёл разбираться, почему так. Первая мысль была очевидной: на сервере не настроен локальный файрвол. Посмотрел — не настроен, служба выключена. Логично: включим, опишем правила, готово.

Включил, описал, проверил снаружи. Внутренние порты закрылись. И тут я понял, что решение неполное, а версия про «забыли настроить файрвол на сервере» — только половина правды.

Вторая половина была на шлюзе. Трансляция «один в один» никуда не делась: любой новый порт, который откроет на сервере любая будущая служба, автоматически станет доступен из интернета. Локальный файрвол — это последний рубеж, а не первый, и держать периметр на нём одном означает, что забытая галочка внутри машины сразу превращается в дыру снаружи.

Поэтому мы сделали обе вещи. На шлюзе заменили трансляцию всего адреса на список из шести портов. На сервере оставили описанные правила как второй слой. И проверили результат тем же полным сканом.

Заодно нашли, что zimbraMtaMyNetworks содержал не только локальную подсеть клиники, но и подсеть 10.8.0.0/24 от старого VPN, который отключили в 2023 году. Наследство от подрядчика. Само по себе оно ничем не грозило, потому что этой сети больше не существовало, но осталось бы там навсегда.

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

Что сделали, за сколько и что было бы иначе

Работы заняли 14 часов, разложились на три дня, простоя почты — 25 минут в момент переключения правил на шлюзе.

  1. Заменили трансляцию на шлюзе. Вместо всего белого адреса — шесть портов: 25, 80, 443, 587, 993, 995. Порт 995 добавили осознанно: три врача забирают почту по POP на домашние машины, и отбирать у них это в тот же день было бы лишним конфликтом.
  2. Подняли патчи с P39 до P41. Перед этим снапшот виртуалки и отдельный архив каталога сервера. Ночное окно, 4 часа.
  3. Выключили postjournal — клиника им не пользовалась, служба досталась в наследство от установки по умолчанию.
  4. Почистили список доверенных сетей и оставили только реальную подсеть офиса.
  5. Описали локальные правила на самой машине как второй рубеж.
  6. Перепроверили снаружи полным сканом и записали эталон в документацию. Теперь его прогоняют раз в квартал и сравнивают с эталоном.
# после работ, тот же внешний хост
$ nmap -Pn -p- --min-rate 800 203.0.113.44
PORT    STATE SERVICE
25/tcp  open  smtp
80/tcp  open  http
443/tcp open  https
587/tcp open  submission
993/tcp open  imaps
995/tcp open  pop3s
Not shown: 65529 filtered tcp ports

Теперь цена бездействия, в тех единицах, в которых её просят считать.

Наши 14 часов и одно ночное окно — это цена профилактики: по нашей ставке 3 500 ₽ в час — 49 000 ₽, один счёт, закрытый за три дня. Для сравнения: разбор уже случившейся компрометации почтового сервера у другого клиента занял три недели и 147 часов работ, то есть 514 500 ₽. Криптомайнер, поднятие прав через неаккуратно выданный sudo, а после первой чистки — повторное заражение через собственный юнит системного менеджера служб, который мы пропустили. Сервер в итоге вывели и мигрировали аварийно, без выбора платформы и графика. Десятикратная разница в счёте — и это ещё та часть, которую можно посчитать заранее.

Дальше идёт то, что считать неприятнее. Клиника на 24 места без почты один рабочий день — это 24 человека по 8 часов; даже по скромной себестоимости часа в 1 100 ₽ получается 211 200 ₽ фонда, который в этот день не отработан, плюс перенесённые приёмы, которые часть пациентов просто не переназначит.

Для клиники к этому добавляется то, чего у обычной компании нет. В почте лежат данные о здоровье пациентов — сведения особой категории. Их утечка это не только испорченная репутация в районе, где половина пациентов пришла по рекомендации соседей, но и предметный разговор с регулятором. Ориентир, который я называю клиентам вслух: по действующей редакции КоАП штраф юридическому лицу за утечку персональных данных измеряется миллионами рублей, для сведений о здоровье — верхней частью этой вилки, а при повторной утечке считается уже как доля годовой выручки. То есть самый мягкий сценарий там на два порядка дороже, чем 49 000 ₽ на закрытие периметра. А поскольку почтовый сервер входит в контур обработки персональных данных, уязвимости в нём — не абстракция: тот же postjournal-RCE и связанные с ним классы дыр учтены в банке данных угроз ФСТЭК, и при проверке смотрят именно туда.

Что делать, если вы обнаружили у себя то же самое

Порядок действий, если полный скан показал лишние порты:

  • Не начинайте с сервера. Начните со шлюза: там правило, которое всё это отдаёт. Заменить трансляцию всего адреса на список портов — это полчаса и никакого риска для работы почты, если в список попали 25, 443 и 587.
  • Только потом закрывайте на самой машине. Это второй рубеж, и он нужен, но он не заменяет первый.
  • Проверьте патч-уровень до того, как обрадуетесь. Закрытый порт не отменяет того, что могло произойти, пока он был открыт. Если 10027 торчал наружу месяцами при непокрытой уязвимости — надо смотреть логи, учётки, задания планировщика и содержимое системных каталогов на предмет чужого.
  • Запишите эталон. Список из шести-семи строк, который вы считаете правильным. Раз в квартал прогоняете скан и сравниваете. Расхождение — повод разбираться, а не пожимать плечами.

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

Первую сделайте сегодня сами, она того стоит. По второй — пришлите мне три вещи: вывод nmap -Pn -p- с внешнего адреса, вывод zmcontrol -v и вывод zmprov gcf zimbraMtaMyNetworks. За день отвечу, что у вас открыто, насколько это опасно при вашем патч-уровне и надо ли отдельно проверять сервер на следы. Если по этим трём выводам будет видно, что всё в порядке — так и напишу.

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

Почему обычный скан не показал опасные порты?

Потому что по умолчанию сканер проверяет тысячу самых распространённых портов, а не все шестьдесят пять тысяч. Служебные порты Zimbra — 7071 у административной консоли, 7072 у обработчика маршрутов, 10027 у postjournal — в эту тысячу не входят. Я на этом обжёгся в Одинцове: первый скан показал пять портов и «всё нормально», полный показал девять и четыре из них лишние. Правило простое: аудит периметра делается полным диапазоном и обязательно с адреса, который не входит в ваши доверенные сети.

Достаточно ли настроить файрвол на самом сервере?

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

Можно ли просто выключить postjournal и не патчить?

Выключить стоит в любом случае: вендор прямо рекомендует это для тех, кто службу не использует, а используют её единицы. Но заменой патча это не является. Во-первых, уязвимость в постжурнале — не единственная в вашей версии, если патч-уровень отстаёт на несколько выпусков. Во-вторых, служба может вернуться после следующего обновления, если её отключили не тем способом. Порядок такой: закрыть порт на периметре, выключить службу, поднять патч-уровень до того, где дыра закрыта — это 8.8.15 P46, 9.0.0 P41, 10.0.9 или 10.1.1 в зависимости от вашей ветки.

У нас Zimbra за обратным прокси. Это решает вопрос?

Частично и только для веб-трафика. Обратный прокси разбирает то, что пришло на 443, и это хорошо: вы получаете лишний слой фильтрации и можете спрятать за ним админ-консоль. Но прокси не имеет отношения к тому, что происходит на других портах. Если трансляция на шлюзе отдаёт весь адрес, то 7071, 10027 и 11211 останутся доступны в обход прокси. Проверяется это ровно тем же полным сканом снаружи — и я советую делать его после каждой перенастройки периметра, а не верить схеме на бумаге.

Как понять, успел ли кто-то воспользоваться открытым портом?

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

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

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

📞 Связаться с нами
#Zimbra#безопасность#периметр#порты#аудит
Комментарии 0

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

загрузка...

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

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

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

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