Linux и сторонние подозрительные приложения

Posted: 2012-11-11 in IT, Security, Software
Метки:,

О том, что программы с закрытым исходном кодом — изначально суть зло недоверенные и потенциально опасные — говорили многие. Хорошо, что у нас есть открытые ОС, набор системного софта и множество пользовательских программ.

Но часть софта не имеют открытых аналогов, и заменить их пока что нечем. В данной статье я не буду рассматривать сверх-тяжелые и очень сложные пакеты типа автокада и 3D-макса — их пользователи жестко (и даже жестоко) привязаны к ОС одной известной компании, и о том уровне безопасности, которого мы легко достигнем в данной заметке — могут только мечтать, молясь на антивирус Кашпировского. Лет так примерно 20 😀 😀 . …

В данной заметке речь пойдет про Skype. Достаточно давно по инету пролетали новости, что скайп и серийные номера оборудования пиздил, и искал что-то странное в профиле браузера и вообще редиска.
Но поскольку адекватных аналогов ему пока что нет (что в джаббере, что в SIP видеовызовы работают исключительно через жопу, а все остальное — на массовые стандартизированные средства не тянет и близко), то надо как-то утешить свою разбушевавшуюся паранойю. Конечно, ssh-ключи скайп вроде пока что ни у кого не тырил, но я предлагаю не ждать сего печального события и озадачиться действительно глубокой изоляцией этой программы от основной системы и наших ценных данных, раз уж нам надо ей пользоваться.

Итак, наша модель угрозы такова: противник, способный удаленно проэксплойтить скайп или даже получить доступ к серверам авторизации. Таким образом, защита пароля и собственно учетки скайпа в нашу текущую задачу не входит. Наша задача — защитить данные на локальной машине от риска компрометации закрытым ПО. Нам совершенно не важно, будет ли это просто сторонний хакер, нашедший уязвимое место в скайпе, или же это будет fedware-троян, прописанный самим микрософтом. Скайп не должен получить доступ ни к рабочим профилям браузеров, ни к документам, ни тем более к криптографическим ключам SSL/SSH/PGP или паролям других приложений.

Для начала расскажу об опробованных ранее вариантах.

0). Отдельная физическая машина. Шутка 😀 . Если я на каждое кривое приложение буду ставить по машине — я в них зарасту по самый потолок :D. Да и жирно ему будет, целую машину-то.

1). Виртуальная машина. Из плюсов тут — относительная простота настройки и действительно глубокая изоляция. Потребуется дать внутрь инет (можно даже через проксик), пробросить одно USB-устройство (веб-камеру) и звук. Но проблем гораздо больше, и не скажу, что они из приятных. Внутри будет жить полноценная ОС — со своим ядром, сервисами, оболочкой. Которая также требует отдельного обновления и обслуживания. Кооторая занимает изрядно места на жестком диске впустую. И которая у каждого пользователя должна быть своя. Можно конечно попытаться запустить скайп внутри виртуалки с TinyCore или с сильно обрезанной виндовс — но это все равно ещё одно ядро, ещё пачка оболочек и как минимум 256 Мб памяти на один только скайп. Кроме того, если скайп вам нужен на слабой машине — например, на нетбуке — то отсутствие аппаратной виртуализации ударит по производиетльности всей системы в целом. Виртуалки конечно прекрасны, но для этой задачи — слишком уж тяжелая артиллерия. Причем тут в принципе без разницы, применим ли мы десктопное решение типа VirtualBox/VMWare или же поднимем свой Xen или Cubes от Рутковской.

2). Запуск от отдельного пользователя. Выглядит просто и привлекательно, но только на первый взгляд. Проблема номер один — у нас удваивается число пользователей. То есть помимо существующих vasya и alex появятся vasya_skype и alex_skype. Этих пользователей надо убрать из списка для интерактивного логина, проверить, что им не оставили возможность логина со слабым паролем. Можно даже запускать его при этом через ssh -X. Кроме того, если соблюдаем правила безопасной работы — у нас возникнут серьезные неудобства, когда нам потребуется принять или передать файл по скайпу. Придется либо делать какие-то общедоступные ресурсы для обоих пользователей, либо перекидывать файлы отдельным процессом с повышенными правами. Кроме того, когда у нас есть активный залогиненный пользователь, процесс, запущенный от имени другого пользователя — не всегда может принимать и передавать звук. Конечно, наверняка в мире существует достаточно сильное колдунство, чтобы это преодолеть, но риск сломать что-нить в udev или
alsa/pulseaudio — не радостен. Как видим, данный метод требует нехилых усилий, чтобы заставить это работать, да и работа получается сильно неудобной.

3). SELinux-sandbox. Технология относительно новая, но это — как раз то, что нам нужно. Во-первых, мы не плодим лишних пользователей. Во-вторых, мы остаемся на том же ядре, и наша песочница — гораздо легче, чем полноценная ВМ. Нам гораздо проще организовать общий каталог — просто пробросив его внутрь, как и на обычных ВМ. И что самое ценное — у нас уже есть готовые контексты, в которых все самое сложное уже сделано до нас. Суть — в наложении на программу дополнительных ограничений средствами SELinux, которая фильтрует системные вызовы. Штука жесткая, но исключительно действенная. О том, что это такое — можно погуглить, или посмотреть пример мана по настройке: http://www.opennet.ru/base/sec/selinux_setup.txt.html . После этого имеет смысл ознакомиться с презентацией Дэна Уолша, который эти чудесные политики и намутил настолько суров, что курирует этот проект в RedHat: http://www.linuxplumbersconf.net/2009/slides/dan-walsh-selinux-sandbox.pdf

А вот теперь приступим к практической настройке.
Я подразумеваю, что у вас в наличии есть Fedora 17 (примеры будут по ней) или иная система с включенным в enforcing-режиме SELinux, обновленная патчами до актуального состояния. Сперва ставим на нее политики для песочницы:

yum install policycoreutils-sandbox

Собственно, теперь подготовим профиль. Скайп хранит настройки в ~/.Skype, мы же там создадим два пустых каталога — вирутальный /home/<username> и виртуальный </tmp>:

mkdir ~/.Skype/se_home
mkdir ~/.Skype/se_tmp

И собственно пытаемся запустить:

sandbox -H ~/.Skype/se_home/ -T ~/.Skype/se_tmp/ -X -t sandbox_net_t skype

Скайп нормально запустится, соединится с сервером, звук будет идти в обе стороны, и при видеозвонке даже будет видно собеседника. Но поскольку это запуск приложения поверх голого Х-сервера, без оконного менеджера (см. статью про платежный терминал), то выглядеть это будет вот так: Работать оно конечно работает, но модальные окна скайпа придется изощряться закрывать с клавиатуры :D, что мягко скажем неудобно. И да — контекст для запуска должен быть именно sandbox_net_t, поскольку скайп юзает не только порты 80 и 443. Если вы ознакомились с презентацией Дэна, то помните, что пеcочница с параметром -X запускает отдельный экземпляр X-сервера. Теперь сделаем так, чтобы внутри песочницы были красивые окошки и чтобы было удобнее пользоваться всем этим. Можно конечно запустить на этом экземпляре ещё одну KDE4 с плазмой и виджетами, но это будет уже не слишком-то легковесно, да и эффекты внутри песочницы нам особо не нужны. Поэтому поставим пару пару легковесных софтин — оконный менеджер и мелкое десктопное окружение:

yum install lxde-common openbox

Потом прописываем вот такой файлик:

cat ~/.Skype/se_home/.config/lxsession/LXDE/autostart
#!/bin/bash

openbox
skype

И пробуем со всем этим взлететь:

sandbox -H ~/.Skype/se_home/ -T ~/.Skype/se_tmp/ -W openbox -X -t sandbox_net_t lxsession

Вуаля, теперь песочница со скайпом выглядит гораздо лучше, и сразу видно, что в домашний каталог из нее хрен попадешь: Отлично.
Делаем тестовый звонок и тестовый чат. Все работает, кроме веб-камеры. Что в случае активного SELinux вполне логично — контексту для песочниц (в нашем случае sandbox_net_t) запрещен доступ к объектам v4l. SELinux при этом в логи пишет вот такое:

SELinux is preventing /usr/bin/skype from open access on the chr_file /dev/video0.

Смотрим контекст для веб-камеры:

$ ls -laZ /dev/video0
crw-rw----+ root video system_u:object_r:v4l_device_t:s0 /dev/video0

Теперь пользуемся audit2allow:

# grep 4C...64 /var/log/audit/audit.log | audit2allow -M Amin_SkypeV4L

и очень внимательно смотрим, что она нам предлагает сделать:

# cat Amin_SkypeV4L.te

module Amin_SkypeV4L 1.0;

require {
        type sandbox_net_client_t;
        type v4l_device_t;
        class chr_file { read write };
}

#============= sandbox_net_client_t ==============
allow sandbox_net_client_t v4l_device_t:chr_file { read write };

То есть предлагается песочницам открыть доступ к веб-камерам V4L. Если нас это устраивает — то теперь надо собрать и установить политику в систему.
Можно сразу добавить подготовленный модуль:

semodule -i Amin_SkypeV4L.pp

Однако если надо поправить политику ручками, то вносим требуемые изменения в *.te-файл и пересобираем модуль для политики двумя командами:

# checkmodule -M -m -o Amin_SkypeV4L.mod  Amin_SkypeV4L.te
checkmodule:  loading policy configuration from Amin_SkypeV4L.te
checkmodule:  policy configuration loaded
checkmodule:  writing binary representation (version 15) to Amin_SkypeV4L.mod
semodule_package --outfile Amin_SkypeV4L.pp --module Amin_SkypeV4L.mod

После чего точно также устанавливаем его:

semodule -i Amin_SkypeV4L.pp

или обновляем:

semodule -u Amin_SkypeV4L.pp

Я это все сделал… и нифига. Никакого доступа не появилось, потому что там есть несколько разных типов вызовов. Так что результирующая политика описывается вот таким *.te-файлом:

# cat Amin_SkypeV4L.te

module Amin_SkypeV4L 1.0.5;

require {
        type sandbox_net_client_t;
        type v4l_device_t;
        class chr_file { read write };
}

require {
        type sandbox_net_client_t;
        type v4l_device_t;
        class chr_file { open ioctl };
}

require {
        type sandbox_net_t;
        type v4l_device_t;
        class chr_file { read write };
}

require {
        type sandbox_net_t;
        type v4l_device_t;
        class chr_file { open ioctl };
}

#============= sandbox_net_client_t ==============
allow sandbox_net_client_t v4l_device_t:chr_file { read write };
allow sandbox_net_client_t v4l_device_t:chr_file { open ioctl };

allow sandbox_net_t v4l_device_t:chr_file { read write };
allow sandbox_net_t v4l_device_t:chr_file { open ioctl };

Теперь тремя вышеприведенными командами соберем её и поставим. В итоге целая пачка разрешенией будет задана в политике всего одним модулем:

# semodule -l | grep Amin
Amin_SkypeV4L       1.0.5

Да, свои собственные модули лучше называть так, чтобы их легко можно было найти и отключить в будущем, если что-то потребуется вернуть в исходное состояние. И номер версии тоже полезно указывать, чтобы сразу было видно, какая версия политики действует. Ура, вот теперь веб-камера доступна изнутри песочницы.

В будущем, если паранойя снова зачешется — можно сделать уже свой контекст для песочницы, и оставить доступ именно к /dev/video0, а не ко всем v4l-устройствам вообще. Но поскольку песочница такая у меня пока что всего одна — оставим пока как есть.

На текущий момент мы добились того, что скайп не то что ключи и документы — он настройки внешней системы получить может далеко не все. Ах да, маленькое неудобство — буфер обмена в песочнице свой. Так что даже если во внешней системе в буфере обмена окажется пароль от сервера — скайп не сможет его перехватить, даже если сильно захочет =).
Я выкрутился просто:

cd ~/.Skype/se_home/Desktop
ln -s Skype-Clipboard.txt ~/Рабочий стол/Skype-Clipboard.txt

Аналогично можно из внешней системы получить доступ к любому внутреннему каталогу песочницы. То есть пробрасывать дополнительные внешние каталоги даже не потребовалось.

Ну и посмотрим напоследок, как оно в менеджере процессов:

$ ps xauZ | grep skype
unconfined_u:unconfined_r:sandbox_net_client_t:s0:... Amin ... skype

Замечательно, контекст что надо. Теперь правим ярлык в панели запуска приложений, чтобы вместо `skype` выполнялась команда `sandbox … skype`, и всё готово.
Что самое ценное — это легко раскатать для всех пользователей, используемые программы по-прежнему легко обновляются пакетным менеджером, а расход ресурсов — минимальный из возможных. И да, профиль подготовленной песочницы (каталог se_home) в tgz-архиве весит всего 1.3 Мб. Если у кого остались трехдюймовые дискеты — как раз влезет 😀

Через некоторое время нездоровое любопытство скайпа было зафиксировано в логах аудита:

SELinux is preventing /usr/bin/skype from read access on the file /home/Amin/.sandboxrc

Вот уж к чему, а к скрипту запуска окружения песочницы скайпу точно доступа не нужно, нет и не может быть у него таких задач. Так что отметим для себя тот факт, что скайп, в том числе текущей версии 4.1, читает даже те конфиги, которые к нему никак не относятся, и ни для какой работы ему нафиг не нужны, а следовательно наше решение насчет его глубокой изоляции было абсолютно верным.

Если есть пожелания, вопросы или советы по улучшению — пишите, обсудим.

Обсуждение закрыто.