Инженерная практика Межотраслевые

Перенос заражённого NextCloud: 400 ГБ без докера за 7 часов

На старом облаке студии жил вирус, занесённый через докер. Вместо лечения — новый сервер, чистый NextCloud без контейнеров и перенос 400 ГБ ночными окнами: днём облако работало. 7 часов по трекеру.

7ч выполнено
Перенос заражённого NextCloud: 400 ГБ без докера за 7 часов

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

Проект одним взглядом

Отрасль конечного клиента digital-агентство / веб-студия
Конечный клиент студия с парком из 12+ VDS, Россия (под NDA)
Формат сотрудничества абонентская DevOps-поддержка, прямой договор
Тип проекта перенос внутреннего облака NextCloud с заражённого сервера на чистый
Объём работ ~400 ГБ файлов + база + все учётные записи; обновление через 5 мажорных версий
Дата проекта 10 июн 2024 – 4 сен 2024 (86 дней; активный перенос — ночные окна 23 авг – 2 сен)
Трудозатраты 7 ч по трекеру; ещё 6 ч — сопровождение до версии 32 в 2024–2025
Команда 2 специалиста (инженер-сисадмин · руководитель проекта)
Технологический стек NextCloud 24→29 · PHP · MySQL (utf8mb4) · occ CLI · Zabbix
Сдано облако на новом сервере без докера, NextCloud 29, домен переключён, бэкапы и планировщик перенастроены, старый сервер выведен

Постановка задачи

Облако NextCloud у студии — рабочий инструмент, а не архив. Туда ежедневно заливаются свежие бэкапы клиентских сайтов, чтобы разработчики могли развернуть любой проект локально. И на этом же сервере поселился вирус, которого прошлый администратор «не смог выкорчевать»: процессы периодически съедали ЦП, облако уходило в недоступность, рабочая практика свелась к «перезапускаем VDS и обычно норм». Однажды после такого перезапуска облако вернулось пятисотой ошибкой.

Запрос клиент сформулировал сам, прямо в задаче трекера: бороться с вирусом «долго, больно и дорого», проще развернуть на новом сервере последнюю версию NextCloud и перенести туда пользователей и файлы. Два жёстких условия. Первое: без докера. По словам бывшего админа, зараза залетела именно через контейнеры. Второе, дословно: «Главное чтобы вирусняк не перекочевал на новый сервер вместе с файлами».

Самое неприятное в таких переносах — не объём, а сочетание. 400 ГБ на канале в 11 МБ/с — это 11 часов копирования, и всё это время хранилищем кто-то хочет пользоваться. Выключить облако на сутки нельзя: разработчики останутся без развёртывания проектов. Скопировать «наживую» и переключить тоже нельзя: потеряются файлы, залитые во время копирования. А притащить вместе с данными старый исполняемый код — значит перевезти и вирус, ради избавления от которого всё затевалось. Любой из трёх промахов превращает плановую работу в инцидент.

Как мы это сделали

1. Новый сервер вместо лечения. Мы сами это рекомендовали, а не расписались в бессилии. Выкорчёвывать зловреда из работающей системы можно бесконечно: часы уходят, а гарантии, что вычистили всё, нет. Чистый сервер с переносом данных стоит предсказуемо и закрывает вопрос целиком. Пока клиент покупал сервер, старый дотянули костылём. В системный скрипт добавили автоматическое убийство процессов find, когда их накапливалось больше пяти: именно они загоняли сервер в высокий load average. 15 минут работы, и облако дожило до переноса без аварий по вине вируса.

2. Со старого сервера — только данные, ни байта кода. На новом сервере NextCloud развернули прямо в систему, из чистого дистрибутива последней версии: без контейнеров, на обычном PHP с MySQL (база пересоздана с нуля, utf8mb4). Со старой машины переехали ровно три вещи: директория data, config.php и дамп базы. Исполняемый код, главный подозреваемый в заражении, на новый сервер не попал вовсе.

3. Ночные окна вместо «большого переключения». Копирование 400 ГБ запустили вечером после согласования; самое длинное окно — 11 ч 56 мин, и эта цифра была названа клиенту заранее, вместе с арифметикой: 11 МБ/с × 400 ГБ ≈ 11 часов. К 8 утра старое облако включалось обратно. Днём разработчики работали как обычно. Финальную синхронизацию базы провели отдельным вечером, после чего старое облако перевели в режим обслуживания, чтобы база не расходилась, пока команда переезжает на новый адрес.

4. Ступенчатое обновление 24 → 25 → 26 → 27 → 28 → 29. План «поставим последнюю версию и подсунем старую базу» разбился о факт: NextCloud не обновляется с перескоком мажорных версий. Выяснили на месте, перестроились за вечер: прошли все 5 ступеней через occ из консоли, с проверкой клиента после первой. На версиях 28/29 платформа отключила 8 несовместимых приложений (calendar, contacts, deck, groupfolders, notes и другие). Полный список мы сразу отправили клиенту, не дожидаясь вопросов. Проверка с той стороны: «Доступы сохранились, файлы отображаются, скачиваются».

5. Root у разработчиков отобрали — взамен дали ровно одну команду. После переноса клиент попросил убрать у разработчиков root-доступ к облачному серверу. Сделали отдельного пользователя с правами только на одну папку данных и sudo-обёртку, которая запускает единственную команду: occ files:scan по конкретному пути. Скрипты заливки бэкапов работают, доступа к чужим файлам и к дереву NextCloud нет. 1,5 часа, закрыто за два дня.

Результаты

Метрика Значение
Перенесено данных ~400 ГБ + база + все учётные записи
Версия NextCloud 24 → 29 за один заход; в сопровождении — до 32
Простой в рабочие часы ночные окна по согласованию; к 8 утра облако включалось
Самое длинное окно 11 ч 56 мин (плановое, цифра названа заранее)
Часы по трекеру 7 ч — перенос; 1,5 ч — доступ без root; 4,5 ч — обновления до 32
Контроль после переноса проверка клиентом: учётки на месте, файлы открываются и скачиваются
Вирус остался на старом сервере; сервер погашен и списан

Если коротко: облако переехало на чистый сервер, поднялось на 5 мажорных версий и продолжило работать днём всё время переноса. Зловред остался на старой машине. Её подержали неделю выключенной на случай, если что-то забыли, и снесли. С тех пор облако живёт без докера и обновляется штатно.

Хвост сопровождения — отдельная часть истории. В марте 2025 обновление до 31-й версии потребовало поднять PHP с 8.2 до 8.3; веб-обновлялка падала на стадии бэкапа, так что прошли через консоль в согласованные выходные. По пути отвалились тема оформления и один плагин кэша. Оба факта клиент узнал из отчёта, а не из жалоб пользователей. Там же — фраза, которую редко услышишь от подрядчика, закрывающего задачу: «stable — это 30 версия, 31 — это beta, так что учтите, возможны странности». В октябре 2025 облако доехало до 32-й. Итого с момента переноса: 24 → 32, без потерь и без авралов.

Процесс

Фаза Когда Результат
Диагноз и костыль 10–13 июн 2024 старый сервер стабилизирован до переноса: авто-убийство лишних find (0,25 ч)
Подготовка нового сервера 23 авг чистый дистрибутив NextCloud, без докера (0,5 ч)
Ночное копирование 26–27 авг 400 ГБ перенесены за ночь, днём облако работало (1,5 ч)
Перенос БД, обновление до 25 27–28 авг облако живёт на новом сервере, клиент проверил файлы и доступы (1,5 ч)
Обновление до 29 29 авг 4 мажорные версии за вечер, отчёт об отключённых приложениях (1 ч)
Финиш 31 авг – 4 сен бэкапы, почта, планировщик, сертификат, переключение домена, старый сервер в shutdown (2,25 ч)
Хвост сопровождения сен 2024 – дек 2025 доступ без root для разработчиков; обновления 29→30→31→32 (6 ч)

Между постановкой задачи (10 июня) и активным переносом прошло два месяца: клиент покупал сервер и согласовывал приоритеты, старое облако в это время держал наш костыль. Сумма часов меньше календаря, потому что вся работа шла короткими ночными и вечерними окнами вокруг живого сервиса.

Команда

  • инженер-сисадмин (бюро) — перенос, ступенчатые обновления, sudo-доступ, сопровождение до версии 32
  • руководитель проекта (бюро) — согласование окон, контроль часов в трекере
  • на стороне клиента — руководитель направления: проверка после переноса, DNS, приоритеты

Если у вас тоже живёт сервис, который страшно трогать (заражённый, отставший на несколько мажорных версий или работающий в режиме «перезапустили и норм»), пришлите бриф или текущую техническую документацию. Мы прикинем объёмы, каналы и окна переноса и вернёмся с фиксированной оценкой в часах. Оценка переноса бесплатна.

Обсудить перенос →

Прокрутить вверх