27.08.2006

Безопасность Solaris 10: Привилегии и Зоны, Часть 1

image

  Данная статья фокусируется на реализации "Концепции Привилегий" (официальное название “Минимальные привилегии” - Least Privilege)  в операционной системе SUN Solaris.

Peter van der Weerd
перевод: Владимир Куксенок

На протяжении долгого времени безопасность в дистрибутивах Unix основывалась на двух параметрах: идентификаторах (IDs) и правах доступа (permissions). Каждый файл имеет UID (идентификатор пользователя) и GID (идентификатор группы), определяющие владельца файла, а также набор атрибутов, определяющих права доступа пользователя-владельца, группы и всего остального мира. Права определенного пользователя на чтение, запись или исполнение файла зависят от его идентификаторов и прав доступа, хранящихся в описателе файла - inode.

На определенном этапе развития в Unix появились Списки Контроля Доступа (Access Control Lists - ACL), но они также основывались на идентификаторах и правах доступа. Пользователь, захотевший выполнить специфическую задачу, требующую прав суперпользователя, вначале должен получить идентификатор суперпользователя. Однако это позволит пользователю выполнить не только его специфическую задачу, а любую задачу. В соответствии со старой моделью пользователь не сможет выполнять задач администрирования, не имея UID 0 (root). Получив этот идентификатор, он сможет выполнять все администраторские задачи.

В Solaris 8 появился Контроль Доступа, Основанный на Ролях (Role Based Access Control - RBAC). RBAC связывает роли, профили, права и пользователей, позволяя определенным пользователям выполнять некоторые действия, типа перезагрузки машины и других администраторских функций, без знания пароля пользователя root. Ясно, что это было усовершенствование. Подход “все или ничего” был заменен на более совершенную модель безопасности. Но в ее основе все равно лежат идентификаторы и права доступа.

В Solaris 10 была представлена концепция Привилегий. Концепция Привилегий (официальное название “Минимальные привилегии” - Least Privilege) не нова. В конце двадцатого века Агентство Национальной Безопасности США начало разработку нового способа повышения безопасности операционных систем. Эта новая концепция включала изменения в ядре в комбинации с RBAC. В качестве платформы разработки был выбран Linux. Первый официальный релиз появился в 2000 году и основывался на ядре версии 2.2.12. Данная статья фокусируется на реализации Sun Microsystems, но с реализацией на базе Linux (Security Enhanced Linux) можно ознакомиться на этом сайте: http://www.nsa.gov/selinux.

Подробней о RBAC

У пользователя есть два идентификатора: реальный (Real UID) и эффективный (Effective UID). В Posix-системах и System V есть еще третий идентификатор - Saved UID, но в этой статье он обсуждаться не будет.

При входе в систему оба идентификатора идентичны и берутся из файла passwd. При запуске пользователем процесса, эффективный UID может отличаться от реального UID. Для изменения эффективного идентификатора пользователь обычно использует команду su. Когда пользователь с UID равным, к примеру, 2001 запускает su, у него будет запрошен пароль суперпользователя и после этого создан новый процесс. Этот процесс имеет реальный UID 2001 и эффективный UID 0, что означает, что на протяжении времени жизни нового процесса все команды пользователя будут выполняться с UID равным 0. Пользователь должен знать пароль другого пользователя, под идентификатор которого он хочет переключиться. root – единственный пользователь, который может переключиться под любой UID без знания пароля этого пользователя. Необходимость знания пароля другого пользователя – главный недостаток в использовании su.

RBAC комбинирует пользователей, роли, профили, права и параметры запуска (Exec Attributes). Пользователь, c помощью команды su, может изменить свою роль, что даст ему возможность выполнять определенные команды, описанные в профиле роли. Профиль связан с параметром запуска. Параметр запуска это специальная команда, выполняющаяся со специфичным эффективным UID.

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

Пользователь -> Роль -> Профиль -> Параметр запуска

Приведем пример:

Для начала добавим пользователя “baseuser” на x86 машину с именем “solx”.

solx# useradd -m -d /export/home/baseuser baseuser
64 blocks
solx# passwd baseuser
New Password: <password here>
Re-enter new Password: <password again>
passwd: password successfully changed for baseuser
solx# grep baseuser /etc/passwd
baseuser:x:5007:1::/export/home/baseuser:/bin/sh

Затем добавим в систему роль.

solx# roleadd -m -d /export/home/reboot reboot 64 blocks
solx# passwd reboot
New Password: <password here>
Re-enter new Password: <password again>
passwd: password successfully changed for reboot
solx# grep reboot /etc/passwd
reboot:x:5008:1::/export/home/reboot:/bin/pfsh

Обратите внимание на командный интерпретатор (/bin/pfsh). Этот шелл позволяет пользователю выполнять команду в профиле. Это не тот командный интерпретатор, с помощью которого вы можете войти в систему.

Присоединим пользователя “baseuser” к роле “reboot”.

solx# usermod -R reboot baseuser
solx# grep baseuser /etc/user_attr
baseuser::::type=normal;roles=reboot

Создадим профиль.

solx# echo "REBOOT:::profile to reboot:help=reboot.html" > \
/etc/security/prof_attr

Соединим профиль “REBOOT” с ролью “reboot”.

solx# rolemod -P REBOOT reboot
solx# grep reboot /etc/user_attr
reboot::::type=role;profiles=REBOOT
baseuser::::type=normal;roles=reboot

Итак, у нас есть пользователь “baseuser” ассоциированный с ролью “reboot”. Роль “reboot” имеет профиль “REBOOT”. Нам осталось сделать так, чтобы профиль (REBOOT) разрешал роле (reboot) выполнить /usr/sbin/reboot с UID 0.

solx# echo "REBOOT:suser:cmd:::/usr/sbin/reboot:euid=0" > \
/etc/security/exec_attr

Теперь “baseuser” может переключиться под роль “reboot” и запустить /usr/sbin/reboot для перезагрузки машины. Стоит ли разрешать простому пользователю перезагружать машину – вопрос, выходящий за рамки данной статьи.

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

Привилегии

Привилегии работают на другом уровне – уровне процессов, обслуживающимся ядром ОС. Это очень серьезное отличие: RBAC работает на уровне пользователя и основывается на идентификаторах и правах доступа, тогда как привилегии работают на уровне ядра и обходятся без атрибутов прав доступа к файлам. Это означает, что если процесс пользователя имеет соответствующую привилегию, он может читать файл, доступный на чтение (в соответствии с inode этого файла) только пользователю root. Или, с другой стороны, пользователь, имеющий доступ на чтение директории, не может читать ничего больше, т.к. привилегия на вызов fork убрана из списка привилегий процесса.

Для получения полного списка привилегий вы можете запустить ppriv:

solx# ppriv -l | wc -l
48

Любая из этих 48 привилегий может быть дана любому из процессов вашей системы. Для упрощения этого, Sun Microsystems сгруппировали эти привилегии следующим образом: группа эффективных привилегий (Effective set), группа допустимых привилегий (Permitted set), группа наследственных привилегий (Inheritable set), и группа предельно допустимых привилегий (Limit set).

  • Группа эффективных привилегий – набор привилегий имеющихся в настоящее время. Группа содержит привилегии процесса во время выполнения. Если хотите, можете сравнивать этот набор с эффективным UID.
  • Группа допустимых привилегий – набор привилегий, которые процесс может получить. Привилегия может быть добавлена в группу эффективных привилегий, только если она присутствует в данной группе.
  • Группа наследственных привилегий – набор привилегий, которые будут унаследованы дочерним процессом. Привилегии, отсутствующие в этой группе, никогда не появятся ни в группе эффективных привилегий, ни в группе допустимых привилегий дочернего процесса.
  • Группа предельно допустимых привилегий – набор привилегий, которыми может обладать процесс и его потомки. Эти привилегии могут быть продвинуты в группу допустимых привилегий и из нее в группы эффективных и наследственных привилегий.

Чтобы узнать, какие из привилегий есть в вашем распоряжении, можно снова запустить ppriv:

solx$ ppriv $$
2141: -sh
flags = none
E: basic
I: basic
P: basic
L: all

solx$ ppriv -v $$
2141: -sh
flags = none
E: file_link_any,proc_exec,proc_fork,proc_info,proc_session
I: file_link_any,proc_exec,proc_fork,proc_info,proc_session
P: file_link_any,proc_exec,proc_fork,proc_info,proc_session
L: contract_event,contract_observer,cpc_cpu,dtrace_kernel,
<...>

Привилегии процессов выглядят не очень функциональными, из-за того, что когда пользователь выйдет из системы и зайдет в нее снова, все сделанные изменения пропадут.

Приведем несколько примеров, помогающих понять плюсы группировки привилегий.

Ниже пример отмены привилегии PRIV_PROC_FORK из группы эффективных привилегий процесса с идентификатором 1774:

solx# ppriv -s E-proc_fork 1774
solx# ppriv 1774
1774: -sh
flags = none
E: basic,!proc_fork
I: basic
P: basic
L: all

В этом примере процесс 1744 будет получать сообщение об отсутствие привилегии каждый раз, когда будет пытаться вызвать fork. Чтобы убедиться в этом, попробуйте ввести команду ls.

Вы можете разрешить процессору с PID 1882 читать любые файлы в системе, добавив к его набору привилегий PRIV_FILE_DAC_READ.

solx# ppriv -s EIP+file_dac_read 1882
solx# ppriv 1882
1882: -sh
flags = none
E: basic,file_dac_read
I: basic,file_dac_read
P: basic,file_dac_read
L: all

В результате этого процессу с идентификатором 1882 разрешено читать любой файл в системе, независимо от EUID и атрибутов файла.

Нам нужно чтобы установленные привилегии были постоянными для выбранных пользователем приложений, т.е. чтобы привилегии устанавливались при входе в систему и каждый процесс, созданный пользователем, имел нужный набор привилегий. Для достижения этой цели, мы должны добавить в /etc/user_attr следующую запись:

solx# usermod -K defaultpriv=basic,-file_link_any baseuser
solx# grep baseuser /etc/user_attr
baseuser::::type=normal;defaultpriv=basic,-file_link_any;roles=reboot

В этом примере пользователь “baseuser” не сможет создавать жесткие ссылки на файлы, владельцем которых он не является. Понижение привилегий будет иметь эффект сразу после входа в систему:

solx# su - baseuser
Sun Microsystems Inc. SunOS 5.10 Generic January 2005
$ln /etc/hosts myhosts
ln: cannot create link myhosts: Not owner

Пользователь может получить информацию о нехватке привилегий другим способом, используя опцию отладки утилиты ppriv:

$ ppriv -eD ln /etc/hosts myhost
ln[9842]: missing privilege "file_link_any"
<…>

Чем дальше, тем лучше. Ясно, что RBAC и привилегии это две разные концепции, работающие на разных уровнях и единственное, что их связывает, это предназначение – защита системы.

Но что насчет Зон? Нужно рассмотреть какое место занимают Зоны во всем вышеописанном. Во второй части этой статьи мы рассмотрим, как комбинировать Привилегии и Зоны для создания защищенного окружения веб сервера Apache.

или введите имя

CAPTCHA