Backup лише через pull: чому production ніколи не повинна діставатися власних резервних копій
Як спроєктувати резервні копії, які зловмисник на production не зможе видалити: pull з боку backup, ключі, замкнені на одну команду, append-only репозиторії, prune локально.

Більшість дизайнів резервного копіювання побудовані для відмови, яку всі уявляють: мертвий диск, видалена таблиця, зламане оновлення. Відмова, яка насправді закінчує компанії, інша. Хтось потрапляє на production-сервер, знаходить облікові дані backup, що лежать просто там, і видаляє резервні копії, перш ніж зашифрувати все інше. Ця стаття пояснює, як спроєктувати резервні копії, які переживуть той день, за схемою, за якою будуємо ми: сторона backup тягне (pull), production ніколи не штовхає (push), а ключі, які створюють резервні копії, не можуть їх знищити.
Проблема з push
Найпростіший backup є cron-завданням на сервері, яке копіює дані на ціль резервного копіювання. Його легко налаштувати, і воно несе структурну ваду. Щоб штовхати, production-сервер потребує маршруту до цілі backup і облікових даних, які можуть на неї писати. Дуже часто ці облікові дані можуть також видаляти, перезаписувати або чистити, бо зберігання має відбуватися десь, і клієнт є очевидним місцем.
Отже, сервер, який ви захищаєте, тримає ключі до власного захисту. Хто володіє цим сервером, той володіє його резервними копіями. Оператори ransomware це знають, і перше, що робить компетентне вторгнення, це шукає агенти backup, змонтовані спільні ресурси backup і SSH-ключі, що вказують на хости сховища.
Монтування спільного ресурсу backup на production-хості є найгіршою формою цього. Ресурс, доступний для запису з production, з погляду атакувальника є просто ще одним диском для шифрування.
Розверніть стрілку
Виправлення: змінити напрямок довіри. Система backup ініціює кожне з’єднання. Вона заходить у production, бере те, що їй потрібно, і йде. Production не має мережевого шляху до інфраструктури backup і не тримає для неї облікових даних.
Забезпечте це там, де скомпрометований хост не може це скасувати: на firewall-пристрої між двома зонами, а не в host firewall сервера backup. Набір правил короткий:
permit ip <management-subnet> host <backup-host> ! admin access only
deny ip any host <backup-host> ! production and everyone else
permit ip any any ! leave other traffic alone
Самому хосту backup потрібен вихідний доступ до production на портах, які він використовує для збору даних, і нічого вхідного, крім як з management. Якщо з’єднання з production-хоста досі вдається, дизайн не діє, хоч би що казала схема.
За духом це схема data-diode, і вона чисто відображається на контролі, про який питають аудитори: сегрегація інфраструктури backup, найменші привілеї і захист периметра в ISO/IEC 27001, NIS2 і NIST SP 800-53.
Найменші привілеї на боці production
Pull усе одно означає, що хост backup входить у production. Цей вхід має бути марним для будь-чого, крім зняття резервної копії. З SSH це просто: дайте ключу хоста backup forced command і опцію restrict в authorized_keys на production-сервері.
command="rrsync -ro /srv/www",restrict ssh-ed25519 AAAA... backup-files
command="/usr/local/bin/backup-dump",restrict ssh-ed25519 AAAA... backup-db
Перший ключ може лише читати web root через rrsync у режимі лише для читання. Другий може лише запускати обгортку дампу, яку написали ви, яка знімає консистентний дамп бази даних (для MySQL або MariaDB з репліки або вузла, що не приймає запис, з --single-transaction або фізичним інструментом, таким як Percona XtraBackup) і передає його в стандартний вивід. Жоден ключ не дає shell, port forwarding або agent forwarding. Якби сам хост backup був скомпрометований, атакувальник отримав би доступ на читання до даних одного клієнта, а не контроль над production.
Використовуйте окремі ключі для окремих завдань і окремі ключі для окремих клієнтів. Радіус ураження має бути одним завданням на одному клієнті.
Зробіть репозиторій append-only
Друга половина дизайну стосується того, що відбувається на боці backup. З BorgBackup, архіватором з дедуплікацією, стисненням і шифруванням, до репозиторію можна звертатися в режимі append-only: нові архіви можна писати, але наявні дані не можна видалити або переписати через цей шлях доступу.
Коли сам Borg має працювати на джерелі (наприклад, тому що web root містить мільйони дрібних файлів і ви хочете, щоб дедуплікація відбувалася до того, як дані перетнуть мережу), ви все одно можете лишити hub головним. Hub відкриває SSH-сесію до production-хоста і надає зворотний тунель назад до себе, а обліковий запис на дальньому кінці цього тунелю замкнений на hub:
command="borg serve --append-only --restrict-to-repository /srv/backup/tenants/<customer>/borg",restrict ssh-ed25519 AAAA... customer-node
Production-хост ніколи нічого не ініціює; він лише говорить назад через тунель, який відкрив hub, і лише зі своїм власним репозиторієм, у режимі append-only.
Зберігання тоді стає окремим, локальним завданням на hub:
borg prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 /srv/backup/tenants/<customer>/borg
borg compact /srv/backup/tenants/<customer>/borg
Запускайте його як привілейоване завдання на самому хості backup, ніколи через шлях, який бачить production. Атакувальник, який шифрує сервер клієнта, може щонайгірше записати більше архівів. Видалити старі він не може.
Один репозиторій, один ключ, один клієнт
На платформі backup для багатьох клієнтів дайте кожному клієнту власний репозиторій і власну парольну фразу, зі шифруванням, увімкненим при створенні репозиторію:
borg init --encryption=repokey-blake2 /srv/backup/tenants/<customer>/borg
Ізоляція тоді тримається на криптографічному рівні, а не лише у правах на файли: дані одного клієнта не можна прочитати ключем іншого клієнта, навіть маючи shell на hub. Дедуплікація й далі добре працює всередині клієнта, а між майже ідентичними web-вузлами одного клієнта другий вузол майже нічого не коштує.
Доводьте, а не довіряйте
Зелене завдання backup каже вам, що завдання виконалося. Воно не каже, що кожна машина, яка має значення, була охоплена, або що дані повертаються. Три звички закривають цю прогалину.
Перевіряйте охоплення проти живого інвентарю. Перелічіть, що працює, перелічіть, що має свіжу резервну копію на диску, і порівняйте. Усе, що працює без недавньої точки відновлення, є знахідкою.
Стежте за свіжістю, а не за статусом. Ставте тривогу на «годин від останнього вдалого архіву» на клієнта, щоб завдання, яке мовчки перестало виконуватися, помічалося швидко.
Відновлюйте за розкладом. Витягайте файли, відновлюйте базу даних у тимчасовий інстанс і перевіряйте, регулярно. Borg робить це дешевим:
borg list /srv/backup/tenants/<customer>/borg
borg extract --dry-run /srv/backup/tenants/<customer>/borg::<archive>
borg check --verify-data /srv/backup/tenants/<customer>/borg
Відновлення також дотримуються правила «лише pull». Хост backup або інженер доставляє відновлені дані у production. Production ніколи не отримує доступу до репозиторію, навіть «лише для відновлення».
Що перевірити на власній платформі
- Чи може будь-який production-сервер відкрити з’єднання до вашого сховища backup? Спробуйте.
- Чи дозволяють будь-які облікові дані на production-сервері видалення або чищення резервних копій?
- Чи змонтований на будь-якому production-хості спільний ресурс backup, доступний для запису?
- Чи обмежені ключі backup однією командою, чи вони дають shell?
- Чи кожен клієнт або система має власний зашифрований репозиторій із власним ключем?
- Коли ви востаннє щось відновлювали і чи перевірили результат?
Якщо якась відповідь вас непокоїть, почніть із правила firewall. Це найдешевший контроль у цьому списку, і він першим прибирає найнебезпечніший шлях.
Якщо ви хотіли б другу пару очей на своєму дизайні резервного копіювання, наші інженери радо допоможуть. Поговоріть з інженером
Related
Пов’язане: Managed backup на Veeam і Borg, лише pull · Disaster recovery і репліки між майданчиками
Опубліковано 10 серпня 2026 р..
Усі нотатки з практики