Блог ИТ склеротика. Управляем привилегиями приложений с помощью Capabilities

Страницы

Расширенный поиск в статьях блога

18 февраля 2012 г.

Управляем привилегиями приложений с помощью Capabilities

Управляем привилегиями приложений с помощью CapabilitiesСегодня поддержка этого механизма реализована почти во всех POSIX-совместимых ОС, однако популярностью он не пользуется и большое количество системных администраторов даже не подозревает о его существовании. Между тем capabilitiesочень мощная и в то же время чрезвычайно простая в использовании подсистема.
Еще до появления SELinux, AppArmor, ACL и прочих технологий ограничения приложений в полномочиях и правах доступа, в стандарт POSIX был принят механизм так называемых "возможностей" (или по-английски: capabilities), который позволял наделять приложения, работающие с правами обычных пользователей, рядом привилегий root, не давая им полных прав суперпользователя.
Смысл cap (я не хочу писать это слово целиком, поэтому буду использовать такое сокращение, читать следует "кэп") заключается в том, чтобы позволить определенным приложениям, запускаемым с правами обычных пользователей и не имеющим серьезных полномочий в системе, совершать серьезные и несущие угрозу действия, на которые раньше был способен только root. Такая возможность позволяет отказаться от использования SUID-бита для приложений и в то же время оставить за ним право на выполнение каких-либо привилегированных действий. Поэтому, если приложение когда-нибудь окажется скомпрометированным, злоумышленник не сможет нанести особого вреда системе (Спасибо, кэп!). В Linux поддержка capabilities реализована уже очень давно, однако раньше приложения должны были сами управлять своими возможностями: на приложение устанавливался SUID-бит, так что после запуска оно получало права root, далее расщеплялось на два независимых процесса, причем порожденный процесс получал права обычного пользователя, а родитель с помощью механизма cap давал ему полномочия на выполнение нужных действий и завершался. Так приложение оставалось почти бесправным, но получало определенные привилегии. Само собой разумеется, что такой способ был неудобен, ни программистам, ни админам, ни пользователям, поэтому начиная с версии 2.6.24 в ядре появилась поддержка capabilities, ассоциированных с исполняемыми файлами.
Capabilities, привязанные к файлам
Начиная с ядра 2.6.24 в расширенные атрибуты любого исполняемого файла можно записать список расширенных привилегий, которые достанутся процессу, порожденному при запуске этого файла. Другими словами: наделить отдельно взятые приложения особыми правами. Чтобы сделать это следует воспользоваться утилитой setcap. В качестве примера возьмем программу /bin/ping. Обычно она имеет установленный SUID-бит, благодаря которому может работать с сырыми (raw) сокетами и, как следствие, отправлять запросы ICMP ECHO. Попробуем снять SUID-бит с программы и посмотреть на результат:
$ sudo chmod -s /bin/ping $ ping execbit.ru ping: icmp open socket: Operation not permitted
Как и следовало ожидать программа стала неработоспособной. Чтобы вернуть ее к жизни, наделим /bin/ping правом на создание RAW-сокетов с помощью capabilities:
$ sudo sudo setcap cap_net_raw=ep /bin/ping
Попробуем запустить ping снова:
$ ping execbit.ru PING execbit.ru (217.107.34.241) 56(84) bytes of data. 64 bytes from 217.107.34.241: icmp_req=1 ttl=50 time=78.7 ms
Теперь все прекрасно работает. И это при том, что ping не имеет прав root! Выгода, как говориться, на лицо. Таким же образом можно наделить работающий с правами обычного пользователя сетевой сервис возможностью привязки к портам ниже 1024 (cap_net_admin) или позволить приложению делать chroot (cap_sys_chroot). Полный список "возможностей" можно найти в man-странице capabilities(8).
Общесистемные capabilities
Кроме возможности изменения capabilities с помощью системного вызова и файловых атрибутов, Linux позволяет также использовать интерфейс псевдо-файловой системы /proc для наложения ограничений (лишения их возможностей) на все работающие процессы. Делается с помощью записи шестнадцатиричных значений в файл/proc/sys/kernel/cap-bound. Прочитав этот файл можно узнать текущий список привилегий:
$ cat /proc/sys/kernel/cap-bound -257
Это значит, что в данной системе любой root-процесс может делать что угодно. Чтобы лишить его какой-либо возможности следует сделать следующее: 1 Открыть man capabilities(8) и найти нужную возможность. 2 Найти ее номер в файле /usr/src/linux/include/linux/capability.h:
$ grep CAP_SYS_MODULE /usr/include/linux/capability.h #define CAP_SYS_MODULE 16
3 Выполнить следующую команду чтобы лишить все процессы этой возможности (используйте вместо 16 номер из предыдущего шага):
# sudo -s # echo $((0xffffffff ^ (1 << 16))) > /proc/sys/kernel/cap-bound
Все, теперь ни один процесс, включая тех, владельцами которых является root, не сможет загружать модули ядра. Более того, снять это ограничение (а точнее вернуть возможность) можно только с помощью перезагрузки системы, так что никакие rootkit'ы, прикидывающиеся модулями ядра теперь не страшны. Просто добавьте последнюю команду в файл /etc/rc.local и все. Нужные модули будут загружены во время инициализации системы, а загрузка всех потенциально вредных будет запрещена. PS Альтернатива последней команде:
# sudo -s # echo 1 > /proc/sys/kernel/modules_disabled

.

Счетчик тИЦ и PR Яндекс.Метрика Msn bot last visit powered by MyPagerank.NetYahoo bot last visit powered by MyPagerank.Net ping fast  my blog, website, or RSS feed for Free