Назад к обновлениям
UpdatedAug 8, 2026

foxcage — Updated!

Запустите Firefox в rootless-контейнере Podman с удалёнными capabilities, изолированной сетью и эфемерным хранилищем, чтобы локализовать побеги из песочницы и предотвратить компрометацию хоста.

Поделиться

foxcage icon foxcage

Запускайте Firefox в rootless-контейнере Podman для изоляции безопасности. Ваш браузер работает практически без Linux-возможностей (capabilities), в собственном пользовательском и сетевом пространстве имён, изолированном от хоста — при этом сохраняя полное аппаратное ускорение GPU, звук и поддержку DRM.

Зачем нужен foxcage?

Firefox уже имеет многопроцессную песочницу, которая изолирует рендереры веб-контента с помощью пространств имён Linux и seccomp-bpf. Для большинства угроз этого достаточно. foxcage добавляет вторую стену: если злоумышленник эксплуатирует уязвимость, обходящую песочницу Firefox (такое случается — для этого существуют CVE), он попадает в изолированный контейнер, а не в вашу полноценную пользовательскую сессию.

От чего защищает foxcage

  • Доступ к файлам после эксплуатации. Побег из песочницы в обычном Firefox даёт доступ ко всему, что может прочитать ваш пользователь: ~/.ssh, ~/.gnupg, профили браузеров для других браузеров, базы данных менеджеров паролей, документы, исходный код. В foxcage злоумышленник видит только то, что вы явно смонтировали внутрь.
  • Остаточные следы на диске. Эфемерный контейнер @tmp не оставляет на диске никаких следов после закрытия окна — включая расширения, состояние HSTS, кэш TLS-сессий и DNS-кэш, которые Firefox в режиме приватного просмотра всё равно сохраняет. Несколько контейнеров @tmp работают одновременно, не мешая друг другу.
  • Постоянство (persistence). В обычном Firefox вредоносное ПО может записываться в ~/.config/autostart, ~/.bashrc, cron или куда угодно ещё, чтобы пережить перезагрузку. Эфемерный контейнер foxcage (--rm) означает, что ничего не сохраняется, если вы не смонтировали это через bind mount.
  • Латеральное перемещение по сети. По умолчанию контейнер не может опрашивать сервисы на localhost. В обычном Firefox побег из песочницы даёт полный сетевой доступ. (Используйте [network] mode = "host", если контейнеру нужен доступ к localhost, например для локальной разработки — но учтите предостережение в разделе «Сеть»: host-режим также открывает доступ к абстрактным Unix-сокетам хоста.)
  • Повышение привилегий. Контейнер отбрасывает все Linux-возможности, кроме CAP_SYS_CHROOT, и блокирует получение новых привилегий. Setuid-бинарники, эксплойты ядра через редкие системные вызовы и подобные пути повышения привилегий отсечены.

От чего foxcage не защищает

  • Атаки на уровне браузера. Фишинг, вредоносные расширения и всё, что действует в рамках обычной функциональности Firefox, не затрагивается — foxcage изолирует контейнер от хоста, а не пользователя от браузера.
  • Каталоги, смонтированные через bind mount. Всё, что вы монтируете внутрь (profile, downloads_dir, дополнительные bind mounts), полностью доступно скомпрометированному браузеру. Если вы смонтируете каталог профиля хоста, злоумышленник сможет вмешиваться в него так же, как в обычном Firefox.
  • Запись звука через PulseAudio. Сокет PulseAudio монтируется в контейнер через bind mount. Хотя на уровне файловой системы он смонтирован только для чтения, Unix-доменные сокеты двунаправленны — скомпрометированный процесс всё равно может отправлять запросы на запись через сокет. Побег из песочницы браузера потенциально может записывать звук с микрофона хоста.
  • Эксплойты Wayland-композитора. Сокет Wayland передаётся внутрь. Композиторы Wayland изолируют клиентов друг от друга по замыслу, но уязвимость в самом композиторе будет достижима.

Конфигурация безопасности

Контейнер запускается со следующими параметрами:

  • Все Linux-возможности отброшены (только CAP_SYS_CHROOT добавлен обратно для песочницы контента Firefox; CAP_SETUID/CAP_SETGID добавляются временно, когда настроен init.root)
  • no-new-privileges для предотвращения повышения привилегий
  • Rootless-пространство имён пользователя (--userns keep-id)
  • Приватный /dev/shm (не общий с хостом) — настраиваемый размер через shm_size
  • Изолированная сеть через pasta с блокировкой loopback хоста по умолчанию
  • DNS использует DNS хоста по умолчанию (настраивается через network.dns)
  • Внутрь монтируются только определённые сокеты из XDG_RUNTIME_DIR (Wayland, PulseAudio, PipeWire и фильтрованный прокси D-Bus) — полный каталог runtime хоста никогда не раскрывается
  • Доступ к шине D-Bus сессии хоста всегда опосредован фильтрованным xdg-dbus-proxy, работающим на хосте. Доступны только org.freedesktop.Notifications, org.freedesktop.portal.Desktop, org.mozilla.* и (для форков) собственное пространство имён форка (например, org.librewolf.*) — сервисы сессии, такие как связка ключей (keyring) и агенты SSH/GPG, заблокированы
  • Доступ к порталам широкий. org.freedesktop.portal.Desktop разрешён целиком, потому что именно так работают выбор файлов, «открыть ссылку в другом приложении» и демонстрация экрана. Он также открывает RemoteDesktop (синтетические клавиатура/мышь для всей сессии), Camera и Location. Они ограничиваются диалогами одобрения вашего рабочего стола, а не foxcage — и запрос RemoteDesktop похож на запрос демонстрации экрана, поэтому читайте диалоги одобрения перед их принятием. У xdg-dbus-proxy нет правила «запретить один интерфейс», поэтому сужение этого означает перечисление всех интерфейсов, которые нужны Firefox; см. docs/DESIGN.md о том, почему это не делается по умолчанию
  • Все bind mounts (profile, downloads_dir, дополнительные [mounts] bind) используют nosuid,noexec
  • Загрузка браузера проверяется по GPG-подписям: Firefox — по подписанным SHA-512 контрольным суммам Mozilla, LibreWolf — по отдельной подписи сопровождающих LibreWolf плюс сопутствующим SHA-256. Проверка строже, чем gpg --verify, который возвращает 0 для подписи, сделанной отозванным ключом, и для любого ключа в связке. foxcage дополнительно требует, чтобы подпись вела к закреплённому основному ключу, и отказывается от любого релиза, подписанного субключом, который его владелец отозвал как скомпрометированный — см. Отозванные ключи подписи
  • Эфемерный контейнер (--rm) — записи в файловую систему теряются при выходе
  • Никакие устройства хоста (веб-камера, ключи безопасности, принтеры) не передаются внутрь, если явно не включены

Каждая включённая вами опция [network] и [mounts] обменивает часть изоляции на удобство. Значения по умолчанию — это наиболее ограничительная конфигурация, которая всё ещё даёт вам рабочий браузер.

Требования

  • Python 3.11+
  • Podman (rootless)
  • Wayland-композитор (X11 не поддерживается)
  • pasta (sudo apt install passt) — если только network.mode = "host"
  • xdg-dbus-proxy (sudo apt install xdg-dbus-proxy)
  • PulseAudio или PipeWire с совместимостью с PulseAudio (для звука)
  • GPU с поддержкой DRI — необязательно; без /dev/dri foxcage выдаёт предупреждение, и Firefox рендерит программно. Драйверы VA-API для Intel, AMD и nouveau установлены в образе, поэтому аппаратное декодирование видео работает без пакетов драйверов хоста — см. Аппаратное декодирование видео

Запускайте foxcage как обычного пользователя рабочего стола, а не от root или через sudo — песочница отображает вашего пользователя в контейнер, а запуск от root устраняет изоляцию, ради которой существует foxcage. Он отказывается запускаться от root.

Протестированная среда: Debian 13 (Trixie) с GNOME 3. Другие дистрибутивы Linux и Wayland-композиторы могут работать, но не были протестированы.

Установка

foxcage — это один Python-скрипт без зависимостей за пределами стандартной библиотеки Python. Скопируйте его в каталог из вашего PATH:```sh sudo cp foxcage /usr/local/bin/foxcage

Или для установки в каталоге пользователя:```sh
cp foxcage ~/.local/bin/foxcage

Убедитесь, что скрипт исполняемый (chmod +x foxcage).

Категории