Jump to content
From ArchWiki

Состояние перевода: На этой странице представлен перевод статьи chroot. Дата последней синхронизации: 30 января 2022. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Ссылки по теме

- PRoot
- Linux Containers
- systemd-nspawn

Chroot — операция изменения корневого каталога диска для запущенного процесса и его дочерних процессов. Программа, запущенная в таком окружении, не может получить доступ к файлам вне нового корневого каталога. Это измененное окружение называется chroot jail.

## Причины

Изменение корневого каталога обычно производится при обслуживании системы, загрузка и/или вход в которую стали невозможны. В таком режиме, например, могут быть выполнены:

- Переустановка загрузчика.
- Пересборка образа initramfs.
- Обновление или откат пакетов.
- Сброс пароля root.
- Сборка пакетов в чистом окружении, смотрите DeveloperWiki:Building in a clean chroot.

Смотрите также Wikipedia:Chroot#Limitations.

## Требования

- Наличие привилегий суперпользователя.
- Возможность загрузки с другой среды Linux, например, LiveCD, загрузочного USB-носителя или другого установленного дистрибутива.
- Совпадение архитектур двух сред: с которой производится загрузка и в которую происходит изменение корня. Архитектуру текущей среды можно узнать командой `uname -m` (например, i686 или x86_64).
- Если среде chroot необходимы какие-нибудь модули ядра, они должны быть загружены.
- Если нужен раздел подкачки, он должен быть включен: `# swapon /dev/sdxY`.
- Интернет-соединение установлено, если нужно.

## Использование

Примечание:

- Некоторые инструменты systemd, такие как hostnamectl, localectl и timedatectl, не работают внутри внутри chroot, поскольку они требуют активного dbus-соединения. [1]
- Файловая система, которая станет новым корнем (`/`), должна быть доступна (т.е. расшифрована, смонтирована).

Есть два варианта использования chroot.

### Используя arch-chroot

Bash-скрипт `arch-chroot` является частью пакета arch-install-scripts. Перед запуском `/usr/bin/chroot` он монтирует нужные виртуальные файловые системы, например `/proc`, и делает `/etc/resolv.conf` доступным из chroot.

#### Переход в chroot

Запустите arch-chroot с указанием нового корневого каталога:

    # arch-chroot /путь/к/новому/корню

Например, руководство по установке использует каталог `/mnt`:

    # arch-chroot /mnt

Выход из chroot простой:

    # exit

#### Запуск одной команды и выход

Чтобы запустить команду из chroot и сразу выйти, добавьте команду в конец строки:

    # arch-chroot /путь/к/новому/корню команда

Чтобы запустить `mkinitcpio -p linux` в окружении chroot минуя создание сеанса в командной оболочке:

    # arch-chroot /mnt/arch /usr/bin/mkinitcpio -p linux

### Используя chroot

Важно: При использовании `--rbind` некоторые подкаталоги `dev/` и `sys/` не будут размонтированы. Попытка размонтирования с помощью `umount -l` в такой ситуации сломает ваш сеанс, и потребуется перезагрузка. По возможности используйте вместо этого `-o bind`.

В данном примере `/путь/к/новому/корню` является каталогом, который станет корнем файловой системы внутри chroot.

Смонтируйте временные интерфейсные файловые системы:

    # cd /путь/к/новому/корню
    # mount -t proc proc proc/
    # mount -t sysfs /sys sys/
    # mount --rbind /dev dev/

И, опционально:

    # mount --rbind /run run/

Если у вас UEFI, вам также может поднадобиться доступ к переменным EFI. Без них попытка установки GRUB приведёт к ошибке вроде `UEFI variables not supported on this machine`:

    # mount --rbind /sys/firmware/efi/efivars sys/firmware/efi/efivars/

Чтобы использовать интернет-соединение в chroot может понадобиться скопировать resolv.conf:

    # cp /etc/resolv.conf etc/resolv.conf

Чтобы запустить bash в окружении chroot:

    # chroot /путь/к/новому/корню /bin/bash

Примечание: Если вы получили ошибки:

- `chroot: cannot run command '/usr/bin/bash': Exec format error`, это значит, что архитектуры основной среды и среды нового корневого каталога не совпадают.
- `chroot: '/usr/bin/bash': permission denied`, перемонтируйте раздел с разрешением exec: `mount -o remount,exec /mnt/arch`.
  - Если это не помогает, убедитесь, что базовые компоненты новой среды не повреждены (если это корень Arch, попробуйте `paccheck --root=/путь/к/новому/корню --files --file-properties --md5sum glibc filesystem` из пакета pacutils)

После входа в сеанс chroot может понадобиться проинициализировать среду командной оболочки в новой среде:

    # source /etc/profile
    # source ~/.bashrc

Совет: Вы также можете установить другое приглашение командной оболочки для того, чтобы отличать среду chroot от основной:

    # export PS1="(chroot) $PS1"

После завершения работы выйдите из сеанса chroot:

    # exit

Теперь размонтируйте временные файловые системы и корневой раздел:

    # cd /
    # umount --recursive /путь/к/новому/корню

Примечание: Если есть ошибки вроде `umount: /path: device is busy`, это обычно означает, что либо какая-то программа (даже командная оболочка) осталась запущенной в chroot, либо что-то внутри всё ещё примонтировано. Выйдите из программы и используйте `findmnt -R /путь/к/новому/корню` чтобы найти и затем размонтировать оставшиеся точки монтирования. Может быть несколько непросто размонтировать некоторые вещи, и можно понадеяться, что сработает `umount --force`. В качестве последнего средства используйте `umount --lazy`, который просто освобождает устройства. В любом случае, чтобы перестраховаться, перезагрузитесь как можно скорее, если эти проблемы не решены, чтобы избежать возможных конфликтов в будущем.

## Запуск графических приложений в среде chroot

Если у вас есть запущенный X-сервер, вы сможете запускать даже графические приложения в среде chroot.

Чтобы разрешить среде chroot соединение с сервером X, откройте виртуальный терминал внутри сервера (то есть, внутри рабочего стола пользователя, который в данный момент вошел в систему), запустите команду xhost, которая даст права каждому подключаться к X-серверу пользователя:

    $ xhost +local:

Теперь, для соединения приложений с сервером X, установите переменной окружения DISPLAY в сеансе chroot значение, совпадающее с переменной окружения DISPLAY пользователя, от имени которого запущен сервер. То есть, выполните

    $ echo $DISPLAY

от имени этого пользователя для того, чтобы узнать значение переменной, и выполните

    # export DISPLAY=:0

в среде chroot, установив переменной нужное значение (в данном примере это `:0`).

## Без прав суперпользователя

Chroot требует привелегий суперпользователя, что может быть нежелательно. Однако, есть несколько способов симулировать работу chroot, используя альтернативные реализации.

### PRoot

PRoot может использоваться для изменения корневого раздела и использовать `mount --bind` без привелегий суперпользователя. Это полезно для ограничивания доступа приложений до единственного каталога или запуска программ, собранных для другой архитектуры. Однако PRoot имеет ограничения, связанные с тем, что все файлы принадлежат пользователю на основной системе. PRoot предоставляет опцию `--root-id`, которая может быть использована в качестве обходного пути для этих ограничений, по тому же принципу (хотя и более ограниченно), что и в fakeroot.

### Fakechroot

fakechroot является небольшой прослойкой, которая перехватывает системные вызовы chroot и симулирует поведение системы, на самом деле не выполняя реальных вызовов (на которые все равно нет прав). Он может использоваться вместе с fakeroot для создания видимости того, что chroot запускается суперпользователем.

    # fakechroot fakeroot chroot ~/my-chroot bash

### Unshare

Unshare можно использовать для создания нового пространства имён в ядре. Он входит в состав пакета util-linux. Он работает с обычной командой chroot. Пример:

    $ unshare --map-root-user chroot ~/namespace /bin/sh

## Решение проблем

### arch-chroot: /путь/к/новому/корню is not a mountpoint. This may have undesirable side effects.

При выполнении `arch-chroot /путь/к/новому/корню` может появиться такое предупреждение:

    ==> WARNING: /путь/к/новому/корню is not a mountpoint. This may have undesirable side effects.

Объяснение этого можно прочитать в arch-chroot(8); там же вы найдёте пример, как превратить каталог в точку монтирования с помощью bind mount.

## Смотрите также

- Basic Chroot

Categories:

- System recovery (Русский)
- Sandboxing (Русский)
- Commands (Русский)