Як використовувати команду chroot в Linux

Команда chroot дозволяє створити ізольоване оточення для розробки, тестування або посилення безпеки вашої системи. Розглянемо найпростіший спосіб її застосування.

Що таке chroot?

При оцінці корисності будь-якої команди важливо враховувати як її функціонал, так і простоту використання. Якщо команда надмірно складна або вимагає значних зусиль для налаштування, її потенціал може залишитися нереалізованим. Команда, якою ніхто не користується, не приносить користі.

З досвіду спілкування з користувачами Linux, зокрема на форумах, команда chroot часто сприймається як складна у використанні або занадто трудомістка для налаштування. Через це її потенціал використовується не в повній мірі.

Chroot дозволяє створювати та запускати програми, або інтерактивні оболонки, такі як Bash, у межах інкапсульованої файлової системи, яка не може взаємодіяти з основною файловою системою. Усе, що відбувається в середовищі chroot, є локалізованим. Жоден елемент chroot не має доступу за межі свого спеціального кореневого каталогу, навіть з правами root. Через це такі середовища часто називають “chroot-тюрмами”. Важливо не плутати цей термін з командою FreeBSD jail, яка створює середовища chroot з вищим рівнем безпеки.

Однак, існує дуже простий спосіб використання chroot, який ми зараз розглянемо. Ми будемо використовувати стандартні команди Linux, що працюють в будь-якому дистрибутиві. Деякі дистрибутиви, такі як Ubuntu, мають спеціальні інструменти для створення chroot-середовищ, наприклад debootstrap, але ми розглянемо універсальний підхід.

Коли варто використовувати chroot?

Середовище chroot надає функціональність, подібну до віртуальної машини, але є більш легким рішенням. Для його створення не потрібні гіпервізори, такі як VirtualBox або Менеджер віртуальних машин. Також немає потреби встановлювати додаткове ядро, chroot використовує ядро вашої основної системи.

У певному сенсі, chroot-середовища ближчі до контейнерів, таких як LXC, ніж до віртуальних машин. Вони легкі, швидко розгортаються, а їх створення та запуск можна автоматизувати. Як і контейнери, їх часто налаштовують, встановлюючи лише необхідний мінімум операційної системи. Необхідний мінімум залежить від конкретних потреб використання chroot.

Основні випадки використання:

  • Розробка та верифікація програмного забезпечення. Розробники створюють програмне забезпечення, а тестувальники його перевіряють. Іноді тестувальники знаходять помилки, які не вдається відтворити на комп’ютері розробника, оскільки на ньому встановлено багато додаткових інструментів та бібліотек. Chroot дозволяє розробникам створити мінімальне середовище, імітуючи умови користувача, для тестування ПЗ перед передачею на верифікацію.
  • Зниження ризику при розробці. Розробник може працювати в ізольованому середовищі, що убезпечує основний комп’ютер від можливих збоїв.
  • Запуск застарілого ПЗ. Якщо стара програма має вимоги, несумісні з вашою версією Linux, можна створити chroot-середовище для її запуску.
  • Відновлення та оновлення файлової системи. Якщо ваша система Linux не завантажується, можна використовувати chroot для підключення пошкодженої файлової системи через Live CD. Це дасть змогу відновити систему, працюючи з файлами так, ніби вони розташовані в кореневому каталозі.
  • Підвищення безпеки. Запуск серверних додатків, таких як FTP, в chroot-середовищі зменшує потенційну шкоду від зовнішньої атаки.

Створення chroot-середовища

Спочатку нам потрібен каталог, який буде використовуватися як кореневий для chroot-середовища. Зручніше створити змінну для зберігання його шляху. Наприклад, змінна “chr” зберігає шлях до каталогу “testroot”. Не має значення, чи він існує, ми його зараз створимо. Якщо ж він існує, то повинен бути порожнім.

chr=/home/dave/testroot

Якщо каталогу немає, його слід створити. Команда “mkdir -p” створить каталог і всі відсутні батьківські каталоги:

mkdir -p $chr

Далі, створимо каталоги для основних компонентів ОС. Нам потрібне мінімалістичне середовище Linux з Bash як інтерактивною оболонкою, а також команди touch, rm та ls. Це дозволить нам створювати, переглядати та видаляти файли, а також використовувати оболонку Bash.

Перелік каталогів у {} використовує розширення брекетів.

mkdir -p $chr/{bin,lib,lib64}

Перейдемо до новоствореного кореневого каталогу:

cd $chr

Скопіюємо необхідні бінарні файли з вашого системного каталогу “/bin” до нашого chroot-каталогу “/bin”. Опція -v (verbose) виводить повідомлення про кожну операцію копіювання:

cp -v /bin/{bash,touch,ls,rm} $chr

Скопійовані файли:

Ці бінарні файли залежать від інших бібліотек. Нам потрібно скопіювати ці залежності до chroot-середовища, інакше bash, touch, rm і ls не працюватимуть. Для кожної з команд будемо робити це по черзі. Почнемо з bash. Команда ldd покаже залежності:

ldd /bin/bash

Залежності відобразяться в терміналі:

Потрібно скопіювати ці файли до нового середовища. Копіювання кожного файлу вручну може зайняти багато часу і призвести до помилок.

На щастя, ми можемо автоматизувати цей процес. Знову виведемо залежності, але цього разу створимо список. Після цього пройдемо по списку, копіюючи файли.

Команда ldd покаже залежності і передасть їх через конвеєр до egrep. Egrep — це те ж саме, що grep з опцією -E (розширені регулярні вирази). Параметр -o (лише збіг) обмежує вивід до відповідних частин рядків. Ми шукаємо файли бібліотек, що закінчуються на цифру [0-9].

list="$(ldd /bin/bash | egrep -o '/lib.*.[0-9]')"

Можемо перевірити список командою echo:

echo $list

Тепер, маючи список, пройдемо по ньому за допомогою циклу, копіюючи файли по одному. Змінна “i” використовується для ітерації по списку. Для кожного елемента списку копіюється файл до chroot-середовища, шлях до якого вказаний у змінній $chr.

Параметр -v (verbose) в cp відображає кожну операцію копіювання. Параметр –parents гарантує створення відсутніх батьківських каталогів у chroot-середовищі.

for i in $list; do cp -v --parents "$i" "${chr}"; done

Результат:

Застосуємо цю техніку для копіювання залежностей інших команд. Потрібно лише трохи змінити команду, що отримує список залежностей. Команда циклу копіювання залишається незмінною.

Використаємо клавішу “вгору” для пошуку попередньої команди і змінимо bash на touch.

list="$(ldd /bin/touch | egrep -o '/lib.*.[0-9]')"

Використаємо той самий цикл:

for i in $list; do cp -v --parents "$i" "${chr}"; done

Файли скопійовано:

Змінимо команду для ls:

list="$(ldd /bin/ls | egrep -o '/lib.*.[0-9]')"

Знову використаємо той самий цикл:

for i in $list; do cp -v --parents "$i" "${chr}"; done

Залежності ls скопійовано:

Відредагуємо командний рядок для rm:

list="$(ldd /bin/ls | egrep -o '/lib.*.[0-9]')"

Використаємо цикл копіювання в останній раз:

for i in $list; do cp -v --parents "$i" "${chr}"; done

Всі залежності скопійовано. Тепер можна використовувати команду chroot, яка встановить корінь середовища та запустить оболонку:

sudo chroot $chr /bin/bash

Середовище chroot активовано. Змінилася підказка терміналу, і інтерактивна оболонка тепер працює в нашому середовищі.

Перевіримо роботу команд:

ls
ls /home/dave/Documents

Команда ls працює в chroot. При спробі отримати доступ за межі середовища команда не працює.

Використаємо touch для створення файлу, ls для перегляду та rm для видалення:

touch sample_file.txt
ls
rm sample_file.txt
ls

Також працюють вбудовані команди Bash. Введіть help для отримання їхнього переліку.

help

Команда exit завершить роботу chroot:

exit

Для видалення chroot-середовища, можна просто його видалити:

rm -r testroot/

Це рекурсивно видалить всі файли і каталоги в середовищі chroot.

Автоматизація для зручності

Якщо ви вважаєте chroot-середовища корисними, але їх створення трохи складне, пам’ятайте, що завжди можна автоматизувати повторювані завдання за допомогою псевдонімів, функцій та скриптів.