Вернуть одно удалённое письмо: dumpster, zmmailbox и флаг -A

Бухгалтерская фирма в Подольске, 12 рабочих мест. В июне 2022 их главбух удалила переписку по контракту, очистила корзину и через девять дней узнала, что письмо нужно в суд. Разворачивать весь сервер ради одного письма никто не собирался. Показываю три уровня возврата — от бесплатного за пять минут до архивного за сорок — и грабли с флагом, на которых я потерял час.

«Я удалила и очистила корзину, это вообще можно вернуть?»

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

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

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

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

Про эти три уровня и про то, где я на них спотыкался, — дальше.

Июнь 2022, Подольск: 12 мест, ящик на 31 ГБ

Клиент — небольшая бухгалтерская фирма на Подольском проспекте, ведёт учёт примерно у сорока юрлиц. 12 рабочих мест, 14 ящиков, Zimbra 8.8.15 Open Source на своей виртуалке. Почта у них — рабочий инструмент номер один: акты, счета, требования, переписка с инспекциями. Всё живёт в письмах. Файловой шары у них нет вообще.

Ящик главбуха на тот момент — 31 ГБ, около 96 тысяч писем, 227 папок, разложенных по клиентам. Она сама раз в квартал разбирает почту и чистит лишнее — привычка хорошая, но именно она и создала проблему.

История простая. 6 июня она удалила ветку переписки с подрядчиком по договору на сопровождение, ветка ушла в корзину. 7 июня почистила корзину. 15 июня клиент подал претензию, и понадобилось письмо от 12 марта, где подрядчик письменно согласовал перенос срока.

Позвонили мне 15-го в 16:40. Само письмо вернулось на следующее утро, с 09:30 до 10:04, — тридцать четыре минуты. А между звонком и этими тридцатью четырьмя минутами уместился вечер 15-го, который я целиком потратил на совершенно другую версию. С неё и начну, чтобы не делать вид, что всё прошло гладко.

Ложный след: час сорок в правилах фильтрации

Сначала я не поверил, что письмо удалено. У главбуха было 27 правил фильтрации, часть — с раскладкой по папкам клиентов, и я решил, что письмо просто уехало не туда. Версия удобная: ничего восстанавливать не надо, достаточно найти.

Я честно прогнал поиск по всему ящику, включая архивные папки. Даты в поиске Zimbra пишутся в американском порядке — месяц, день, год, — и первый прогон я сделал по январю вместо марта, просто набрав дату привычно. Правильно так:

su - zimbra
zmmailbox -z -m glavbuh@example.ru search -l 50 \
    'from:podryadchik.ru after:03/01/2022 before:04/01/2022'
zmmailbox -z -m glavbuh@example.ru getAllFilterRules

Ноль результатов. Все 27 правил проверил построчно — ни одно не отправляло письма этого отправителя в сторону. 1 час 40 минут ушло на то, чтобы убедиться: письма в ящике действительно нет.

Мораль для меня самого простая. Факт удаления проверяется первым делом, а не последним. Всё это время ответ лежал в /opt/zimbra/log/mailbox.log за 7 июня — одна строка с операцией очистки папки. 5 минут работы вместо ста.

grep -i 'glavbuh@example.ru' /opt/zimbra/log/mailbox.log.2022-06-07 | \
    grep -i 'emptyfolder\|itemaction.*op=delete' | head

Уровень 1: dumpster, и час, который я потерял на флаге

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

Проверяем, включён ли он вообще и сколько хранит:

su - zimbra
zmprov gc default zimbraDumpsterEnabled zimbraMailDumpsterLifetime
zmprov ga glavbuh@example.ru zimbraDumpsterEnabled

У клиента zimbraDumpsterEnabled стоял в TRUE, а zimbraMailDumpsterLifetime — 30 дней. Само по себе это удача: по умолчанию механизм выключен, и включить его кто-то должен был руками. Письмо удалили 7 июня, обратились 15-го. Восемь суток из тридцати. Успели с запасом. Если бы срок стоял 7 дней — а такое я вижу часто, — мы бы опоздали на сутки.

Пользователю возврат доступен прямо из веб-почты: правой кнопкой на корзине, «Восстановить удалённые». Там открывается окно поиска по dumpster, письмо перетаскивается обратно в папку. Главбух сделала это сама за две минуты, я только подсказал, куда нажать.

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

ERROR: service.PERM_DENIED (permission denied: cannot access dumpster)

Я перебирал права, класс обслуживания, административные роли. Час. Ошибка PERM_DENIED выглядит как проблема с ролями, хотя дело совсем в другом: zmmailbox требует флаг -A, иначе доступа к служебной области ящика у команды нет — даже под административной учёткой, даже с ключом -z.

# без -A — PERM_DENIED
zmmailbox -z -m glavbuh@example.ru -A emptyDumpster

Один символ. Час.

Уровень 2: развернуть архив нужной даты во временный ящик

Если срок хранения в dumpster вышел или он вообще выключен — идём в архив. Здесь важно не делать распространённую ошибку: не восстанавливать боевой ящик поверх самого себя.

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

su - zimbra
# 1. временный ящик
zmprov ca restore.tmp@example.ru 'Vremenn1y-Parol!' \
    displayName 'RESTORE TEMP' zimbraMailQuota 0

# 2. разворачиваем архив нужной даты
/opt/zimbra/bin/zmmailbox -z -m restore.tmp@example.ru -t 0 \
    postRestURL "//?fmt=tgz&resolve=reset" /backup/2022-06-05/glavbuh.tgz

# 3. нашли письмо — забираем его
#    и удаляем временный ящик
zmprov da restore.tmp@example.ru

Дальше письмо переносится в боевой ящик обычным способом. Главбух заходит во временный ящик через веб-почту и перетаскивает нужное к себе. Две минуты. Боевой ящик за всё это время не тронут ни разу — в нём как было 96 тысяч писем, так и осталось.

Если архива нужной даты нет в готовом виде, ящик выгружается с любого сервера, где он ещё цел, той же парой команд:

/opt/zimbra/bin/zmmailbox -z -m glavbuh@example.ru -t 0 \
    getRestURL "//?fmt=tgz" > /backup/glavbuh.tgz

Ключ -t 0 — бесконечный таймаут. На ящике в 31 ГБ без него выгрузка обрывается на середине, и это самая частая причина жалобы «у меня не работает getRestURL». Архив кладите не в /tmp, а на том с запасом: 31 ГБ почты дали примерно 22 ГБ архива. Я видел, как забитый /tmp ронял операцию на 80 процентах.

Почему resolve=reset нельзя направлять в боевой ящик

Здесь я хочу задержаться, потому что это место, где самостоятельная попытка превращается из «не получилось» в «стало хуже».

Режим resolve=reset означает буквально следующее: целевой ящик полностью очищается перед импортом. Не дополняется. Не сливается. Очищается.

Сценарий катастрофы выглядит так. Нужно вернуть письмо от 12 марта. Есть архив ящика от 5 июня. Человек находит в сети команду импорта — почти всегда именно с resolve=reset, потому что так написано в большинстве инструкций, — и запускает её прямо в боевой ящик. Письмо от марта возвращается. А всё, что пришло с 5 по 15 июня, исчезает: 10 суток переписки, включая ту самую претензию, ради которой всё затевалось.

Правило простое. resolve=reset направляется только во временный ящик, созданный десять минут назад и пустой. Есть режимы разрешения конфликтов, которые не очищают цель, но полагаться на них в спешке я не советую: разница между ними — один параметр в строке, а последствия ошибки необратимы.

Второй момент — время. Импорт ящика на 31 ГБ шёл у нас 58 минут. Прерывать его нельзя: обрыв на середине способен повредить базу ящика. Поэтому запуск строго в отсоединяемой сессии — screen или tmux, по вкусу. Я на этом обжигался в 2020-м, на другом клиенте и на другой задаче.

screen -S restore
/opt/zimbra/bin/zmmailbox -z -m restore.tmp@example.ru -t 0 \
    postRestURL "//?fmt=tgz&resolve=reset" /backup/2022-06-05/glavbuh.tgz
# Ctrl+A, D

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

Эти команды покажут, есть ли у вас вообще первый уровень возврата. Ничего не меняют.

su - zimbra -c 'zmprov gc default zimbraDumpsterEnabled zimbraMailDumpsterLifetime'
su - zimbra -c 'for c in $(zmprov gac); do zmprov gc $c zimbraDumpsterEnabled; done'
ls -1 /путь/к/бэкапу/ | tail -5
Что получилосьЧто это значит
zimbraDumpsterEnabled: FALSEПервого уровня у вас нет. Любое удалённое письмо сразу требует работы с архивом — это часы вместо минут. Включается одной командой.
Срок хранения меньше 30 днейТипичная просьба приходит на 7–14 день после удаления. При сроке в неделю вы регулярно будете опаздывать.
Классов обслуживания несколько, значение разноеЧасть сотрудников защищена, часть нет. Разбирается за пять минут, но обычно про это никто не знает.
Поящичных архивов в бэкапе нет, только образ машиныВторой уровень тоже недоступен. Ради одного письма придётся поднимать сервер целиком — это полдня.
Свежий архив ящика есть, дате больше месяцаВы вернёте письмо, но потеряете границу: всё, что нужно из последнего месяца, придётся искать в другом месте.

Включение и срок — 2 команды, применяются к классу обслуживания и подхватываются без перезапуска служб:

zmprov mc default zimbraDumpsterEnabled TRUE
zmprov mc default zimbraMailDumpsterLifetime 30d

Сколько это заняло и во что обошлось бы иначе

Возврат письма в Подольске занял 34 минуты: с 09:30 до 10:04 утра 16 июня. Из них 25 минут — проверка настроек и объяснение главбуху, куда нажимать. Плюс час сорок накануне вечером, потраченные мной на ложную версию, — их я в счёт не поставил, это моя цена, а не клиента. Счёт: одна консультация.

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

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

Дальше цифры сложились сами. За следующие три года у этой фирмы было одиннадцать обращений «верните письмо». Девять закрылись через dumpster за 10–20 минут. Два потребовали разворота архива во временный ящик — по 40 и 55 минут. Полного восстановления сервера не понадобилось ни разу.

Одиннадцать обращений по четыре часа — это 44 часа, которых не случилось.

Что я теперь ставлю всем на входе

Когда я беру на обслуживание чужую Zimbra, три вещи по этой теме делаются в первый же день, до всякого аудита.

  • Dumpster включён во всех классах обслуживания, срок — 30 дней. Дисковая цена есть, но умеренная: удалённые письма продолжают занимать место в /opt/zimbra/store ещё месяц вместо того, чтобы освободить его сразу. На ящиках с большим оборотом это видно, на обычных — теряется в погрешности.
  • Поящичные tgz по расписанию для трёх-четырёх самых критичных ящиков: бухгалтерия, руководитель, общий ящик компании. Остальные — раз в неделю. У фирмы в Подольске это 4 ящика ежедневно и 10 еженедельно, суммарно 61 ГБ архивов на диске.
  • Короткая инструкция для пользователей на полстраницы: «Восстановить удалённые» в веб-почте, что делать, если письма там нет, кому писать. Без неё люди не знают, что первый уровень вообще существует.

Последний пункт даёт больше всего. У бухгалтерской фирмы после появления инструкции 9 обращений из 11 закрылись без меня — люди вернули письма сами, за 10–20 минут каждое.

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

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

Сколько времени письмо лежит в dumpster и можно ли этот срок увеличить?

Срок задаётся в классе обслуживания и меняется одной командой. У большинства серверов, которые я вижу, стоит значение по умолчанию, а иногда механизм вообще выключен. Я ставлю 30 дней. Типичная просьба «верните письмо» приходит на 7–14 день после удаления, и месячного окна хватает почти всегда. Увеличивать сильно дальше смысла мало — письма всё это время занимают место в store, и на больших ящиках разница становится заметной. Если у вас есть требования по срокам хранения переписки, лучше решать их отдельным архивным механизмом, а не растягиванием dumpster до года.

Пользователь может сам вернуть письмо, без администратора?

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

Почему скрипт по dumpster падает с PERM_DENIED, если я работаю под администратором?

Потому что административного входа недостаточно. Ключа -z мало. Нужен ещё флаг -A у самой команды zmmailbox. Без него доступ к служебной области ящика не открывается, и вы получаете отказ по правам, который выглядит как проблема с ролями или классом обслуживания. Я потратил на это 60 минут: перебирал права, смотрел роли, менял класс обслуживания, читал /opt/zimbra/log/mailbox.log построчно. Всё оказалось в одном символе. Если пишете свои скрипты обслуживания — проверьте этот флаг первым делом, он экономит вечер.

Можно ли восстановить письмо в боевой ящик напрямую из архива?

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

Что делать, если dumpster был выключен и архива нужной даты тоже нет?

Остаются варианты, но они дороже и менее надёжны. Первое — почтовые клиенты: если человек работал через Outlook или мобильное приложение, локальная копия письма могла сохраниться на устройстве, даже когда на сервере её уже нет. Второе — вторая сторона переписки: письмо есть у отправителя или получателя, и запросить копию с корректной шапкой иногда быстрее всего. Третье — журналы сервера. Тело письма в /var/log/maillog не хранится, но факт и время доставки там есть, и в спорах это тоже имеет вес — при условии, что ротация не съела нужную дату. Полного восстановления содержимого это не заменит, поэтому первый уровень стоит включить заранее, а не после случая.

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

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

📞 Связаться с нами
#Zimbra#dumpster#восстановление#zmmailbox#почта
Комментарии 0

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

загрузка...

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

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

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

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