Недавно передо мной встала задача запускать определенное приложение или набор приложений в так называемой песочнице.
Немного покапавшись в гугле я нашел для себя несколько вариантов как можно реализовать это. В этой заметке я опишу несколько вариантов, а так же напишу почему некоторые мне не подошли. Предполагается, что мы знакомы с lxc, chroot, openvz, jail, и считаем свой уровень познаний в linux высоким.
Краткий экскурс в суть вопроса:
Предположим у нас есть парк компьютеров, с linux на борту, нам в силу определенных интересов, будь то вопрос о защите персональных данных или вопрос о сохранении чистоты файловой системы необходимо запускать приложение, в моем случае браузер firefox и утилита для сканирования sane в собственном окружении изолированном от хост-системы, при чем, каждый раз, когда пользователь включает свой компьютер это окружение автоматически создается и по факту пользователь работает полностью в новой системе.
Вариант №1
Использование lxc-контейнера.
LXC (англ. Linux Containers) — система виртуализации на уровне операционной системы для запуска нескольких изолированных экземпляров ОС Linux на одном компьютере. LXC не использует виртуальные машины, а создает виртуальное окружение с собственным пространством процессов и сетевым стеком. Все экземпляры LXC используют один экземпляр ядра ОС.
Стоит сразу же заметить, lxc не готов к использованию на продакшен, связано это с тем, что управление ресурсами cgroup не отлажено и находится на низком уровне, по этому есть риск краха контейнера и хост-системы в целом.
Но как вариант мы все же рассмотрим. Итак, у нас есть два пути, создание полноценной виртуальной системы, которая автоматически создается путем запуска нужного нам скрипта (template). На выбор разработчики предлагают нам следующее:
ls -l /usr/lib/lxc/templates/ lxc-busybox - набор минимальный, для запуска busybox lxc-debian - полноценный шаблон для debian, для установки необходим пакет debootstrap lxc-fedora - полноценный шаблон для fedora lxc-sshd - минимальный набор для создания контейнера для запуска ssh-сервера, после создания потребуется настроить сеть bridge lxc-ubuntu - шаблон для ubuntu
Что пробовал я, создавал полностью систему из шаблона ubuntu, вышло примерно 700мб дискового пространства, учесть что каждый день контейнер должен пересоздаваться + автоматически устанавливаться firefox и sane, этот вариант отпал сразу. Хотя "из коробки" все завелось без проблем. От создания полноценной виртуальной системы пришлось отказаться, я перешел к созданию контейнера lxc для запуска в нем приложения, за основу брал шаблон debian, после установки контейнер занимал примерно ~400мб, что тоже не айс. Немного почитал про структуру файловой системы в lxc контейнерах, я предпринял попытку ручного создания контейнера, для этого необходимо создать дерево файловой системы:
root@server:/home/hellname# tree /var/lxc/simple/ /var/lxc/simple/ ├── fstab ├── lxc-simple.conf └── rootfs ├── bin ├── dev │ └── pts │ ├── network │ └── shm ├── etc ├── lib ├── proc ├── root ├── sbin ├── sys ├── usr └── var ├── empty ├── lib └── run
Немного поясню, /var/lxc/simple -- директория файлов контейнера, rootfs - директория с псевдо-файловой системой
fstab - файл, в котором мы указываем что и куда монтировать из хост-системы в контейнер, lxc-simple.conf - конфиг контейнера.
root@server:/home/hellname# cat /var/lxc/simple/fstab /lib /var/lxc/simple/rootfs/lib none ro,bind 0 0 /bin /var/lxc/simple/rootfs/bin none ro,bind 0 0 /usr /var/lxc/simple/rootfs/usr none ro,bind 0 0 /sbin /var/lxc/simple/rootfs/sbin none ro,bind 0 0
root@server:/home/hellname# cat /var/lxc/simple/lxc-simple.conf lxc.utsname = simple lxc.mount = /var/lxc/simple/fstab lxc.rootfs = /var/lxc/simple/rootfs
Для запуска firefox из этого контейнера, нам необходимо создать симлинки библиотек firefox, чтобы узнать какие либы он использует поможет утилита ldd. Делаем симлинки, либо просто копируем эти либы в аналогичные директории lxc-контейнера, далее копируем саму директорию с firefox в аналогичную директорию lxc-контейнера. Иногда возникает проблема с запуском графических приложений которые должны использовать X хост-системы, по этому если приложение не запускается, следует примонтировать:
/tmp/X11/.X11-unix в /var/lxc/simple/rootfs/tmp/.X11-unix/ Соответсвенно директория /tmp/.X11-unix в lxc-контейнере должна присутствовать.
Пробуем запустить контейнер:
lxc-execute -n simple -f /var/lxc/simple/lxc-simple.conf firefox
Если все прошло хорошо, firefox должен запуститься.
С этим вариантом мы разобрались, теперь почему он не подходит мне! Изначально я не просто так упомянул такие слова, как персональные данные и чистота системы, а учитывая что дела в lxc с cgroup обстоят плохо, то о никакой песочницы гостевой файловой системы речи не идет. Мы можем просто нажать Ctrl+O в firefox и увидеть файловую систему хост-системы. Но я не хочу сказать что LXC это сырое и ужасное поделие, отнюдь, простота и легкость создания и масштабирования контейнеров просто впечатляет, и если разработчики не оставят свой проект, то я думаю у него большое и светлое будущее, кстати в Яндекс насколько я знаю используют допиленный LXC для создания виртуальных контейнеров.
Еще немного обдумав все варианты и возможные концепции создания отдельного, изолированного окружения, которое никак не позволит гостевому пользователю заглянуть в файловую систему хост-системы (тавтология, мать вашу) я начал копать в сторону нативного chroot и легковестных дистрибутивов linux.
Вариант №2
Создание chroot окружения и запуск приложения.
Итак, понеслось.
В интернете существует множество легковестных дистрибутивов, например DSL, tinycorelinux и т.п. Я остановился на slitaz.
Подготавливаем место для нашей песочницы:
Создаем директорию
# mkdir -p /var/chroot/slitaz
Создаем директорию для временного монтирования образа системы
# mkdir /tmp/slitaz
Скачиваем образ slitaz, я скачал сборку cooking, взять можно отсюда.
Далее нам необходимо смонтировать этот образ в /tmp/slitaz, это нужно для того, чтобы взять rootfs.gz (корневая файловая система)
# mount -o loop /var/chroot/slitaz/slitaz-cooking.iso /tmp/slitaz
Копируем rootfs.gz в chroot-окружение
cp /tmp/slitaz/boot/rootfs.gz /var/chroot/slitaz
Нам необходимо распаковать этот архив, это не обычный gz-архив, по этому нужно сделать следующее:
# cd /var/chroot/slitaz # unlzma rootfs.gz -S .gz # cat rootfs | cpio -id
Итогом выполнения этих команд должен быть результат вывода утилиты tree:
# tree -L 1
.
├── bin
├── dev
├── etc
├── home
├── init
├── lib
├── media
├── mnt
├── proc
├── root
├── sbin
├── sys
├── tmp
├── usr
└── var
Но это еще не все, нам необходимо примонтировать некоторые разделы из хост-системы в chroot-окружение, для автоматизации этого процесса можно воспользоваться скриптом, написанным разработчиками slitaz, ВАЖНО! так как нам потребуется запуск графики, то монтируем /dev и /tmp
#!/bin/sh # Chroot in SliTaz to hack. # ROOTFS="/var/chroot/slitaz" # подключение виртуальной файловой системы ядра и chroot. # mount --bind /dev $ROOTFS/dev mount --bind /tmp $ROOTFS/tmp mount -t proc proc $ROOTFS/proc mount -t sysfs sysfs $ROOTFS/sys mount -t devpts devpts $ROOTFS/dev/pts mount -t tmpfs shm $ROOTFS/dev/shm echo "Переключение chroot в $ROOTFS... " chroot $ROOTFS /bin/sh --login # отключение виртуальной файловой системы ядра при выходе. # umount $ROOTFS/dev/shm umount $ROOTFS/dev/pts umount $ROOTFS/sys umount $ROOTFS/proc umount $ROOTFS/tmp umount $ROOTFS/dev echo "Выход из окружения chroot $ROOTFS... " EOF
Теперь, чтобы зайти в гостевую систему, нам просто нужно запустить этот скрипт, а для выхода набрать exit в гостевой системе.
Находясь в гостевой системе, обновим репозитории, в slitaz используется собственная система управления пакетами tazpkg:
Но для начала настроим сеть, у меня на хост системе интерфейс wlan0
root@hell:/# udhcpc -i wlan0 udhcpc (v1.12.0) started Sending discover... Sending select for 192.168.0.130... Lease of 192.168.0.130 obtained, lease time 86400 deleting routers route: SIOCDELRT: No such process adding dns 192.168.0.1
# tazpkg recharge Увидим примерно следующее: Creating backup of the last packages list... [ OK ] Mirrored packages diff ================================================================================ 35 new packages on the mirror.
Установим firefox:
# tazpkg get-install firefox
tazpkg сам разрулит зависимости и стянет все что необходимо для запуска графики.
Теперь для запуска firefox мы сделаем:
export DISPLAY=:0.0
а на хост-системе:
# xhost + # access control disabled, clients can connect from any host
Собственно все, запускаем firefox:
на хост-системе выполняем:
# chroot /var/chroot/slitaz firefox
Перед нами firefox запущенный в slitaz chroot-окружении
Полезные ссылки:
http://www.slitaz.org/
http://www.slitaz.org/ru/get/flavors.php
Комментарии
10 лет 50 недель назад
10 лет 51 неделя назад
10 лет 51 неделя назад
11 лет 5 часов назад
11 лет 1 неделя назад
11 лет 2 недели назад
11 лет 2 недели назад
11 лет 12 недель назад
11 лет 12 недель назад
11 лет 12 недель назад