Linux, Unionfs · 7 min read · Feb 03, 2026
Вход в безопасное зеркало при входе с Unionfs и Chroot
Вход в безопасное зеркало при входе с Unionfs и Chroot
1. Введение
При чтении “подсказки” на сайте LinuxFromScratch я обнаружил специальные возможности unionfs, особенно в сочетании с chroot. Позже я прочитал HowTo на вики-сайте Gentoo о входе в chrooted домашний каталог, используя специальный скрипт в качестве оболочки. Сочетание этих двух приводит меня к использованию chrooted окружения, в которое вы входите, входя как специальный пользователь. Это окружение является точной копией (зеркалом) системы, с которой вы работаете. Поскольку вы находитесь в безопасной копии реальной системы, вы можете делать все, что хотите, это никогда не изменит систему, все остается внутри кэша (ветвь чтения и записи).
Ссылки:
TRIP, TRIvial Packager для LFS (и других систем Linux) - Оригинальная подсказка на сайте LFS
Home_directory_jail - Руководство по настройке chroot тюрьмы в Gentoo
2. Основная техника
Делайте все, что хотите, устанавливайте, изменяйте и удаляйте файлы из системы, и никакого вреда. Ваша реальная система остается нетронутой. Это может звучать как магия, но на самом деле это возможно только благодаря сочетанию некоторых техник из всех доступных для Linux.
Используя файловую систему Unionfs, chroot и несколько хорошо выбранных перемонтированных директорий, вы можете настроить эту виртуальную систему.
2.1 Unionfs
Самая важная часть - это использование unionfs. Unionfs дает вам возможность создать файловую систему, которая является объединением как минимум двух других. См. www.unionfs.org для получения дополнительной информации. Теперь, позволив новой файловой системе быть объединением нашей оригинальной файловой системы (корня) в режиме только для чтения и временной файловой системы (кэша) в режиме чтения и записи, вы получите файловую систему, которая выглядит точно так же, как ваша оригинальная файловая система, но в которой вы можете изменять, удалять и/или добавлять файлы, не делая ничего с вашей оригинальной системой. Это невозможно, потому что корень смонтирован в режиме только для чтения. Каждое изменение сохраняется unionfs в кэше.
Единственное различие между оригинальной и вновь созданной системой - это путь: в новой системе он всегда начинается с пути точки монтирования объединения. Вот почему следующий шаг необходим.
Особое примечание: сегодня [июнь 2007] похоже, что unionfs будет включен в ядро. Unionfs в настоящее время активно разрабатывается. Посмотрите на сайт для получения дополнительной информации.
На сайте вы найдете информацию о том, как включить unionfs. Для последних ядер (позже 2.6.19) есть патч для исходного кода ядра, для не столь недавних ядер есть внешний модуль.
2.2 (Пере)Монтирование
Еще одно, что вам нужно сделать, это (пере)монтирование нескольких ключевых директорий, таких как /dev, /proc и /sys. Это связано с тем, что объединенная файловая система не сохраняет существующие точки монтирования.
Также рекомендуется перемонтировать некоторые специальные директории, такие как /tmp и директорию, в которой вы собираете программное обеспечение.
2.3 Chroot
Путем chroot к этой точке монтирования вы входите в окружение, которое абсолютно является копией вашей системы. Вы можете делать все, что хотите, даже удалять ключевые директории и файлы. Протестируйте это! Посмотрите, как далеко вы можете зайти, прежде чем ваша система зависнет.
2.4 Вход в это окружение
Как объясняется в концепции Home_directory_jail, возможно войти в окружение, созданное с помощью unionfs и chroot, создав специальную оболочку для входа.
Идея, объясненная здесь, заключается в том, чтобы создать специального пользователя с особой оболочкой. Эта оболочка, прежде чем войти в интерактивную оболочку, сначала выполнит необходимые шаги, такие как монтирование объединенной файловой системы, перемонтирование некоторых важных директорий и выполнение chroot.
3. Подготовка
3.1 Раздел кэша
Чтобы начать, создайте раздел с достаточным пространством для функционирования в качестве кэша. Это не обязательно должен быть физический раздел, это может быть виртуальный диск.
Создайте этот диск с:
dd if=/dev/zero of=/mnt/cache.img bs=1M count=500
mkfs.ext2 /mnt/cache.img
mkdir /mnt/cache
mount /mnt/cache.img /mnt/cache -o loopchmod 777 /mnt/cachemkdir /mnt/unionЭто создает виртуальный раздел (или диск) объемом 500 М.
(Примечание: устройство обратной связи должно поддерживаться в вашем ядре. Ядра большинства дистрибутивов это делают.)
3.2 Специальная оболочка для входа
Создайте скрипт оболочки chroot-union, который выполнит все необходимые шаги:
Скрипт chroot-union в /bin:
#!/bin/bash
function mount_unionfs {
# монтирование временных файловых систем
if [ -z "$(mount -t unionfs | grep -w /mnt/union )" ]; then
sudo /bin/mount -t unionfs -o dirs=/mnt/cache:/=ro unionfs /mnt/union
fi
if [ -n "$(mount -t unionfs | grep -w /mnt/union )" ]; then
# базовые монтирования системы
if [ -z "$(mount | grep -w /mnt/union/dev)" ]; then
sudo /bin/mount --bind /dev /mnt/union/dev 2> /dev/null
fi
if [ -z "$(mount -t devpts | grep -w /mnt/union/dev/pts)" ]; then
sudo /bin/mount -t devpts devpts /mnt/union/dev/pts 2> /dev/null
fi
if [ -z "$(mount -t tmpfs | grep -w /mnt/union/dev/shm)" ]; then
sudo /bin/mount -t tmpfs shm /mnt/union/dev/shm 2> /dev/null
fi
if [ -z "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
sudo /bin/mount -t sysfs sysfs /mnt/union/sys 2> /dev/null
fi
if [ -z "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
sudo /bin/mount -t proc proc /mnt/union/proc 2> /dev/null
fi
if [ -z "$(mount | grep -w /mnt/union/tmp)" ]; then
sudo /bin/mount --bind /tmp /mnt/union/tmp 2> /dev/null
fi
else
echo "Монтирование /mnt/union не удалось."
exit 2
fi
}
function umount_unionfs {
#
# размонтировать /tmp
#
if [ -n "$(mount | grep -w /mnt/union/tmp)" ]; then
sudo /bin/umount /mnt/union/tmp 2> /dev/null
fi
#
# размонтировать /proc
#
if [ -n "$(mount -t proc | grep -w /mnt/union/proc)" ]; then
sudo /bin/umount /mnt/union/proc 2> /dev/null
fi
#
# размонтировать /sys
#
if [ -n "$(mount -t sysfs | grep -w /mnt/union/sys)" ]; then
sudo /bin/umount /mnt/union/sys 2> /dev/null
fi
#
# размонтировать /dev/shm
#
if [ -n "$(mount -t tmpfs | grep -w /mnt/union/dev/shm)" ]; then
sudo /bin/umount /mnt/union/dev/shm 2> /dev/null
fi
#
# размонтировать /dev/pts
#
if [ -n "$(mount -t devpts | grep -w /mnt/union/dev/pts)" ]; then
sudo /bin/umount /mnt/union/dev/pts 2> /dev/null
fi
#
# размонтировать /dev
#
if [ -n "$(mount | grep -w /mnt/union/dev)" ]; then
sudo /bin/umount /mnt/union/dev 2> /dev/null
fi
if [ -n "$(mount | grep -w /mnt/union )" ]; then
sudo /bin/umount /mnt/union 2> /dev/null
fi
}
mount_unionfs
# войти в chroot
sudo /usr/sbin/chroot /mnt/union /bin/su --shell /bin/bash --login $USER
# размонтировать временные файловые системы
umount_unionfs
EOF
Добавьте новую оболочку для входа в файл /etc/shells. Вам нужно будет сделать это, когда PAM будет проверять оболочку.
3.3 Создание пользователя и группы.
Создайте новую группу и пользователя с этим скриптом в качестве оболочки:
groupadd -g 27 uniongroup
useradd -c "Тестовый пользователь для chrooted union." -d /home/unionuser \
-m -s /bin/chroot-union -g uniongroup -u 27 unionuser
passwd unionuser3.4 Дайте пользователю достаточно прав
Дайте новому пользователю больше прав с помощью sudo. Добавьте следующую строку в конфигурационный файл sudo, /etc/sudoers:
unionuser ALL=(ALL) ALL
Примечание: существуют и другие способы предоставить этому пользователю разрешения. Я сейчас на них смотрю.
Примечание: предоставление этих полных разрешений слишком много для обычного пользователя. Но для пользователя, который будет устанавливать программное обеспечение и изменять вашу систему, это необходимо.
Что возможно
Безопасная и защищенная среда для обычных пользователей
Эта конструкция очень подходит для гостей, которым вы не можете доверять. Первое, что я попробовал, - это запуск графической сессии. У меня не было никаких проблем.
Установка программного обеспечения от имени этого пользователя
Еще одно возможное использование - установка программного обеспечения от имени этого пользователя. Это можно сделать следующим образом:
- как этот пользователь установите ваше программное обеспечение. Благодаря специальной конструкции все изменения попадают в кэш.
- после выхода сравните содержимое кэша с реальной системой.
- контролирующий пользователь (root) имеет возможность выполнить реальную установку, просто переместив содержимое из кэша в корень.
Например, компиляция и установка небольшого пакета audiofile-0.2.6. Предположим, что исходный код находится в /tmp. Сначала войдите:
[root@hostname ]# login
hostname login: unionuser
Password:
Last login: Wed Jun 20 19:58:32 CEST 2007 on pts/0
[unionuser@hostname ]$Теперь скомпилируйте и установите пакет:
[unionuser@hostname ]$ cd /tmp/audiofile-0.2.6
[unionuser@hostname ]$ ./configure –prefix=/usr
[unionuser@hostname ]$ make
[unionuser@hostname ]$ sudo make install
Теперь выйдите из сессии и проверьте содержимое кэша:
[unionuser@hostname ]$exit
[root@hostname ]# cd /mnt/cache
[root@hostname ]# ls -Al
drwxr-xr-x 3 root root 1024 2007-06-05 17:32 home
drwxr-xr-x 6 root root 1024 2007-06-05 17:37 usr
drwxr-xr-x 3 root root 1024 2007-06-05 17:32 var
[root@hostname ]#
Домашний каталог появляется здесь, потому что оболочка Bash изменяет файл .bash_history; директория var появляется из-за изменений в файле /var/run/utmp и директории /var/run/sudo. Это доказывает, что все работает так, как должно.
Теперь, когда мы смотрим на изменения в директории /usr, где я установил программное обеспечение, получаем:
[root@hostname ]# find usr -type f
usr/lib/pkgconfig/audiofile.pc
usr/lib/libaudiofile.la
usr/lib/libaudiofile.a
usr/lib/libaudiofile.so.0.0.2
usr/include/audiofile.h
usr/include/aupvlist.h
usr/include/af_vfs.h
usr/bin/audiofile-config
usr/bin/sfconvert
usr/bin/sfinfo
usr/share/aclocal/audiofile.m4
[root@hostname ]# find usr -type d
usr
usr/lib
usr/lib/pkgconfig
usr/include
usr/bin
usr/share
usr/share/aclocal
Как видите, все находится в директории /mnt/cache/usr.
Вы можете сделать резервную копию этого:
[root@hostname ]# find usr | sort -u > /tmp/filelist-audiofile-0.2.6
[root@hostname ]# tar --create --files-from=/tmp/filelist-audiofile-0.2.6 \
--file=/tmp/install-audiofile-0.2.6.tar --directory=/mnt/cache \
--no-recursion --absolute-names --preserve-permissionsТакже очень возможно сделать резервную копию всех файлов, которые будут перезаписаны:
[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \
if [ -e "/$installfile ]; then \
echo "/$installfile" >> /tmp/backup-audiofile-0.2.6 \
fi \
done
[root@hostname ]# tar --create --files-from=/tmp/backup-audiofile-0.2.6 \
--file=/tmp/backup-audiofile-0.2.6.tar --directory=/mnt/cache \
--no-recursion --absolute-names --preserve-permissionsТеперь выполните реальную установку, скопировав все файлы в корень:
[root@hostname ]# for installfile in $(cat /tmp/filelist-audiofile-0.2.6); do \
cp --verbose --force --recursive --parents --no-dereference \
--preserve --target-directory=/ $installfile \
doneПримечание: команды выше предназначены для иллюстрации идеи. Я создал скрипты для резервного копирования, проверки и установки, и это работает очень хорошо.
Get new posts in your inbox
No spam. Unsubscribe anytime.