Недавно передо мной встала задача запускать определенное приложение или набор приложений в так называемой песочнице.
Немного покапавшись в гугле я нашел для себя несколько вариантов как можно реализовать это. В этой заметке я опишу несколько вариантов, а так же напишу почему некоторые мне не подошли. Предполагается, что мы знакомы с 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 лет 26 недель назад
10 лет 27 недель назад
10 лет 27 недель назад
10 лет 28 недель назад
10 лет 29 недель назад
10 лет 30 недель назад
10 лет 30 недель назад
10 лет 40 недель назад
10 лет 40 недель назад
10 лет 40 недель назад