Ограничение дискового пространства при распаковке архивов: как защитить систему от переполнения

Распаковка архива — операция, которая кажется безобидной ровно до момента, когда содержимое начинает заполнять диск быстрее, чем вы успеваете её остановить. Вредоносные «zip-бомбы», повреждённые архивы или просто невнимательность могут привести к тому, что система останется без свободного места: упадут базы данных, перестанут писаться логи, зависнут сервисы. Разумное решение — заранее ограничить доступное дисковое пространство для распаковки. Ниже разобраны основные способы сделать это в Linux, Windows и macOS, а также проверки, которые стоит выполнить до запуска распаковки.

Содержание
  1. Почему переполнение диска опаснее, чем кажется
  2. Главный принцип: считать до, а не после
  3. Шаг 1. Оцените размер содержимого архива до распаковки
  4. Ограничение этого подхода
  5. Шаг 2. Выберите механизм ограничения под свою задачу
  6. Отдельный раздел или том — самый надёжный вариант
  7. Квоты пользователей в Linux
  8. ulimit: ограничение размера файлов процесса
  9. Виртуальный диск для ручной работы в Windows и macOS
  10. Лимиты на уровне архиватора
  11. Признаки zip-бомбы и другие проверки перед распаковкой
  12. Типичные ошибки при работе с большими архивами
  13. Готовый порядок действий
  14. Сценарии: что выбрать в вашей ситуации
  15. Частые вопросы
  16. Можно ли доверять размеру, который показывает архиватор?
  17. Что делать, если распаковка уже заполнила диск?
  18. Помогает ли сжатие самого диска (NTFS compression, btrfs zstd)?
  19. Нужны ли ограничения, если я распаковываю свои собственные архивы?
  20. Что запомнить

Почему переполнение диска опаснее, чем кажется

Когда диск заполняется под завязку, страдает не только сама распаковка. На серверах свободное место нужно журналируемым файловым системам, СУБД, очередям сообщений и системным логам. Их отказ часто необратим: база данных может остановиться в некорректном состоянии, а почтовый сервер — потерять входящие письма. На рабочей станции последствия мягче, но тоже неприятны: браузер и приложения начинают сбоить, а очистка превращается в ручную работу.

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

Третий сценарий — банальная ошибка планирования: архив на 50 ГБ распаковывают в раздел, где свободно 40 ГБ. Процесс падает на середине, оставляя после себя частичные файлы, которые занимают место и требуют ручной уборки.

Главный принцип: считать до, а не после

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

  • файловые системы резервируют служебные структуры, а мелкие файлы занимают больше места из-за размера блока;
  • во время распаковки одновременно существуют и сам архив, и его содержимое;
  • другие процессы продолжают писать на тот же раздел.

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

Шаг 1. Оцените размер содержимого архива до распаковки

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

Linux и macOS:

  • unzip -l archive.zip — показывает список файлов и итоговый несжатый размер ZIP-архива;
  • tar -tvf archive.tar.gz — выводит содержимое tar-архива с размерами;
  • 7z l archive.7z — универсальный вариант для 7z, zip, rar и других форматов, в конце выводится суммарный размер.

Windows: встроенный проводник показывает содержимое архива, но неудобен для подсчёта суммы. Проще использовать 7-Zip: откройте архив, выделите всё содержимое — внизу отобразится распакованный размер. В командной строке с установленным 7-Zip работает команда вида 7z l archive.zip.

Сравните полученную сумму со свободным местом на целевом разделе (df -h /path в Linux и macOS, свойства диска в Windows). Если запаса нет — освободите место, выберите другой раздел или используйте принудительные ограничения.

Ограничение этого подхода

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

Шаг 2. Выберите механизм ограничения под свою задачу

Механизм Где работает Что ограничивает Когда подходит
Отдельный раздел или том фиксированного размера Все ОС Всё пространство целиком Серверная обработка, регулярная работа с чужими архивами
Квота пользователя Linux, Unix Данные конкретного пользователя Многопользовательские системы, FTP/SFTP-серверы
ulimit -f / cgroups Linux Размер записываемых файлов процесса или ресурсы группы процессов Автоматизация, скрипты, контейнеры
Виртуальный диск (VHD/DMG) фиксированного размера Windows, macOS Всё внутри образа Ручная работа с сомнительными архивами на рабочей станции
Настройки архиватора Зависит от программы Лимиты на количество файлов и коэффициент распаковки Сервисы приёма файлов, CI/CD

Отдельный раздел или том — самый надёжный вариант

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

В Linux это может быть отдельный LVM-том или обычный раздел, смонтированный, например, в /srv/incoming. В Docker-подобных средах ту же роль играют ограничения на размер слоя или volume. В Windows можно создать виртуальный диск VHD/VHDX фиксированного размера и монтировать его как отдельный букву диска — это не требует переразбивки физического накопителя.

Квоты пользователей в Linux

Если архивы распаковывают разные пользователи (например, через SFTP), включите квоты на нужной файловой системе и задайте жёсткий лимит (hard limit) для учётной записи. При превышении лимита запись блокируется, и распаковка завершается ошибкой вместо того, чтобы съесть весь диск. Конкретные команды настройки квот зависят от файловой системы (ext4, XFS, btrfs используют разные механизмы), поэтому уточняйте документацию вашей версии дистрибутива.

ulimit: ограничение размера файлов процесса

Команда ulimit -f N в Linux и других Unix-системах запрещает текущему сеансу создавать файлы больше N блоков (обычно блок равен 1024 байтам). Распаковщик, пытающийся записать больший файл, получит ошибку записи. Это простой способ остановить распаковку одного гигантского файла, например видеофайла внутри архива.

Пример последовательности для bash:

  1. Убедитесь, что находитесь в целевом каталоге распаковки.
  2. Задайте лимит: ulimit -f 1048576 (примерно 1 ГБ на один файл).
  3. Запустите распаковку: unzip archive.zip.
  4. После завершения проверьте результат и снимите лимит в новом сеансе либо командой ulimit -f unlimited, если политика системы позволяет.

Ограничение действует только на текущий сеанс и его дочерние процессы — глобальные настройки системы оно не меняет. Учтите также, что ulimit ограничивает размер отдельных файлов, но не суммарный объём всех файлов: тысяча файлов по 900 МБ пройдёт мимо лимита в 1 ГБ на файл. Для контроля суммарного потребления ресурсов процесса лучше подходят cgroups (группа управления ресурсами), где можно задать лимиты ввода-вывода и другие параметры, либо контейнеризация с ограничением размера хранилища.

Виртуальный диск для ручной работы в Windows и macOS

Разовый сценарий «распаковать подозрительный архив» удобно решать так:

  1. Создайте виртуальный диск фиксированного размера, например 10 ГБ (в Windows — «Управление дисками» → создание VHD; в macOS — образ DMG через «Дисковую утилиту»).
  2. Смонтируйте его как отдельный диск.
  3. Распакуйте архив внутрь.
  4. Осмотрите содержимое антивирусом, при необходимости перенесите нужное наружу.
  5. Отключите и удалите образ вместе со всем содержимым одним действием.

Фиксированный размер образа гарантирует, что даже zip-бомба не выйдет за его пределы. Это самый простой в освоении метод для тех, кто не хочет разбираться с квотами и ulimit.

Лимиты на уровне архиватора

Некоторые инструменты позволяют задать политику прямо при распаковке, что особенно ценно для автоматических сервисов приёма файлов:

  • Python-модуль zipfile начиная с версии 3.12 поддерживает параметр ограничения количества распакованных файлов и общего объёма данных (аргументы max_file_count и max_uncompress_size в функции extractall); в более старых версиях лимиты реализуют вручную, проверяя метаданные перед извлечением каждого элемента;
  • утилита 7-Zip и библиотека libarchive дают контроль над обработкой содержимого, а в связках с обёртками можно прерывать распаковку по достижении порога;
  • в собственных скриптах распаковки добавляйте счётчик: перед извлечением каждого следующего файла проверяйте, сколько уже записано, и прерывайте работу при превышении порога.

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

Признаки zip-бомбы и другие проверки перед распаковкой

Помимо оценки размера, обратите внимание на косвенные признаки проблемного архива:

  • Аномальный коэффициент сжатия. Обычные данные сжимаются в разы, максимум в десятки раз. Отношение распакованного размера к размеру архива в тысячи и более раз — повод остановиться и выяснить, что внутри.
  • Глубокая вложенность. Архив внутри архива внутри архива — классическая схема обхода поверхностных проверок. Решите заранее, сколько уровней вложенности вы готовы обрабатывать.
  • Огромное количество мелких файлов. Миллион файлов по несколько байт способен исчерпать не место, а inode (структуры файловой системы для учёта файлов). Диск будет «полон» при формально свободных гигабайтах. Лимит на количество файлов так же важен, как лимит на объём.
  • Совпадающие имена файлов. Некоторые архиваторы молча перезаписывают существующие файлы. Распаковка в чистый каталог с ключом отказа от перезаписи защищает ваши данные.
  • Пути выхода за пределы каталога. Уязвимость класса Zip Slip: имя файла в архиве содержит ../, и распаковщик пишет данные вне целевой папки. Современные версии популярных распаковщиков защищены, но старые скрипты и самописные решения — частый источник проблемы. Всегда проверяйте, что итоговые пути остаются внутри каталога назначения.

Типичные ошибки при работе с большими архивами

  • Распаковка в системный раздел. Каталоги вроде временных папок часто находятся на том же разделе, что и операционная система. Переполнение там бьёт по всей системе, а не только по вашей задаче.
  • Игнорирование промежуточного состояния. Если распаковка прервалась, частичные файлы остаются на диске. Заведите привычку удалять каталог назначения перед повторной попыткой.
  • Распаковка «на лету» из потока. Чтение архива напрямую из сети без сохранения лишает вас возможности оценить размер и повторить операцию. Для недоверенных источников сначала скачайте файл, проверьте его, затем распаковывайте.
  • Одна и та же учётная запись для всего. Если сервис приёма файлов работает от имени администратора, никакие квоты его не остановят. Выделите отдельную непривилегированную учётную запись с минимальными правами.
  • Отсутствие мониторинга. В автоматизированных конвейерах добавьте проверку свободного места перед запуском и оповещение при приближении к порогу — это дешевле, чем разбор последствий упавшей ночью базы данных.

Готовый порядок действий

  1. Определите источник архива. Собственный файл — достаточно оценки размера. Чужой файл — обязательны принудительные ограничения.
  2. Посмотрите содержимое и суммарный несжатый размер без распаковки.
  3. Проверьте свободное место на целевом разделе с запасом 20–30%.
  4. Выберите механизм ограничения: отдельный том, квота, ulimit, виртуальный диск или лимиты архиватора.
  5. Распаковывайте в чистый каталог на непривилегированной учётной записи, если источник недоверенный.
  6. Следите за количеством файлов, а не только за объёмом.
  7. После сбоя удалите частичные результаты перед повторной попыткой.

Сценарии: что выбрать в вашей ситуации

Разовая распаковка найденного или присланного архива дома. Создайте виртуальный диск на пару десятков гигабайт, распакуйте туда, проверьте антивирусом, удалите образ. Быстро, безопасно, без изменения настроек системы.

Регулярная обработка пользовательских загрузок на сервере. Выделите отдельный том под входящие файлы, включите квоты, запускайте обработку от непривилегированного пользователя, задайте лимиты на количество файлов и суммарный объём в коде распаковки. Добавьте алерт на заполненность тома.

CI/CD или фоновые задачи. Используйте контейнеры с ограничением размера хранилища либо отдельный том под рабочие артефакты. Перед распаковкой проверяйте метаданные архива и отклоняйте файлы с аномальным коэффициентом сжатия.

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

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

Можно ли доверять размеру, который показывает архиватор?

Для своих файлов — да, метаданные обычно корректны. Для файлов из недоверенных источников — нет: значения в заголовке можно подделать. Именно поэтому оценка размера дополняется принудительными ограничениями на уровне системы или кода.

Что делать, если распаковка уже заполнила диск?

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

Помогает ли сжатие самого диска (NTFS compression, btrfs zstd)?

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

Нужны ли ограничения, если я распаковываю свои собственные архивы?

Строгие лимиты избыточны, но быстрая проверка размера перед распаковкой полезна всегда: она стоит секунды и избавляет от ситуации «процесс упал на 90%». Достаточно сравнить несжатый размер со свободным местом.

Что запомнить

Безопасная распаковка строится на трёх опорах: знать объём результата заранее, физически ограничивать возможный ущерб и не доверять архивам из недоверенных источников. Самая надёжная защита — отдельный том фиксированного размера; самые гибкие инструменты — квоты, ulimit и лимиты в коде распаковки; самый простой вариант для разовой задачи — виртуальный диск. Начните с малого: перед следующей распаковкой выполните команду просмотра содержимого архива и сверьте итоговый размер со свободным местом. Эта одна привычка предотвращает большинство инцидентов, а для регулярной работы с чужими файлами добавьте к ней отдельный том и лимит на количество файлов.

PEFile.ru