- Зачем: - Профили на пути установки Codex ломались после переустановки, а прежние проверки могли давать ложный успех. - Что: - Штатный профиль системного bwrap выбран основным способом настройки; исторические обходы ограничены подтверждёнными случаями. - Уточнены диагностика, переход со старых профилей и проверки режимов и границ записи. - Обновлены связанные инструкции и записан результат применения на Ubuntu 24.04.4 с Codex 0.154.0. - Проверка: - Пройдены quick_validate, проверка ссылок, синтаксиса Bash и git diff --check. - Штатный профиль применён; старые профили выгружены. Оба режима и запреты записи проверены из процесса unconfined; подтверждены метки AppArmor у bwrap и дочерней команды.
158 lines
12 KiB
Markdown
158 lines
12 KiB
Markdown
# Песочница Codex на Linux: проверка и настройка AppArmor
|
||
|
||
Читай при первом запуске на Linux/WSL, после смены версии или установки
|
||
Codex и при отказе команд внутри песочницы. Основной путь — системный
|
||
`bwrap` со штатным профилем AppArmor. Способ запуска проверяй по фактам:
|
||
номер версии сам по себе не доказывает выбор встроенного или системного bwrap.
|
||
|
||
## 1. Проверь запуск в нужной среде
|
||
|
||
Из рабочего каталога проекта выполни оба вызова тем же способом, которым
|
||
будет запущен исполнитель или ревьюер:
|
||
|
||
```bash
|
||
codex sandbox -c 'sandbox_mode="read-only"' -- sh -c 'pwd && echo READ_OK'
|
||
codex sandbox -c 'sandbox_mode="workspace-write"' -- sh -c \
|
||
'set -eu; probe=$(mktemp ./.codex-sandbox-check.XXXXXX); rm -- "$probe"; echo WRITE_OK'
|
||
```
|
||
|
||
Успех — нулевой код выхода и соответствующий маркер от каждой команды.
|
||
Это проверка запуска; проверка запретов записи — в разделе 4.
|
||
Работающий `web_search` ничего не говорит о выполнении shell-команд.
|
||
|
||
Если в конфигурации остался `use_legacy_landlock=true`, для проверочных
|
||
вызовов добавь `-c 'features.use_legacy_landlock=false'`: проверяем штатную
|
||
песочницу, а не старый обход.
|
||
|
||
## 2. Установи причину отказа
|
||
|
||
`bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted` — повод
|
||
проверить AppArmor, но не достаточный диагноз. Собери:
|
||
|
||
```bash
|
||
codex --version
|
||
cat /etc/os-release
|
||
type -a codex bwrap
|
||
sysctl kernel.apparmor_restrict_unprivileged_userns
|
||
cat /proc/self/attr/current
|
||
```
|
||
|
||
Проверь журнал ядра за время неудачного вызова: записи `apparmor="DENIED"`
|
||
для `userns_create`, `uid_map` или настройки сети подтверждают ограничение
|
||
AppArmor. Отсутствие доступа к журналу — пробел в диагностике, а не
|
||
доказательство причины. При отказе доступа к
|
||
`codex-bwrap-synthetic-mount-targets` сравни минимальный вызов из среды
|
||
агента и из обычного терминала хоста. Если на хосте он работает, исследуй
|
||
ограничения внешней песочницы и способ запуска агента; профиль AppArmor
|
||
пока не считай причиной. Если вызов падает и на хосте, а причина по
|
||
доступным данным не установлена, сохрани точную ошибку и результаты обоих
|
||
запусков; запроси недостающие записи журнала за это время. До подтверждения
|
||
причины рецепт AppArmor не применяй.
|
||
|
||
По [документации OpenAI](https://learn.chatgpt.com/docs/sandboxing#prerequisites)
|
||
Codex выбирает первый `bwrap` из `PATH`, а при его отсутствии использует
|
||
встроенный. Проверяй `PATH` именно запускающего процесса: оболочка,
|
||
редактор и агент могут видеть разные установки. При расхождении с этим
|
||
поведением установи фактический исполняемый файл дочернего bwrap через
|
||
`/proc/<pid>/exe` или трассировку `execve`/`execveat`; одного `command -v`
|
||
для этого недостаточно.
|
||
|
||
## 3. Настрой системный bwrap
|
||
|
||
Если подтверждена блокировка AppArmor, используй пакет `bubblewrap` и
|
||
профиль `bwrap-userns-restrict` из дистрибутива. Путь в профиле должен
|
||
соответствовать фактически запускаемому bwrap. При другой копии в `PATH`
|
||
сначала приведи запуск к системной установке.
|
||
|
||
Для Ubuntu 24.04 официальный рецепт использует пакеты:
|
||
|
||
```bash
|
||
sudo apt update
|
||
sudo apt install bubblewrap apparmor-profiles apparmor-utils
|
||
```
|
||
|
||
Если `/etc/apparmor.d/bwrap-userns-restrict` уже существует, изучи его;
|
||
локальные изменения сохрани. Если файла нет, проверь наличие штатного
|
||
образца и установи его:
|
||
|
||
```bash
|
||
test -f /usr/share/apparmor/extra-profiles/bwrap-userns-restrict && \
|
||
sudo install -m 0644 /usr/share/apparmor/extra-profiles/bwrap-userns-restrict \
|
||
/etc/apparmor.d/bwrap-userns-restrict
|
||
```
|
||
|
||
Загрузи профиль без перезагрузки машины:
|
||
|
||
```bash
|
||
sudo apparmor_parser -r /etc/apparmor.d/bwrap-userns-restrict
|
||
```
|
||
|
||
В Ubuntu 25.04 профиль поставляется пакетом `apparmor`; на других выпусках
|
||
проверь состав пакетов. Если образца нет или загрузка не удалась, останови
|
||
этот рецепт и выясни совместимость пакетов и AppArmor по документации
|
||
дистрибутива. Отсутствующий профиль не заменяй расширением разрешений всей
|
||
машины или отключением песочницы.
|
||
|
||
Установка пакетов и изменение профилей — настройка машины. Выполняй её в
|
||
пределах уже разрешённой задачи; если настройка среды не разрешена, сначала
|
||
подготовь конкретные команды по результатам диагностики и запроси согласие.
|
||
|
||
## 4. Проверь результат и убери старый обход
|
||
|
||
Повтори оба вызова из раздела 1. Затем проверь границы записи, явно задавая
|
||
режим каждому вызову:
|
||
|
||
- `read-only`: чтение работает, создание временного файла внутри проекта
|
||
запрещено.
|
||
- `workspace-write`: создание и удаление временного файла внутри проекта
|
||
работает; запись за пределами разрешённых каталогов запрещена.
|
||
|
||
Для проверки запрета используй отдельный временный каталог, в который тот
|
||
же пользователь может записать вне проверяемой песочницы. Отказ засчитывай
|
||
только после успешного запуска команды и как запрет доступа, а не любую
|
||
ошибку. `/etc` не подходит: запись туда обычно запрещена уже правами Unix;
|
||
`/tmp` не подходит для проверки внешнего запрета, если разрешён политикой.
|
||
Удали только созданные проверкой файлы и каталоги.
|
||
|
||
Если раньше был установлен профиль на бинарь Codex (например,
|
||
`codex-bwrap` с секциями `codex-cli*`), одного успешного прогона недостаточно:
|
||
дочерние процессы могут наследовать его разрешения. При переходе сохрани
|
||
старый профиль для отката, выведи его из автозагрузки и выгрузи его секции
|
||
из ядра. Запусти проверку из новой оболочки, не унаследовавшей старую метку
|
||
AppArmor, и новым процессом Codex. Продолжение прежней сессии не доказывает
|
||
независимость от обхода. При неудаче восстанови старую настройку и сохрани
|
||
диагноз; переход не завершён.
|
||
|
||
Готово, когда оба режима и запреты записи проверены, а при переходе со
|
||
старого профиля — ещё и подтверждена независимость от него. После этого
|
||
убери оставшийся `use_legacy_landlock` из конфигурации. Если системная
|
||
настройка не выполнялась, различай «инструкция подготовлена» и
|
||
«песочница на этой машине исправлена».
|
||
|
||
## Исторические обходы и границы применимости
|
||
|
||
- **2026-07-10, Codex 0.144.1, Ubuntu 24.04.** Наблюдался запуск встроенного
|
||
bwrap через `memfd`: профиль на дисковый файл bwrap не применялся.
|
||
Профиль на сам бинарь Codex с разрешением `userns` помог. Это запасной
|
||
вариант для подтверждённого встроенного запуска, если перейти на
|
||
поддерживаемый системный bwrap нельзя; путь определяют на конкретной
|
||
машине, ограничивая его текущей установкой.
|
||
- **Тогда же:** `use_legacy_landlock=true` помогал read-only, но
|
||
workspace-write завершался ошибкой несовместимости. Для конвейера,
|
||
которому нужна запись, это не решение.
|
||
- **2026-09-10, Codex 0.154.0.** Смена npm-установки на standalone вывела
|
||
бинарь из-под старого профиля; добавление второго пути устранило симптом.
|
||
Затем этот рецепт применён на Ubuntu 24.04.4: штатный профиль из
|
||
`apparmor-profiles` 4.0.1really4.0.1-0ubuntu0.24.04.7 установлен без
|
||
изменений, старые профили Codex выгружены и убраны из автозагрузки.
|
||
Из процесса `unconfined` проверены чтение, запрет записи в read-only,
|
||
запись внутри workspace-write и запрет снаружи; перед проверкой обычная
|
||
пользовательская запись в оба временных каталога проходила.
|
||
Через `/proc` подтверждены `/usr/bin/bwrap` с меткой `bwrap (enforce)`
|
||
и дочерняя команда с `bwrap//&unpriv_bwrap (enforce)`.
|
||
`apparmor_restrict_unprivileged_userns=1` сохранён, legacy-обход отсутствует.
|
||
|
||
Наблюдения относятся к указанным установкам, а не ко всем версиям Codex.
|
||
Штатный рецепт и состав пакетов сверены с документацией OpenAI 2026-09-10.
|
||
Связанная запись: [lessons-archive.md](lessons-archive.md).
|