Статья 9 из 10, в которой речь пойдёт о запуске графических приложений в изолированных контейнерах, что улучшает безопасность без накладных расходов.
Заметки.
Данная статья подразумевает использование непривилегированных контейнеров. Это требование не является чем-то сложным, но очень важно́ для приложений с графическим интерфейсом.
Предположим, что мы хотим запустить Google Chrome с плагинами Google Talk (Hangout) и Adobe Flash в контейнере, чтобы не рисковать хостовой машиной.
Причины запуска приложений в изолированных контейнерах:
- Есть бинарник, но нет его исходника.
- Внешние не-Ubuntu репозитория, которые могут после добавления пропихнуть в систему всё что пожелают. Только грамотный apt pining может уменьшить риск.
- Софт устанавливает своё задание для Cron, которое добавляет удалённые вами репозитория.
- Софт использует setuid бинарник для создания своей песочницы.
- Желание отделить рабочую среду от программ, страдающих проблемами безопасности, такого как Adobe Flash, который ещё популярен в web.
Ниже будут описаны шаги, которые улучшают безопасность хостовой системы, НО до идеала далеко, так как, чтобы GUI приложения работали корректно, они должны получить доступ к:
- pulseaudio: возможна запись звуков.
- X11: возможен перехват клавиш или создание скриншотов экрана.
- dri/snd устройства: с помощью их умелый злоумышленник может придумать что-нибудь зловредное.
Запуск Google Chrome в контейнере.
Идея проста. Берём для контейнера операционную систему Ubuntu 12.04 i386, которая стабильна и хорошо поддерживается многими.
lxc-create -t download -n precise-gui -- -d ubuntu -r precise -a i386
Не забываем, что речь идёт не о системных контейнерах и поэтому в ~/.local/share/lxc/precise-gui/config внесём строки, заменив USERNAME на свой аккаунт.
lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir lxc.mount.entry = /dev/snd dev/snd none bind,optional,create=dir lxc.mount.entry = /tmp/.X11-unix tmp/.X11-unix none bind,optional,create=dir lxc.mount.entry = /dev/video0 dev/video0 none bind,optional,create=file lxc.hook.pre-start = /home/USERNAME/.local/share/lxc/precise-gui/setup-pulse.sh
В конфиге у вас будет что-то подобное
lxc.id_map = u 0 100000 65536 lxc.id_map = g 0 100000 65536
Нужно заменить на строки, подразумевая что ваш UID=1000 и GID=1000. Команда id подскажет, если забыли.
lxc.id_map = u 0 100000 1000 lxc.id_map = g 0 100000 1000 lxc.id_map = u 1000 1000 1 lxc.id_map = g 1000 1000 1 lxc.id_map = u 1001 101001 64535 lxc.id_map = g 1001 101001 64535
Эти отображения означают, что контейнер будет обладать UID/GID, начиная с 0 до 65535. Эти UID/GID сопоставляются с хостовыми - 100000 до 165535, за исключением UID/GID 1000. Этот трюк позволит пользователю в контейнере получить доступ к X, pulseaudio и устройствам DRI/snd, как пользователь в хосте, что облегчает задачу.
Создаём исполняемый скрипт ~/.local/share/lxc/precise-gui/setup-pulse.sh
#!/bin/sh PULSE_PATH=$LXC_ROOTFS_PATH/home/ubuntu/.pulse_socket if [ ! -e "$PULSE_PATH" ] || [ -z "$(lsof -n $PULSE_PATH 2>&1)" ]; then pactl load-module module-native-protocol-unix auth-anonymous=1 \ socket=$PULSE_PATH fi
Если скрипт будет не исполняемым, то LXC проигнорирует его. Данный скрипт связывает pulseaudio в хостовой системе с /home/ubuntu/.pulse_socket в контейнере.
Исправим права доступа в домашней директории пользователя внутри контейнера, подразумевая что ваш UID=1000 и GID=1000.
sudo chown -R 1000:1000 ~/.local/share/lxc/precise-gui/rootfs/home/ubuntu
Контейнер готов, пора его запускать и ставить нужное.
lxc-start -n precise-gui -d lxc-attach -n precise-gui -- umount /tmp/.X11-unix lxc-attach -n precise-gui -- apt-get update lxc-attach -n precise-gui -- apt-get dist-upgrade -y lxc-attach -n precise-gui -- apt-get install wget ubuntu-artwork ca-certificates -y lxc-attach -n precise-gui -- wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb -O /tmp/chrome.deb lxc-attach -n precise-gui -- wget https://dl.google.com/linux/direct/google-talkplugin_current_i386.deb -O /tmp/talk.deb lxc-attach -n precise-gui -- dpkg -i /tmp/chrome.deb /tmp/talk.deb lxc-attach -n precise-gui -- apt-get -f install -y lxc-stop -n precise-gui
На данном этапе, всё что нужно у нас есть, но, чтобы в будущем работа с контейнером была проще, можно создать исполняемый скрипт start-chrome и поместить его рядом с setup-pulse.sh.
#!/bin/sh CONTAINER=precise-gui CMD_LINE="google-chrome --disable-setuid-sandbox $*" STARTED=false if ! lxc-wait -n $CONTAINER -s RUNNING -t 0; then lxc-start -n $CONTAINER -d lxc-wait -n $CONTAINER -s RUNNING STARTED=true fi PULSE_SOCKET=/home/ubuntu/.pulse_socket lxc-attach --clear-env -n $CONTAINER -- sudo -u ubuntu -i \ env DISPLAY=$DISPLAY PULSE_SERVER=$PULSE_SOCKET $CMD_LINE if [ "$STARTED" = "true" ]; then lxc-stop -n $CONTAINER -t 10 fi
Скрипт start-chrome проверяет - работает ли контейнер? Если нет, то запускает его. Запускает google-chrome в правильном окружении, отключая его собственную песочницу.
Последний, полирующий штрих - создаём ярлык запуска Google Chrome в контейнере. Замените USERNAME на свой аккаунт.
[Desktop Entry] Version=1.0 Name=Google Chrome Comment=Access the Internet Exec=/home/USERNAME/.local/share/lxc/precise-gui/start-chrome %U Icon=/home/USERNAME/.local/share/lxc/precise-gui/rootfs/opt/google/chrome/product_logo_256.png Type=Application Categories=Network;WebBrowser;
У вас будет ярлык для вашей среды, по щелчку которого запускается Хром в контейнере. Можно добавить функционала в виде симлинков к папке Downloads (Закачки) или заюзать bind-mount, чтобы быстро получать доступ к скачанным файлам.
Созданный precise-gui под Google Chrome можно использовать и для запуска других программ, для примера Skype. Или создать под другие программы - другие контейнеры, подобные precise-gui.
Предыдущая статья LXC 1.0: Скрипты и API. Следующая статья LXC 1.0: Решение проблем и отладка.
Дополнительные материалы:
Серия статей LXC 1.0. от Стефана Грабера.
Adobe Flash перестанет работать в Chromium с апреля 2014.
Немає коментарів:
Дописати коментар